ILIAS  release_10 Revision v10.1-43-ga1241a92c2f
class.ilObjTestGUI.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
21 use ILIAS\Test\Results\Data\Repository as TestResultRepository;
29 use ILIAS\Test\Questions\Presentation\Printer as QuestionPrinter;
30 use ILIAS\Test\Questions\Properties\Repository as TestQuestionsRepository;
34 use ILIAS\Test\Scoring\Settings\Settings as SettingsScoring;
43 use ILIAS\Test\Results\Data\Factory as ResultsDataFactory;
67 use ILIAS\Style\Content\Service as ContentStyle;
68 
110 {
112 
113  public const SHOW_QUESTIONS_CMD = 'showQuestions';
114  private const SHOW_LOGS_CMD = 'history';
115 
116  private const INFO_SCREEN_CHILD_CLASSES = [
117  'ilpublicuserprofilegui', 'ilobjportfoliogui'
118  ];
119 
123 
129  private TestQuestionsRepository $test_questions_repository;
135  protected ?TabsManager $tabs_manager = null;
141  protected ilDBInterface $db;
145  private ContentStyle $content_style;
146  protected HTTPServices $http;
147  protected ilHelpGUI $help;
151  protected IRSS $irss;
156  protected ResultsDataFactory $results_data_factory;
158  protected TestResultRepository $test_pass_result_repository;
163 
164  protected bool $create_question_mode;
165 
171  public function __construct()
172  {
174  global $DIC;
175  $this->navigation_history = $DIC['ilNavigationHistory'];
176  $this->component_repository = $DIC['component.repository'];
177  $this->component_factory = $DIC['component.factory'];
178  $this->ui_factory = $DIC['ui.factory'];
179  $this->ui_renderer = $DIC['ui.renderer'];
180  $this->ui_service = $DIC->uiService();
181  $this->http = $DIC['http'];
182  $this->error = $DIC['ilErr'];
183  $this->db = $DIC['ilDB'];
184  $this->help = $DIC['ilHelp'];
185  $this->global_screen = $DIC['global_screen'];
186  $this->obj_data_cache = $DIC['ilObjDataCache'];
187  $this->irss = $DIC['resource_storage'];
188  $this->skills_service = $DIC->skills();
189  $this->archives = $DIC->archives();
190  $this->type = 'tst';
191  $this->data_factory = new DataFactory();
192  $this->ui_service = $DIC->uiService();
193  $this->taxonomy = $DIC->taxonomy()->domain();
194  $this->ui_service = $DIC->uiService();
195  $this->content_style = $DIC->contentStyle();
196 
197  $local_dic = TestDIC::dic();
198  $this->questionrepository = $local_dic['question.general_properties.repository'];
199  $this->test_questions_repository = $local_dic['questions.properties.repository'];
200  $this->qplrequest = $local_dic['question.request_data_wrapper'];
201  $this->title_builder = $local_dic['title_columns_builder'];
202  $this->testrequest = $local_dic['request_data_collector'];
203  $this->response_handler = $local_dic['response_handler'];
204  $this->participant_repository = $local_dic['participant.repository'];
205  $this->results_data_factory = $local_dic['results.data.factory'];
206  $this->results_presentation_factory = $local_dic['results.presentation.factory'];
207  $this->export_factory = $local_dic['exportimport.factory'];
208  $this->export_repository = $local_dic['exportimport.repository'];
209  $this->participant_access_filter_factory = $local_dic['participant.access_filter.factory'];
210  $this->test_pass_result_repository = $local_dic['results.data.test_result_repository'];
211  $this->toplist_repository = $local_dic['results.toplist.repository'];
212 
213  $ref_id = 0;
214  if ($this->testrequest->hasRefId() && is_numeric($this->testrequest->getRefId())) {
215  $ref_id = $this->testrequest->getRefId();
216  }
217  parent::__construct("", $ref_id, true, false);
218 
219  $this->ctrl->saveParameter($this, ['ref_id', 'test_ref_id']);
220 
221  $this->lng->loadLanguageModule('assessment');
222 
223  $this->objective_oriented_container = new ilTestObjectiveOrientedContainer();
224 
225  if (!($this->object instanceof ilObjTest)) {
226  $this->setCreationMode(true);
227  return;
228  }
229 
230  $this->test_question_set_config_factory = new ilTestQuestionSetConfigFactory(
231  $this->tree,
232  $this->db,
233  $this->lng,
234  $this->getTestObject()->getTestlogger(),
235  $this->component_repository,
236  $this->getTestObject(),
237  $this->questionrepository
238  );
239 
240  $this->test_player_factory = new ilTestPlayerFactory($this->getTestObject());
241  $this->test_session_factory = new ilTestSessionFactory($this->getTestObject(), $this->db, $this->user);
242  $this->setTestAccess(new ilTestAccess($this->ref_id, $this->getTestObject()->getTestId()));
243 
244  $this->tabs_manager = new TabsManager(
245  $this->tabs_gui,
246  $this->lng,
247  $this->ctrl,
248  $this->access,
249  $this->test_access,
250  $this->getTestObject(),
251  $this->objective_oriented_container,
252  $this->test_session_factory->getSession()
253  );
254  }
255 
259  public function executeCommand(): void
260  {
261  $cmd = $this->ctrl->getCmd('testScreen');
262 
263  $cmds_disabled_due_to_offline_status = [
264  'resumePlayer', 'resumePlayer', 'outUserResultsOverview', 'outUserListOfAnswerPasses'
265  ];
266 
267  if (!$this->getCreationMode() && $this->object->getOfflineStatus() && in_array($cmd, $cmds_disabled_due_to_offline_status)) {
268  $cmd = 'infoScreen';
269  }
270 
271  $next_class = $this->ctrl->getNextClass($this);
272 
273  // add entry to navigation history
274  if (!$this->getCreationMode() &&
275  $this->access->checkAccess('read', '', $this->testrequest->getRefId())
276  ) {
277  $this->navigation_history->addItem(
278  $this->testrequest->getRefId(),
279  ilLink::_getLink($this->testrequest->getRefId(), 'tst'),
280  'tst',
281  );
282  }
283 
285 
286  switch ($next_class) {
287  case 'illtiproviderobjectsettinggui':
288  if ((!$this->access->checkAccess("read", "", $this->testrequest->getRefId()))) {
289  $this->redirectAfterMissingRead();
290  }
291  $this->prepareOutput();
292  $this->addHeaderAction();
293  $this->tabs_manager->getSettingsSubTabs();
294  $this->tabs_manager->activateTab('settings');
295  $this->tabs_manager->activateSubTab('lti_provider');
296  $lti_gui = new ilLTIProviderObjectSettingGUI($this->getTestObject()->getRefId());
297  $lti_gui->setCustomRolesForSelection($this->rbac_review->getLocalRoles($this->getTestObject()->getRefId()));
298  $lti_gui->offerLTIRolesForSelection(false);
299  $this->ctrl->forwardCommand($lti_gui);
300  break;
301 
302  case 'iltestexportgui':
303  if (!$this->access->checkAccess('write', '', $this->ref_id)) {
304  $this->redirectAfterMissingWrite();
305  }
306 
307  $this->prepareOutput();
308  $this->addHeaderAction();
309  $this->tabs_manager->activateTab(TabsManager::TAB_ID_EXPORT);
310 
311  $selected_files = [];
312  if ($this->testrequest->isset('file') && $this->testrequest->raw('file')) {
313  $selected_files = $this->testrequest->raw('file');
314  }
315 
316  if (is_string($selected_files)) {
317  $selected_files = [$selected_files];
318  }
319 
320  $export_gui = new ilTestExportGUI(
321  $this,
322  $this->db,
323  $this->obj_data_cache,
324  $this->user,
325  $this->ui_factory,
326  $this->ui_renderer,
327  $this->irss,
328  $this->request,
329  $this->export_repository,
330  $this->temp_file_system,
331  $this->participant_access_filter_factory,
332  new ilTestHTMLGenerator(),
333  $selected_files,
334  $this->questionrepository,
335  $this->testrequest
336  );
337  $this->ctrl->forwardCommand($export_gui);
338  break;
339 
340  case strtolower(ilInfoScreenGUI::class):
341  if (
342  !$this->access->checkAccess('read', '', $this->testrequest->getRefId())
343  && !$this->access->checkAccess('visible', '', $this->testrequest->getRefId())
344  ) {
345  $this->redirectAfterMissingRead();
346  }
347 
348  $this->prepareOutput();
349  $this->addHeaderAction();
350  $this->forwardToInfoScreen();
351  break;
352 
353  case strtolower(TestScreenGUI::class):
354  if (!$this->access->checkAccess('read', '', $this->testrequest->getRefId()) && !$this->access->checkAccess('visible', '', $this->testrequest->getRefId())) {
355  $this->redirectAfterMissingRead();
356  }
357  $this->prepareOutput();
358  $this->addHeaderAction();
359  $this->ctrl->forwardCommand($this->getTestScreenGUIInstance());
360  break;
361 
362  case 'ilobjectmetadatagui':
363  if (!$this->access->checkAccess('write', '', $this->getTestObject()->getRefId())) {
364  $this->redirectAfterMissingWrite();
365  }
366 
367  $this->prepareOutput();
368  $this->addHeaderAction();
369  $this->tabs_manager->activateTab(TabsManager::TAB_ID_META_DATA);
370  $md_gui = new ilObjectMetaDataGUI($this->getTestObject());
371  $this->ctrl->forwardCommand($md_gui);
372  break;
373 
374  case strtolower(ilTestParticipantsGUI::class):
375  if ((!$this->access->checkAccess("read", "", $this->testrequest->getRefId()))) {
376  $this->redirectAfterMissingRead();
377  }
378 
379  $gui = new ilTestParticipantsGUI(
380  $this->getTestObject(),
381  $this->user,
383  $this->test_question_set_config_factory->getQuestionSetConfig(),
386  $this->tpl,
391  $this->lng,
392  $this->ctrl,
394  $this->db,
405  );
406 
407  $this->ctrl->forwardCommand($gui);
408 
414  $this->prepareOutput();
415  $this->addHeaderAction();
416  $this->tabs_manager->activateTab(TabsManager::TAB_ID_PARTICIPANTS);
417 
418  break;
419 
420  case 'iltestresultsgui':
421  if ((!$this->access->checkAccess("read", "", $this->testrequest->getRefId()))) {
422  $this->redirectAfterMissingRead();
423  }
424  $this->prepareOutput();
425  $this->addHeaderAction();
426 
427  $gui = new ilTestResultsGUI(
428  $this->getTestObject(),
429  $this->ctrl,
430  $this->test_access,
431  $this->db,
432  $this->refinery,
433  $this->user,
434  $this->lng,
435  $this->getTestObject()->getTestlogger(),
436  $this->component_repository,
437  $this->tabs_manager,
438  $this->toolbar,
439  $this->tpl,
440  $this->ui_factory,
441  $this->ui_renderer,
442  $this->skills_service,
443  $this->questionrepository,
444  $this->toplist_repository,
445  $this->testrequest,
446  $this->http,
447  $this->data_factory,
448  $this->test_session_factory->getSession(),
450  );
451 
452  $this->ctrl->forwardCommand($gui);
453  break;
454 
455  case "iltestplayerfixedquestionsetgui":
456  if (
457  $cmd !== 'autosave' &&
458  (!$this->access->checkAccess("read", "", $this->testrequest->getRefId()))
459  ) {
460  $this->redirectAfterMissingRead();
461  }
462  $this->trackTestObjectReadEvent();
463  if (!$this->getTestObject()->getKioskMode()) {
464  $this->prepareOutput();
465  }
466  $gui = new ilTestPlayerFixedQuestionSetGUI($this->getTestObject());
467  $gui->setObjectiveOrientedContainer($this->getObjectiveOrientedContainer());
468  $this->ctrl->forwardCommand($gui);
469  break;
470 
471  case "iltestplayerrandomquestionsetgui":
472  if (
473  $cmd !== 'autosave' &&
474  (!$this->access->checkAccess("read", "", $this->testrequest->getRefId()))
475  ) {
476  $this->redirectAfterMissingRead();
477  }
478  $this->trackTestObjectReadEvent();
479  if (!$this->getTestObject()->getKioskMode()) {
480  $this->prepareOutput();
481  }
482  $gui = new ilTestPlayerRandomQuestionSetGUI($this->getTestObject());
483  $gui->setObjectiveOrientedContainer($this->getObjectiveOrientedContainer());
484  $this->ctrl->forwardCommand($gui);
485  break;
486 
487  case "iltestevaluationgui":
488  if ((!$this->access->checkAccess("read", "", $this->testrequest->getRefId()))) {
489  $this->redirectAfterMissingRead();
490  }
491  $this->forwardToEvaluationGUI();
492  break;
493 
494  case "iltestservicegui":
495  if ((!$this->access->checkAccess("read", "", $this->testrequest->getRefId()))) {
496  $this->redirectAfterMissingRead();
497  }
498  $this->prepareOutput();
499  $this->addHeaderAction();
500  $serviceGUI = new ilTestServiceGUI($this->getTestObject());
501  $this->ctrl->forwardCommand($serviceGUI);
502  break;
503 
504  case 'ilpermissiongui':
505  if ((!$this->access->checkAccess("read", "", $this->testrequest->getRefId()))) {
506  $this->redirectAfterMissingRead();
507  }
508  $this->prepareOutput();
509  $this->addHeaderAction();
510  $this->tabs_manager->activateTab(TabsManager::TAB_ID_PERMISSIONS);
511  $perm_gui = new ilPermissionGUI($this);
512  $ret = $this->ctrl->forwardCommand($perm_gui);
513  break;
514 
515  case "illearningprogressgui":
516  if ((!$this->access->checkAccess("read", "", $this->testrequest->getRefId()))) {
517  $this->redirectAfterMissingRead();
518  }
519 
520  $this->prepareOutput();
521  $this->addHeaderAction();
522  $this->tabs_manager->activateTab(TabsManager::TAB_ID_LEARNING_PROGRESS);
523 
524  $test_session = $this->test_session_factory->getSessionByUserId($this->user->getId());
525  if (!$this->test_access->checkOtherParticipantsLearningProgressAccess()
526  && !$this->getTestObject()->canShowTestResults($test_session)) {
527  $this->tpl->setOnScreenMessage(
528  'info',
529  $this->lng->txt('tst_res_tab_msg_no_lp_access'),
530  );
531  break;
532  }
533 
535  $this->ctrl->forwardCommand($new_gui);
536 
537  break;
538 
539  case "ilcertificategui":
540  if ((!$this->access->checkAccess("read", "", $this->testrequest->getRefId()))) {
541  $this->redirectAfterMissingRead();
542  }
543  $this->prepareOutput();
544  $this->addHeaderAction();
545 
546  $this->tabs_manager->activateTab(TabsManager::TAB_ID_SETTINGS);
547 
548  $gui_factory = new ilCertificateGUIFactory();
549  $output_gui = $gui_factory->create($this->getTestObject());
550 
551  $this->ctrl->forwardCommand($output_gui);
552  break;
553 
554  case strtolower(TestScoringByQuestionGUI::class):
555  if ((!$this->access->checkAccess("read", "", $this->testrequest->getRefId()))) {
556  $this->redirectAfterMissingRead();
557  }
558  $this->prepareOutput();
559  $this->addHeaderAction();
560  $output_gui = new TestScoringByQuestionGUI($this->getTestObject(), $this->ui_service);
561  $output_gui->setTestAccess($this->getTestAccess());
562  $this->ctrl->forwardCommand($output_gui);
563  break;
564 
565  case strtolower(TestScoringByParticipantGUI::class):
566  if ((!$this->access->checkAccess("read", "", $this->testrequest->getRefId()))) {
567  $this->redirectAfterMissingRead();
568  }
569  $this->prepareOutput();
570  $this->addHeaderAction();
571  $output_gui = new TestScoringByParticipantGUI($this->getTestObject());
572  $output_gui->setTestAccess($this->getTestAccess());
573  $this->ctrl->forwardCommand($output_gui);
574  break;
575 
576  case strtolower(MarkSchemaGUI::class):
577  if ((!$this->access->checkAccess("read", "", $this->testrequest->getRefId()))) {
578  $this->redirectAfterMissingRead();
579  }
580  $this->protectByWritePermission();
581 
582  $mark_schema_gui = new MarkSchemaGUI(
583  $this->getTestObject(),
584  $this->user,
585  $this->lng,
586  $this->ctrl,
587  $this->tpl,
588  $this->toolbar,
589  $this->getObject()->getTestLogger(),
590  $this->post_wrapper,
591  $this->request_wrapper,
592  $this->response_handler,
593  $this->request,
594  $this->refinery,
595  $this->ui_factory,
596  $this->ui_renderer
597  );
598  $this->ctrl->forwardCommand($mark_schema_gui);
599 
600  $this->prepareOutput();
601  $this->addHeaderAction();
602  $this->tabs_manager->activateTab(TabsManager::TAB_ID_SETTINGS);
603  $this->tabs_manager->activateSubTab(TabsManager::SETTINGS_SUBTAB_ID_MARK_SCHEMA);
604 
605  break;
606 
607  case strtolower(SettingsMainGUI::class):
608  if ((!$this->access->checkAccess("read", "", $this->testrequest->getRefId()))) {
609  $this->redirectAfterMissingRead();
610  }
611 
612  $gui = new SettingsMainGUI(
613  $this->tpl,
614  $this->toolbar,
615  $this->ctrl,
616  $this->access,
617  $this->lng,
618  $this->tree,
619  $this->db,
620  $this->obj_data_cache,
621  $this->settings,
622  $this->ui_factory,
623  $this->ui_renderer,
624  $this->refinery,
625  $this->request,
626  $this->component_repository,
627  $this->user,
628  $this,
629  $this->getTestObject()->getTestLogger(),
630  $this->questionrepository
631  );
632  $this->ctrl->forwardCommand($gui);
633  $this->prepareOutput();
634  $this->tabs_manager->activateTab(TabsManager::TAB_ID_SETTINGS);
635  $this->tabs_manager->activateSubTab(TabsManager::SUBTAB_ID_GENERAL_SETTINGS);
636  $this->addHeaderAction();
637  break;
638 
639  case strtolower(SettingsScoringGUI::class):
640  if ((!$this->access->checkAccess("read", "", $this->testrequest->getRefId()))) {
641  $this->redirectAfterMissingRead();
642  }
643  $this->prepareOutput();
644  $this->addHeaderAction();
645  $gui = new SettingsScoringGUI(
646  $this->ctrl,
647  $this->access,
648  $this->lng,
649  $this->tree,
650  $this->db,
651  $this->component_repository,
652  $this,
653  $this->tpl,
654  $this->tabs_gui,
655  $this->getTestObject()->getTestLogger(),
656  $this->getTestObject()->getScoreSettingsRepository(),
657  $this->getTestObject()->getTestId(),
658  $this->ui_factory,
659  $this->ui_renderer,
660  $this->refinery,
661  $this->request,
662  $this->user
663  );
664 
665  $this->ctrl->forwardCommand($gui);
666  break;
667 
668  case 'iltestrandomquestionsetconfiggui':
669  if ((!$this->access->checkAccess("read", "", $this->testrequest->getRefId()))) {
670  $this->redirectAfterMissingRead();
671  }
672  $this->prepareOutput();
673  $this->addHeaderAction();
674  $test_process_locker_factory = (new ilTestProcessLockerFactory(
675  new ilSetting('assessment'),
676  $this->db
677  ))->withContextId($this->getTestObject()->getId());
679  $this->getTestObject(),
680  $this->ctrl,
681  $this->user,
682  $this->access,
683  $this->ui_factory,
684  $this->ui_renderer,
685  $this->data_factory,
686  $this->tabs_manager,
687  $this->lng,
688  $this->getTestObject()->getTestlogger(),
689  $this->tpl,
690  $this->db,
691  $this->tree,
692  $this->component_repository,
693  $this->obj_definition,
694  $this->obj_data_cache,
695  $test_process_locker_factory,
696  $this->testrequest,
697  $this->title_builder,
698  $this->questionrepository
699  );
700  $this->ctrl->forwardCommand($gui);
701  break;
702 
703  case 'iltestquestionbrowsertablegui':
704  if ((!$this->access->checkAccess("read", "", $this->testrequest->getRefId()))) {
705  $this->redirectAfterMissingRead();
706  }
707  $this->prepareOutput();
708  $this->addHeaderAction();
710  $this->tabs_gui,
711  $this->tree,
712  $this->db,
713  $this->getTestObject()->getTestlogger(),
714  $this->component_repository,
715  $this->getTestObject(),
716  $this->user,
717  $this->access,
718  $this->http,
719  $this->refinery,
720  $this->ui_factory,
721  $this->ui_renderer,
722  $this->testrequest,
723  $this->questionrepository,
724  $this->lng,
725  $this->ctrl,
726  $this->tpl,
727  $this->ui_service,
728  $this->data_factory,
729  $this->taxonomy,
730  );
731  $this->ctrl->forwardCommand($gui);
732  break;
733 
734  case 'iltestskilladministrationgui':
735  if ((!$this->access->checkAccess("read", "", $this->testrequest->getRefId()))) {
736  $this->redirectAfterMissingRead();
737  }
738  $this->prepareOutput();
739  $this->addHeaderAction();
740  $gui = new ilTestSkillAdministrationGUI(
741  $this->ctrl,
742  $this->access,
743  $this->tabs_manager,
744  $this->tpl,
745  $this->lng,
746  $this->refinery,
747  $this->db,
748  $this->getTestObject()->getTestlogger(),
749  $this->tree,
750  $this->component_repository,
751  $this->getTestObject(),
752  $this->questionrepository,
753  $this->testrequest,
754  $this->ref_id
755  );
756  $this->ctrl->forwardCommand($gui);
757  break;
758 
759  case 'ilobjectcopygui':
760  if ((!$this->access->checkAccess("read", "", $this->testrequest->getRefId()))) {
761  $this->redirectAfterMissingRead();
762  }
763  $this->prepareOutput();
764  $this->addHeaderAction();
765  $cp = new ilObjectCopyGUI($this);
766  $cp->setType('tst');
767  $this->ctrl->forwardCommand($cp);
768  break;
769 
770  case strtolower(ilAssQuestionPreviewGUI::class):
771  if (!$this->access->checkAccess('write', '', $this->getTestObject()->getRefId())) {
772  $this->redirectAfterMissingWrite();
773  }
774  $this->prepareOutput();
775  $this->forwardCommandToQuestionPreview($cmd);
776  break;
777  case 'ilassquestionpagegui':
778  if ($cmd === 'finishEditing') {
779  $this->prepareOutput();
781  break;
782  }
783  if ((!$this->access->checkAccess("read", "", $this->testrequest->getRefId()))) {
784  $this->redirectAfterMissingRead();
785  }
786  if ($cmd === 'edit' && !$this->access->checkAccess('write', '', $this->testrequest->getRefId())) {
787  $this->redirectAfterMissingWrite();
788  }
789  $this->prepareOutput();
790  $forwarder = new ilAssQuestionPageCommandForwarder(
791  $this->getTestObject(),
792  $this->lng,
793  $this->ctrl,
794  $this->tpl,
795  $this->questionrepository,
796  $this->testrequest
797  );
798  $forwarder->forward();
799  break;
800 
801  case 'ilassspecfeedbackpagegui':
802  if ((!$this->access->checkAccess("read", "", $this->testrequest->getRefId()))) {
803  $this->redirectAfterMissingRead();
804  }
805  $pg_gui = new ilAssSpecFeedbackPageGUI((int) $this->testrequest->raw("feedback_id"));
806  $this->ctrl->forwardCommand($pg_gui);
807  break;
808 
809  case 'ilassgenfeedbackpagegui':
810  if ((!$this->access->checkAccess("read", "", $this->testrequest->getRefId()))) {
811  $this->redirectAfterMissingRead();
812  }
813  $pg_gui = new ilAssGenFeedbackPageGUI($this->testrequest->int("feedback_id"));
814  $this->ctrl->forwardCommand($pg_gui);
815  break;
816 
817  case 'illocalunitconfigurationgui':
818  if ((!$this->access->checkAccess("read", "", $this->testrequest->getRefId()))) {
819  $this->redirectAfterMissingRead();
820  }
821  $this->prepareSubGuiOutput();
822 
823  // set return target
825  $question = $question_gui->getObject();
826  $question->setObjId($this->getTestObject()->getId());
827  $question_gui->setObject($question);
828  $question_gui->setQuestionTabs();
829  $gui = new ilLocalUnitConfigurationGUI(
830  new ilUnitConfigurationRepository($this->testrequest->getQuestionId())
831  );
832  $this->ctrl->forwardCommand($gui);
833  break;
834 
835  case "ilcommonactiondispatchergui":
836  if (!$this->access->checkAccess("read", "", $this->testrequest->getRefId()) && !$this->access->checkAccess("visible", "", $this->testrequest->getRefId())) {
837  $this->redirectAfterMissingRead();
838  }
839  $this->prepareOutput();
841  $this->ctrl->forwardCommand($gui);
842  break;
843 
844  case 'ilassquestionhintsgui':
845  if (!$this->access->checkAccess('write', '', $this->getTestObject()->getRefId())) {
846  $this->redirectAfterMissingWrite();
847  }
848 
849  if ($this->getTestObject()->evalTotalPersons() !== 0) {
850  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('question_is_part_of_running_test'), true);
851  $this->prepareOutput();
853  return;
854  }
855  $this->prepareSubGuiOutput();
856 
858  $question = $question_gui->getObject();
859  $question->setObjId($this->getTestObject()->getId());
860  $question_gui->setObject($question);
861  $question_gui->setQuestionTabs();
862 
863  $this->addQuestionTitleToObjectTitle($question->getTitle());
864 
865  $gui = new ilAssQuestionHintsGUI($question_gui);
866 
867  $gui->setEditingEnabled(
868  $this->access->checkAccess('write', '', $this->getTestObject()->getRefId())
869  );
870 
871  $this->ctrl->forwardCommand($gui);
872  break;
873 
874  case 'ilassquestionfeedbackeditinggui':
875  if (!$this->access->checkAccess('write', '', $this->getTestObject()->getRefId())) {
876  $this->redirectAfterMissingWrite();
877  }
878  $this->prepareSubGuiOutput();
879 
880  // set return target
881  $this->ctrl->setReturnByClass(self::class, self::SHOW_QUESTIONS_CMD);
883  $question = $question_gui->getObject();
884  $question->setObjId($this->getTestObject()->getId());
885  $question_gui->setObject($question);
886  $question_gui->setQuestionTabs();
887 
888  $this->addQuestionTitleToObjectTitle($question->getTitle());
889 
890  if ($this->getTestObject()->evalTotalPersons() !== 0) {
891  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('question_is_part_of_running_test'), true);
892  $this->prepareOutput();
894  }
896  $question_gui,
897  $this->ctrl,
898  $this->access,
899  $this->tpl,
900  $this->tabs_gui,
901  $this->lng,
902  $this->help,
903  $this->qplrequest,
904  $this->content_style
905  );
906  $this->ctrl->forwardCommand($gui);
907  break;
908 
909  case 'iltestcorrectionsgui':
910  if ((!$this->access->checkAccess('read', '', $this->testrequest->getRefId()))) {
911  $this->redirectAfterMissingRead();
912  }
913  $this->prepareOutput();
914  $gui = new ilTestCorrectionsGUI(
915  $this->db,
916  $this->ctrl,
917  $this->lng,
918  $this->tabs_gui,
919  $this->help,
920  $this->ui_factory,
921  $this->tpl,
922  $this->refinery,
923  $this->getTestObject()->getTestLogger(),
924  $this->testrequest,
925  $this->getTestObject(),
926  $this->user
927  );
928  $this->ctrl->forwardCommand($gui);
929  break;
930 
931  case 'iltestpagegui':
932  if ((!$this->access->checkAccess("write", "", $this->testrequest->getRefId()))) {
933  $this->redirectAfterMissingWrite();
934  }
935 
936  if ($cmd === 'downloadFile') {
937  $page_id = $this->object->getIntroductionPageId();
938  if ($this->testrequest->strVal('page_type') === 'concludingremarkspage') {
939  $page_id = $this->object->getConcludingRemarksPageId();
940  }
941  $this->ctrl->forwardCommand(new ilTestPageGUI('tst', $page_id));
942  }
943  $this->showEditTestPageGUI($cmd);
944  break;
945 
946  case '':
947  case 'ilobjtestgui':
948  if (!$this->access->checkAccess('read', '', $this->testrequest->getRefId())
949  && !$this->access->checkAccess('visible', '', $this->testrequest->getRefId())) {
950  $this->redirectAfterMissingRead();
951  }
952  $this->prepareOutput();
953  $this->addHeaderAction();
954 
955  if ($cmd === 'testScreen') {
956  $this->ctrl->forwardCommand($this->getTestScreenGUIInstance());
957  return;
958  }
959 
960  $local_cmd = $cmd . 'Object';
961  if (!method_exists($this, $local_cmd)) {
962  $local_cmd = self::SHOW_QUESTIONS_CMD . 'Object';
963  }
964  $this->$local_cmd();
965  break;
966 
967  default:
968  if ((!$this->access->checkAccess('read', '', $this->testrequest->getRefId()))) {
969  $this->redirectAfterMissingRead();
970  }
971  if (in_array(
972  $cmd,
973  ['editQuestion', 'previewQuestion', 'save', 'saveReturn', 'uploadImage',
974  'removeImage', 'syncQuestion', 'syncQuestionReturn', 'suggestedsolution']
975  )
976  && !$this->access->checkAccess('write', '', $this->getTestObject()->getRefId())) {
977  $this->redirectAfterMissingWrite();
978  }
979  if (in_array($cmd, ['editQuestion', 'save', 'saveReturn', 'suggestedsolution'])
980  && $this->getTestObject()->evalTotalPersons() !== 0) {
981  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('question_is_part_of_running_test'), true);
982  $this->prepareOutput();
984  return;
985  }
986  $this->forwardCommandToQuestion($cmd);
987  break;
988  }
989  if (!in_array(strtolower($this->testrequest->raw('baseClass')), ['iladministrationgui', 'ilrepositorygui'])
990  && $this->getCreationMode() !== true) {
991  $this->tpl->printToStdout();
992  }
993  }
994 
995  protected function redirectAfterMissingWrite()
996  {
997  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('no_permission'), true);
998  $target_class = get_class($this->object) . 'GUI';
999  $this->ctrl->setParameterByClass($target_class, 'ref_id', $this->ref_id);
1000  $this->ctrl->redirectByClass($target_class);
1001  }
1002 
1003  protected function redirectAfterMissingRead(): void
1004  {
1005  $this->tpl->setOnScreenMessage('failure', sprintf(
1006  $this->lng->txt("msg_no_perm_read_item"),
1007  $this->object->getTitle()
1008  ), true);
1009  $this->ctrl->setParameterByClass('ilrepositorygui', 'ref_id', ROOT_FOLDER_ID);
1010  $this->ctrl->redirectByClass('ilrepositorygui');
1011  }
1012 
1014  string $cmd,
1015  assQuestionGUI $question_gui = null
1016  ): void {
1017  $nr_of_participants_with_results = $this->getTestObject()->evalTotalPersons();
1018 
1019  $this->ctrl->saveParameterByClass(self::class, 'q_id');
1020  $gui = new ilAssQuestionPreviewGUI(
1021  $this->ctrl,
1022  $this->rbac_system,
1023  $this->tabs_gui,
1024  $this->toolbar,
1025  $this->tpl,
1026  $this->ui_factory,
1027  $this->lng,
1028  $this->db,
1029  $this->refinery->random(),
1031  $this->http,
1034  );
1035 
1036  if ($nr_of_participants_with_results > 0) {
1037  $gui->addAdditionalCmd(
1038  $this->lng->txt('tst_corrections_qst_form'),
1039  $this->ctrl->getLinkTargetByClass(ilTestCorrectionsGUI::class, 'showQuestion')
1040  );
1041  }
1042 
1043  $question_gui ??= assQuestion::instantiateQuestionGUI($this->fetchAuthoringQuestionIdParameter());
1044 
1045  $this->addQuestionTitleToObjectTitle($question_gui->getObject()->getTitle());
1046 
1047  if (!$this->getTestObject()->isRandomTest() && $nr_of_participants_with_results === 0) {
1048  $gui->setPrimaryCmd(
1049  $this->lng->txt('edit_question'),
1050  $this->ctrl->getLinkTargetByClass(
1051  get_class($question_gui),
1052  'editQuestion'
1053  )
1054  );
1055  $gui->addAdditionalCmd(
1056  $this->lng->txt('edit_page'),
1057  $this->ctrl->getLinkTargetByClass(
1058  ilAssQuestionPageGUI::class,
1059  'edit'
1060  )
1061  );
1062  }
1063 
1064  $gui->initQuestion($question_gui, $this->getTestObject()->getId());
1065  $gui->initPreviewSettings($this->getTestObject()->getRefId());
1066  $gui->initPreviewSession($this->user->getId(), $this->testrequest->getQuestionId());
1067  $gui->initHintTracking();
1068  $gui->initStyleSheets();
1069 
1070  $this->ctrl->clearParameterByClass(self::class, 'q_id');
1071  $this->tabs_gui->setBackTarget(
1072  $this->lng->txt('backtocallingtest'),
1073  $this->ctrl->getLinkTargetByClass(self::class, self::SHOW_QUESTIONS_CMD)
1074  );
1075  $this->ctrl->saveParameterByClass(self::class, 'q_id');
1076  $gui->{$cmd . 'Cmd'}();
1077  }
1078 
1079  private function addQuestionTitleToObjectTitle(string $question_title): void
1080  {
1081  $this->tpl->setTitle(
1082  $this->refinery->encode()->htmlSpecialCharsAsEntities()->transform(
1083  "{$this->getTestObject()->getTitle()}: {$question_title}"
1084  )
1085  );
1086  }
1087 
1088  protected function forwardCommandToQuestion(string $cmd): void
1089  {
1090  $this->create_question_mode = true;
1091  $this->prepareOutput();
1092 
1093  try {
1094  $qid = $this->fetchAuthoringQuestionIdParameter();
1095 
1096  $this->ctrl->setReturnByClass(self::class, self::SHOW_QUESTIONS_CMD);
1097 
1098  $question_gui = assQuestionGUI::_getQuestionGUI(
1099  ilUtil::stripSlashes($this->testrequest->strVal('question_type')),
1100  $qid
1101  );
1102 
1103  $question_gui->setEditContext(assQuestionGUI::EDIT_CONTEXT_AUTHORING);
1104  $question = $question_gui->getObject();
1105  $question->setObjId($this->getTestObject()->getId());
1106  $question_gui->setObject($question);
1107  $question_gui->setContextAllowsSyncToPool(true);
1108  $question_gui->setQuestionTabs();
1109 
1110  $this->addQuestionTitleToObjectTitle($question->getTitle());
1111 
1112  $target = strpos($cmd, 'Return') === false ? 'stay' : 'return';
1113 
1114  if (in_array($cmd, ['syncQuestion', 'syncQuestionReturn'])) {
1115  $question_gui->syncQuestion();
1116  $this->showNextViewAfterQuestionSave($question_gui, $target);
1117  return;
1118  }
1119 
1120  if ($question_gui->isSaveCommand()
1121  || $question_gui->cmdNeedsExistingQuestion($cmd)) {
1122  $question_gui = $this->addPostCreationTasksToQuestionGUI($question_gui);
1123  }
1124 
1125  if ($qid === 0 && $question_gui->cmdNeedsExistingQuestion($cmd)) {
1126  $question_gui->getObject()->createNewQuestion();
1127  $question_gui->setQuestionTabs();
1128  $this->executeAfterQuestionCreationTasks($question_gui);
1129  }
1130 
1131  if (!$question_gui->isSaveCommand()) {
1132  $this->ctrl->forwardCommand($question_gui);
1133  return;
1134  }
1135 
1136  if (!$question_gui->saveQuestion()) {
1137  return;
1138  }
1139 
1140  $this->tpl->setOnScreenMessage('success', $this->lng->txt('msg_obj_modified'), true);
1141  if ($qid === 0) {
1142  $this->executeAfterQuestionCreationTasks($question_gui);
1143  }
1144  $this->executeAfterQuestionSaveTasks($question_gui);
1145  $this->showNextViewAfterQuestionSave($question_gui, $target);
1146  } catch (ilTestException $e) {
1147  $this->showQuestionsObject();
1148  }
1149  }
1150 
1152  assQuestionGUI $question_gui
1153  ): assQuestionGUI {
1154  if ($this->testrequest->isset('move_after_question_with_id')) {
1155  $question_gui->setMoveAfterQuestionId(
1156  $this->testrequest->int('move_after_question_with_id')
1157  );
1158  }
1159 
1160  if ($this->testrequest->isset('pool_title')) {
1161  $question_gui->setCopyToNewPoolOnSave(
1162  $this->testrequest->strVal('pool_title')
1163  );
1164  }
1165 
1166  if ($this->testrequest->isset('pool_ref')) {
1167  $question_gui->setCopyToExistingPoolOnSave(
1168  $this->testrequest->int('pool_ref')
1169  );
1170  }
1171  return $question_gui;
1172  }
1173 
1174  private function executeAfterQuestionSaveTasks(assQuestionGUI $question_gui): void
1175  {
1176  if ($this->getTestObject()->getTestLogger()->isLoggingEnabled()) {
1177  $this->getTestObject()->getTestLogger()->logQuestionAdministrationInteraction(
1178  $question_gui->getObject()->toQuestionAdministrationInteraction(
1179  $this->getTestObject()->getTestLogger()->getAdditionalInformationGenerator(),
1180  $this->getTestObject()->getRefId(),
1181  TestQuestionAdministrationInteractionTypes::QUESTION_MODIFIED
1182  )
1183  );
1184  }
1185  }
1186 
1187  private function executeAfterQuestionCreationTasks(assQuestionGUI $question_gui): void
1188  {
1189  if ($this->getTestObject()->getQuestionSetType() === ilObjTest::QUESTION_SET_TYPE_FIXED
1190  && !in_array($question_gui->getObject()->getId(), $this->getTestObject()->getQuestions())) {
1191  $this->getTestObject()->insertQuestion($question_gui->getObject()->getId(), true);
1192  }
1193 
1194  if ($question_gui->getMoveAfterQuestionId() !== null) {
1195  $this->getTestObject()->moveQuestions(
1196  [$question_gui->getObject()->getId()],
1197  $question_gui->getMoveAfterQuestionId() === 0
1198  ? $this->getTestObject()->getQuestions()[1]
1199  : $question_gui->getMoveAfterQuestionId(),
1200  $question_gui->getMoveAfterQuestionId() === 0 ? 0 : 1
1201  );
1202  $question_gui->setMoveAfterQuestionId(null);
1203  }
1204 
1205  if ($question_gui->getCopyToExistingPoolOnSave() !== null) {
1206  $original_id = $this->copyQuestionToPool(
1207  $question_gui,
1208  new ilObjQuestionPool($question_gui->getCopyToExistingPoolOnSave())
1209  );
1210  assQuestion::saveOriginalId($question_gui->getObject()->getId(), $original_id);
1211  $question_gui->setCopyToExistingPoolOnSave(null);
1212  }
1213 
1214  if ($question_gui->getCopyToNewPoolOnSave() !== null) {
1215  $question_pool = $this->createQuestionPool($question_gui->getCopyToNewPoolOnSave());
1216  $original_id = $this->copyQuestionToPool(
1217  $question_gui,
1218  $question_pool
1219  );
1220  assQuestion::saveOriginalId($question_gui->getObject()->getId(), $original_id);
1221  $question_gui->setCopyToNewPoolOnSave(null);
1222  }
1223  }
1224 
1225  private function showNextViewAfterQuestionSave(assQuestionGUI $question_gui, string $target): void
1226  {
1227  if ($target === 'return') {
1230  $question_gui
1231  );
1232  }
1233 
1234  if ($target === 'stay') {
1235  $this->ctrl->setParameterByClass(ilAssQuestionPreviewGUI::class, 'q_id', $question_gui->getObject()->getId());
1236  $this->tabs_gui->setBackTarget(
1237  $this->lng->txt('backtocallingpage'),
1238  $this->ctrl->getLinkTargetByClass(
1239  ilAssQuestionPreviewGUI::class,
1241  )
1242  );
1243  $question_gui->editQuestion(false, false);
1244  }
1245  }
1246 
1247  protected function trackTestObjectReadEvent()
1248  {
1250  $this->getTestObject()->getType(),
1251  $this->getTestObject()->getRefId(),
1252  $this->getTestObject()->getId(),
1253  $this->user->getId()
1254  );
1255  }
1256 
1261  protected function exportObject()
1262  {
1263  $this->ctrl->redirectByClass('ilTestExportGUI');
1264  }
1265 
1271  {
1272  $qid = $this->testrequest->int('q_id');
1273 
1274  if ($qid === 0 || $this->getTestObject()->checkQuestionParent($qid)) {
1275  return $qid;
1276  }
1277 
1278  throw new ilTestException('question id does not relate to parent object!');
1279  }
1280 
1281  private function questionsTabGatewayObject()
1282  {
1283  if ($this->getTestObject()->isRandomTest()) {
1284  $this->ctrl->redirectByClass('ilTestRandomQuestionSetConfigGUI');
1285  }
1286 
1287  $this->ctrl->redirectByClass('ilObjTestGUI', self::SHOW_QUESTIONS_CMD);
1288  }
1289 
1290  private function showEditTestPageGUI(string $cmd): void
1291  {
1292  $this->prepareOutput();
1293  $this->tabs_manager->getSettingsSubTabs();
1294 
1295  if ($this->request_wrapper->has('page_type')
1296  && $this->request_wrapper->retrieve(
1297  'page_type',
1298  $this->refinery->kindlyTo()->string()
1299  ) === 'introductionpage'
1300  ) {
1301  $page_type = 'IntroductionPage';
1302  $this->tabs_manager->activateSubTab(TabsManager::SETTINGS_SUBTAB_ID_EDIT_INTRODUCTION_PAGE);
1303  $page_id = $this->getTestObject()->getIntroductionPageId();
1304  } else {
1305  $page_type = 'ConcludingRemarksPage';
1306  $this->tabs_manager->activateSubTab(TabsManager::SETTINGS_SUBTAB_ID_EDIT_CONCLUSION_PAGE);
1307  $page_id = $this->getTestObject()->getConcludingRemarksPageId();
1308  }
1309  $this->ctrl->saveParameterByClass(ilTestPageGUI::class, 'page_type');
1310 
1311  $gui = new ilTestPageGUI('tst', $page_id);
1312  $this->content_style->gui()->addCss($this->tpl, $this->ref_id);
1313  $this->tpl->setContent($this->ctrl->forwardCommand($gui));
1314 
1315  $this->tabs_manager->activateTab(TabsManager::TAB_ID_SETTINGS);
1316  }
1317 
1318  public function getTestAccess(): ilTestAccess
1319  {
1320  return $this->test_access;
1321  }
1322 
1324  {
1325  $this->test_access = $test_access;
1326  }
1327 
1328  private function forwardToEvaluationGUI()
1329  {
1330  $this->prepareOutput();
1331  $this->addHeaderAction();
1332  $gui = new ilTestEvaluationGUI($this->getTestObject());
1333  $gui->setObjectiveOrientedContainer($this->getObjectiveOrientedContainer());
1334  $gui->setTestAccess($this->getTestAccess());
1335 
1336  $this->ctrl->forwardCommand($gui);
1337  }
1338 
1340  {
1341  $this->ctrl->redirectByClass(SettingsMainGUI::class, SettingsMainGUI::CMD_SHOW_FORM);
1342  }
1343 
1344  private function prepareSubGuiOutput()
1345  {
1346  $this->tpl->loadStandardTemplate();
1347  $this->setLocator();
1348  $this->setTitleAndDescription();
1349  }
1350 
1351  public function runObject()
1352  {
1353  $this->ctrl->redirectByClass([ilRepositoryGUI::class, self::class, ilInfoScreenGUI::class]);
1354  }
1355 
1356  protected function importFile(string $file_to_import, string $path_to_uploaded_file_in_temp_dir): void
1357  {
1358  list($subdir, $importdir, $xmlfile, $qtifile) = $this->buildImportDirectoriesFromImportFile($file_to_import);
1359 
1361  ->withZipOutputPath($this->getImportTempDirectory());
1362 
1363  $unzip = $this->archives->unzip(Streams::ofResource(fopen($file_to_import, 'r')), $options);
1364  $unzip->extract();
1365 
1366  if (!is_file($qtifile)) {
1367  ilFileUtils::delDir($importdir);
1368  $this->deleteUploadedImportFile($path_to_uploaded_file_in_temp_dir);
1369  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('tst_import_non_ilias_zip'), true);
1370  }
1371  $qtiParser = new ilQTIParser($importdir, $qtifile, ilQTIParser::IL_MO_VERIFY_QTI, 0, []);
1372  $qtiParser->startParsing();
1373  $founditems = $qtiParser->getFoundItems();
1374 
1375  $complete = 0;
1376  $incomplete = 0;
1377  foreach ($founditems as $item) {
1378  if ($item["type"] !== '') {
1379  $complete++;
1380  } else {
1381  $incomplete++;
1382  }
1383  }
1384 
1385  if (count($founditems) && $complete == 0) {
1386  ilFileUtils::delDir($importdir);
1387  $this->deleteUploadedImportFile($path_to_uploaded_file_in_temp_dir);
1388  $this->tpl->setOnScreenMessage('info', $this->lng->txt('qpl_import_non_ilias_files'));
1389  return;
1390  }
1391 
1392  ilSession::set('path_to_import_file', $file_to_import);
1393  ilSession::set('path_to_uploaded_file_in_temp_dir', $path_to_uploaded_file_in_temp_dir);
1394 
1395  if ($qtiParser->getQuestionSetType() !== ilObjTest::QUESTION_SET_TYPE_FIXED
1396  || file_exists($this->buildResultsFilePath($importdir, $subdir))
1397  || $founditems === []) {
1398  $this->importVerifiedFileObject(true);
1399  return;
1400  }
1401 
1402  $form = $this->buildImportQuestionsSelectionForm(
1403  'importVerifiedFile',
1404  $importdir,
1405  $qtifile,
1406  $file_to_import,
1407  $path_to_uploaded_file_in_temp_dir
1408  );
1409 
1410  if ($form === null) {
1411  return;
1412  }
1413 
1414  $panel = $this->ui_factory->panel()->standard(
1415  $this->lng->txt('import_tst'),
1416  [
1417  $this->ui_factory->legacy($this->lng->txt('qpl_import_verify_found_questions')),
1418  $form
1419  ]
1420  );
1421  $this->tpl->setContent($this->ui_renderer->render($panel));
1422  $this->tpl->printToStdout();
1423  exit;
1424  }
1425 
1427  {
1428  $tst = new ilObjTest();
1429  $defaults = $tst->getAvailableDefaults();
1430  if ($defaults === []) {
1431  return [];
1432  }
1433 
1434  $additional_options = [];
1435  foreach ($defaults as $row) {
1436  $additional_options["tstdef_" . $row["test_defaults_id"]] = [$row["name"],
1437  $this->lng->txt("tst_default_settings")];
1438  }
1439  return $additional_options;
1440  }
1441 
1446  public function afterSave(ilObject $new_object): void
1447  {
1448  $info = '';
1449  $new_object->saveToDb();
1450 
1451  $test_def_id = $this->getSelectedPersonalDefaultsSettingsFromForm();
1452  if ($test_def_id !== null
1453  && ($defaults = $new_object->getTestDefaults($test_def_id)) !== null) {
1454  $info = $new_object->applyDefaults($defaults);
1455  }
1456 
1457  $new_object->saveToDb();
1458 
1459  if ($new_object->getTestLogger()->isLoggingEnabled()) {
1460  $new_object->getTestLogger()->logTestAdministrationInteraction(
1461  $new_object->getTestLogger()->getInteractionFactory()->buildTestAdministrationInteraction(
1462  $this->getRefId(),
1463  $this->user->getId(),
1464  TestAdministrationInteractionTypes::NEW_TEST_CREATED,
1465  []
1466  )
1467  );
1468  }
1469 
1470  if ($info === '') {
1471  $this->tpl->setOnScreenMessage('success', $this->lng->txt('object_added'), true);
1472  } else {
1473  $this->tpl->setOnScreenMessage('info', $this->lng->txt($info), true);
1474  }
1475  $this->ctrl->setParameter($this, 'ref_id', $new_object->getRefId());
1476  $this->ctrl->redirectByClass(SettingsMainGUI::class);
1477  }
1478 
1480  {
1481  $data = $this->initCreateForm($this->type)
1482  ->withRequest($this->request)
1483  ->getData();
1484  return isset($data['didactic_templates'])
1485  ? $this->parseDidacticTemplateVar($data['didactic_templates'], 'tstdef')
1486  : null;
1487  }
1488 
1489  public function backToRepositoryObject()
1490  {
1491  $path = $this->tree->getPathFull($this->getTestObject()->getRefID());
1492  ilUtil::redirect($this->getReturnLocation("cancel", "./ilias.php?baseClass=ilRepositoryGUI&cmd=frameset&ref_id=" . $path[count($path) - 2]["child"]));
1493  }
1494 
1495  public function getTestObject(): ?ilObjTest
1496  {
1497  return $this->object;
1498  }
1499 
1503  public function importVerifiedFileObject(
1504  bool $skip_retrieve_selected_questions = false
1505  ): void {
1506  if (!$this->checkPermissionBool('create', '', 'tst')) {
1507  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('no_permission'), true);
1508  $this->ctrl->returnToParent($this);
1509  }
1510  $file_to_import = ilSession::get('path_to_import_file');
1511  $path_to_uploaded_file_in_temp_dir = ilSession::get('path_to_uploaded_file_in_temp_dir');
1512  list($subdir, $importdir, $xmlfile, $qtifile) = $this->buildImportDirectoriesFromImportFile($file_to_import);
1513 
1514  $new_obj = new ilObjTest(0, true);
1515  $new_obj->setTitle('dummy');
1516  $new_obj->setDescription('test import');
1517  $new_obj->create(true);
1518  $new_obj->createReference();
1519  $new_obj->putInTree($this->testrequest->getRefId());
1520  $new_obj->setPermissions($this->testrequest->getRefId());
1521  $new_obj->saveToDb();
1522 
1523  $selected_questions = [];
1524  if (!$skip_retrieve_selected_questions) {
1525  $selected_questions = $this->retrieveSelectedQuestionsFromImportQuestionsSelectionForm(
1526  'importVerifiedFile',
1527  $importdir,
1528  $qtifile,
1529  $this->request
1530  );
1531  }
1532 
1533  ilSession::set('tst_import_selected_questions', $selected_questions);
1534 
1535  $imp = new ilImport($this->testrequest->getRefId());
1536  $map = $imp->getMapping();
1537  $map->addMapping('components/ILIAS/Test', 'tst', 'new_id', (string) $new_obj->getId());
1538 
1543  if (is_file($importdir . DIRECTORY_SEPARATOR . '/manifest.xml')) {
1544  $imp->importObject($new_obj, $file_to_import, basename($file_to_import), 'tst', 'components/ILIAS/Test', true);
1545  } else {
1546  $test_importer = new ilTestImporter();
1547  $test_importer->setImport($imp);
1548  $test_importer->setInstallId(IL_INST_ID);
1549  $test_importer->setImportDirectory($importdir . '/' . $subdir);
1550  $test_importer->init();
1551 
1552  $test_importer->importXmlRepresentation(
1553  '',
1554  '',
1555  '',
1556  $map,
1557  );
1558  }
1559 
1560  if ($new_obj->getTestLogger()->isLoggingEnabled()) {
1561  $new_obj->getTestLogger()->logTestAdministrationInteraction(
1562  $new_obj->getTestLogger()->getInteractionFactory()->buildTestAdministrationInteraction(
1563  $new_obj->getRefId(),
1564  $this->user->getId(),
1565  TestAdministrationInteractionTypes::NEW_TEST_CREATED,
1566  []
1567  )
1568  );
1569  }
1570 
1571  ilFileUtils::delDir($importdir);
1572  $this->deleteUploadedImportFile($path_to_uploaded_file_in_temp_dir);
1573  ilSession::clear('path_to_import_file');
1574  ilSession::clear('path_to_uploaded_file_in_temp_dir');
1575 
1576  $this->tpl->setOnScreenMessage('success', $this->lng->txt("object_imported"), true);
1577 
1578  $question_skill_assignments_import_fails = new ilAssQuestionSkillAssignmentImportFails($new_obj->getId());
1579  if ($question_skill_assignments_import_fails->failedImportsRegistered()) {
1580  $this->tpl->setOnScreenMessage(
1581  'info',
1582  $question_skill_assignments_import_fails->getFailedImportsMessage($this->lng),
1583  true
1584  );
1585  }
1586 
1587  $this->ctrl->setParameterByClass(ilObjTestGUI::class, 'ref_id', $new_obj->getRefId());
1588  $this->ctrl->redirectByClass(ilObjTestGUI::class);
1589  }
1590 
1594  public function downloadFileObject()
1595  {
1596  $file = explode("_", $this->testrequest->raw("file_id"));
1597  $fileObj = new ilObjFile((int) $file[count($file) - 1], false);
1598  $fileObj->sendFile();
1599  exit;
1600  }
1601 
1605  public function fullscreenObject()
1606  {
1607  $page_gui = new ilAssQuestionPageGUI($this->testrequest->raw("pg_id"));
1608  $page_gui->showMediaFullscreen();
1609  }
1610 
1614  public function download_paragraphObject()
1615  {
1616  $pg_obj = new ilAssQuestionPage($this->testrequest->raw("pg_id"));
1617  $pg_obj->sendParagraph($this->testrequest->raw("par_id"), $this->testrequest->raw("downloadtitle"));
1618  exit;
1619  }
1620 
1621  public function createQuestionPool($name = "dummy", $description = ""): ilObjQuestionPool
1622  {
1623  $parent_ref = $this->tree->getParentId($this->getTestObject()->getRefId());
1624  $qpl = new ilObjQuestionPool();
1625  $qpl->setType("qpl");
1626  $qpl->setTitle($name);
1627  $qpl->setDescription($description);
1628  $qpl->create();
1629  $qpl->createReference();
1630  $qpl->putInTree($parent_ref);
1631  $qpl->setPermissions($parent_ref);
1632  $qpl->getObjectProperties()->storePropertyIsOnline($qpl->getObjectProperties()->getPropertyIsOnline()->withOnline()); // must be online to be available
1633  $qpl->saveToDb();
1634  return $qpl;
1635  }
1636 
1637  public function createQuestionObject(): void
1638  {
1639  $this->protectByWritePermission();
1640 
1641  $this->ctrl->setReturnByClass(self::class, self::SHOW_QUESTIONS_CMD);
1642 
1643  $form = $this->buildQuestionCreationForm()->withRequest($this->request);
1644  $data_with_section = $form->getData();
1645  if ($data_with_section === null) {
1646  $this->createQuestionFormObject($form);
1647  return;
1648  }
1649  $data = $data_with_section[0];
1650 
1651  $qpl_mode = $data['pool_selection']['qpl_type'];
1652  if ($qpl_mode === self::QUESTION_CREATION_POOL_SELECTION_NEW_POOL && $data['pool_selection']['title'] === ''
1653  || $qpl_mode === self::QUESTION_CREATION_POOL_SELECTION_EXISTING_POOL && $data['pool_selection']['pool_ref_id'] === 0) {
1654  $this->tpl->setOnScreenMessage('info', $this->lng->txt("questionpool_not_entered"));
1655  $this->createQuestionFormObject($form);
1656  return;
1657  }
1658 
1660  $question_gui = assQuestionGUI::_getQuestionGUI(
1662  );
1663  $question_gui->setEditContext(assQuestionGUI::EDIT_CONTEXT_AUTHORING);
1664  $question = $question_gui->getObject();
1665  $question->setAdditionalContentEditingMode($data['editing_type']);
1666  $question->setObjId($this->getTestObject()->getId());
1667  $question_gui->setObject($question);
1668  $question_gui->setQuestionTabs();
1669 
1670  if (array_key_exists('position', $data)) {
1671  $question_gui->setMoveAfterQuestionId($data['position']);
1672  }
1673 
1674  if ($qpl_mode === self::QUESTION_CREATION_POOL_SELECTION_NEW_POOL) {
1675  $question_gui->setCopyToNewPoolOnSave($data['pool_selection']['title']);
1676  }
1677 
1678  if ($qpl_mode === self::QUESTION_CREATION_POOL_SELECTION_EXISTING_POOL) {
1679  $question_gui->setCopyToExistingPoolOnSave($data['pool_selection']['pool_ref_id']);
1680  }
1681 
1682  $question_gui->editQuestion();
1683  }
1684 
1685  public function cancelCreateQuestionObject(): void
1686  {
1687  $this->ctrl->redirect($this, self::SHOW_QUESTIONS_CMD);
1688  }
1689 
1690  private function insertQuestionsObject(array $selected_array = null): void
1691  {
1692  $this->protectByWritePermission();
1693 
1694  if (($selected_array ?? $this->testrequest->getQuestionIds()) === []) {
1695  $this->tpl->setOnScreenMessage('info', $this->lng->txt('tst_insert_missing_question'), true);
1696  $this->ctrl->redirect($this, 'browseForQuestions');
1697  }
1698 
1699  $this->getTestObject()->saveCompleteStatus($this->test_question_set_config_factory->getQuestionSetConfig());
1700  $this->tpl->setOnScreenMessage('success', $this->lng->txt('tst_questions_inserted'), true);
1701  $this->ctrl->redirect($this, self::SHOW_QUESTIONS_CMD);
1702  return;
1703  }
1704 
1705  public function createQuestionFormObject(Form $form = null): void
1706  {
1707  $this->protectByWritePermission();
1708 
1709  $this->tabs_manager->getQuestionsSubTabs();
1710  $this->tabs_manager->activateSubTab(TabsManager::SUBTAB_ID_QST_LIST_VIEW);
1711 
1712  $sub_screen_id = ['createQuestion'];
1713 
1714  $this->tabs_manager->activateTab(TabsManager::TAB_ID_QUESTIONS);
1715  $this->help->setScreenId('assQuestions');
1716  $this->help->setSubScreenId(implode('_', $sub_screen_id));
1717 
1718  $this->tpl->setContent(
1719  $this->ui_renderer->render(
1720  $form ?? $this->buildQuestionCreationForm()
1721  )
1722  );
1723  }
1724 
1725  private function buildQuestionCreationForm(): Form
1726  {
1727  $inputs['question_type'] = $this->buildInputQuestionType();
1728  $questions = $this->getTestObject()->getQuestionTitlesAndIndexes();
1729  if ($questions !== []) {
1730  $inputs['position'] = $this->buildInputPosition($questions);
1731  }
1732 
1733  $inputs['editing_type'] = $this->buildInputEditingType();
1734 
1735  if ($inputs['editing_type'] instanceof Radio) {
1736  $sub_screen_id[] = 'editMode';
1737  }
1738 
1739  $sub_screen_id[] = 'poolSelect';
1740 
1741  $inputs['pool_selection'] = $this->buildInputPoolSelection();
1742 
1743  $section = [
1744  $this->ui_factory->input()->field()->section($inputs, $this->lng->txt('ass_create_question'))
1745  ];
1746 
1747  $form = $this->ui_factory->input()->container()->form()->standard(
1748  $this->ctrl->getFormAction($this, 'createQuestion'),
1749  $section
1750  )->withSubmitLabel($this->lng->txt('create'));
1751 
1752  return $form;
1753  }
1754 
1755  private function buildInputQuestionType(): Select
1756  {
1757  $question_types = (new ilObjQuestionPool())->getQuestionTypes(false, true, false);
1758  $options = [];
1759  foreach ($question_types as $label => $data) {
1760  $options[$data['question_type_id']] = $label;
1761  }
1762 
1763  return $this->ui_factory->input()->field()->select(
1764  $this->lng->txt('question_type'),
1765  $options
1766  )->withRequired(true);
1767  }
1768 
1769  private function buildInputPosition(array $questions): Select
1770  {
1771  $options = [0 => $this->lng->txt('first')];
1772  foreach ($questions as $key => $title) {
1773  $options[$key] = $this->lng->txt('behind') . ' ' . $title
1774  . ' [' . $this->lng->txt('question_id_short') . ': ' . $key . ']';
1775  }
1776  return $this->ui_factory->input()->field()->select(
1777  $this->lng->txt('position'),
1778  $options
1779  )->withAdditionalTransformation($this->refinery->kindlyTo()->int());
1780  }
1781 
1782  private function buildInputEditingType(): Input
1783  {
1784  if (!$this->getTestObject()->getGlobalSettings()->isPageEditorEnabled()) {
1785  return $this->ui_factory->input()->field()->hidden()->withValue(
1787  );
1788  }
1789 
1790  return $this->ui_factory->input()->field()->radio($this->lng->txt('tst_add_quest_cont_edit_mode'))
1791  ->withOption(
1793  $this->lng->txt('tst_add_quest_cont_edit_mode_IPE'),
1794  $this->lng->txt('tst_add_quest_cont_edit_mode_IPE_info')
1795  )->withOption(
1797  $this->lng->txt('tst_add_quest_cont_edit_mode_RTE'),
1798  $this->lng->txt('tst_add_quest_cont_edit_mode_RTE_info')
1799  )
1801  }
1802 
1804  {
1805  $f = $this->ui_factory->input()->field();
1806  $kt = $this->refinery->kindlyTo();
1807 
1808  $trafo = $this->refinery->custom()->transformation(
1809  static function ($values) use ($kt): array {
1810  $return['qpl_type'] = $kt->int()->transform($values[0]);
1811  if ($return['qpl_type'] === self::QUESTION_CREATION_POOL_SELECTION_NO_POOL) {
1812  return $return;
1813  }
1814  if ($return['qpl_type'] === self::QUESTION_CREATION_POOL_SELECTION_NEW_POOL) {
1815  return $return + ['title' => $kt->string()->transform($values[1][0])];
1816  }
1817  return $return + ['pool_ref_id' => $kt->int()->transform($values[1][0])];
1818  }
1819  );
1820 
1821  $questionpools = ilObjQuestionPool::_getAvailableQuestionpools(false, false, true, false, false, "write");
1822  $pools_data = [];
1823  foreach ($questionpools as $key => $p) {
1824  $pools_data[$key] = $p['title'];
1825  }
1826 
1827  $inputs = [
1828  self::QUESTION_CREATION_POOL_SELECTION_NO_POOL => $f->group([], $this->lng->txt('assessment_no_pool')),
1829  self::QUESTION_CREATION_POOL_SELECTION_EXISTING_POOL => $f->group(
1830  [$f->select($this->lng->txt('select_questionpool'), $pools_data)],
1831  $this->lng->txt('assessment_existing_pool')
1832  ),
1833  self::QUESTION_CREATION_POOL_SELECTION_NEW_POOL => $f->group(
1834  [$f->text($this->lng->txt('name'))],
1835  $this->lng->txt('assessment_new_pool')
1836  )
1837  ];
1838 
1839  return $f->switchableGroup(
1840  $inputs,
1841  $this->lng->txt('assessment_pool_selection')
1842  )->withAdditionalTransformation($trafo)
1843  ->withRequired(true)
1844  ->withValue(1);
1845  }
1846 
1847  public function showQuestionsObject()
1848  {
1849  $this->protectByWritePermission();
1850 
1851  if ($this->testrequest->raw('add')) {
1852  $this->addQuestion();
1853  return;
1854  }
1855 
1857  if (($table_cmd = $table_query->getTableAction()) !== null) {
1858  if (!$this->getQuestionsTableActions()->handleCommand(
1859  $table_cmd,
1860  $table_query->getRowIds($this->object),
1861  fn() => $this->protectByWritePermission(),
1862  fn() => $this->createQuestionpoolTargetObject('copyAndLinkQuestionsToPool'),
1863  fn() => $this->getTable()
1864  )) {
1865  return;
1866  }
1867  }
1868 
1869  $this->tpl->addBlockFile('ADM_CONTENT', 'adm_content', 'tpl.il_as_tst_questions.html', 'components/ILIAS/Test');
1870 
1871  $this->setupToolBarAndMessage($this->getTestObject()->evalTotalPersons() !== 0);
1872 
1873  $this->tabs_manager->getQuestionsSubTabs();
1874  $this->tabs_manager->activateSubTab(TabsManager::SUBTAB_ID_QST_LIST_VIEW);
1875 
1876  $this->tpl->setCurrentBlock('adm_content');
1877  $this->tpl->setVariable('ACTION_QUESTION_FORM', $this->ctrl->getFormAction($this));
1878  $this->tpl->setVariable(
1879  'QUESTIONBROWSER',
1880  $this->ui_renderer->render(
1881  $this->getTable()->getTableComponent()
1882  )
1883  );
1884  $this->tpl->parseCurrentBlock();
1885  }
1886 
1887  private function addQuestion(): void
1888  {
1889  $selected_array = [$this->testrequest->int('add')];
1890  $total = $this->getTestObject()->evalTotalPersons();
1891  if ($total > 0) {
1892  // the test was executed previously
1893  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('test_has_datasets_warning_page_view'));
1894  $this->showQuestionsObject();
1895  return;
1896  }
1897  $this->tpl->setOnScreenMessage('info', $this->lng->txt('tst_insert_questions'));
1898  $this->insertQuestionsObject($selected_array);
1899  }
1900 
1901  private function setupToolBarAndMessage(bool $has_started_test_runs): void
1902  {
1903  if (!$this->access->checkAccess('write', '', $this->ref_id)
1904  || $this->getTestObject()->isRandomTest()) {
1905  return;
1906  }
1907 
1908  if ($has_started_test_runs) {
1909  $link = $this->ui_factory->link()->standard(
1910  $this->lng->txt('test_has_datasets_warning_page_view_link'),
1911  $this->ctrl->getLinkTargetByClass([\ilTestParticipantsGUI::class])
1912  );
1913 
1914  $message = $this->lng->txt('test_has_datasets_warning_page_view');
1915  $massage_box = $this->ui_factory->messageBox()->info($message)->withLinks([$link]);
1916  $this->tpl->setCurrentBlock('mess');
1917  $this->tpl->setVariable(
1918  'MESSAGE',
1919  $this->ui_renderer->render($massage_box)
1920  );
1921  $this->tpl->parseCurrentBlock();
1922  return;
1923  }
1924 
1925  $this->toolbar->addButton($this->lng->txt('ass_create_question'), $this->ctrl->getLinkTarget($this, 'createQuestionForm'));
1926  $this->toolbar->addSeparator();
1928  }
1929 
1931  {
1932  $this->ctrl->setParameterByClass(
1933  ilTestQuestionBrowserTableGUI::class,
1936  );
1937 
1938  $toolbar->addButton(
1939  $this->lng->txt('tst_browse_for_qpl_questions'),
1940  $this->ctrl->getLinkTargetByClass(
1941  ilTestQuestionBrowserTableGUI::class,
1943  )
1944  );
1945 
1946  $this->ctrl->setParameterByClass(
1947  ilTestQuestionBrowserTableGUI::class,
1950  );
1951 
1952  $toolbar->addButton(
1953  $this->lng->txt('tst_browse_for_tst_questions'),
1954  $this->ctrl->getLinkTargetByClass(
1955  ilTestQuestionBrowserTableGUI::class,
1957  )
1958  );
1959  }
1960 
1961  public function takenObject(): void
1962  {
1963  }
1964 
1965  public function historyObject(): void
1966  {
1967  if (!$this->getTestObject()->getTestLogger()->isLoggingEnabled()
1968  || !$this->rbac_review->isAssigned($this->user->getId(), SYSTEM_ROLE_ID)
1969  && !$this->access->checkAccess('tst_history_read', '', $this->getTestObject()->getRefId())) {
1970  $this->redirectAfterMissingWrite();
1971  }
1972 
1973  $here_uri = $this->data_factory->uri(ILIAS_HTTP_PATH
1974  . '/' . $this->ctrl->getLinkTargetByClass(self::class, self::SHOW_LOGS_CMD));
1975  list($url_builder, $action_parameter_token, $row_id_token) = (new URLBuilder($here_uri))->acquireParameters(
1976  LogTable::QUERY_PARAMETER_NAME_SPACE,
1977  LogTable::ACTION_TOKEN_STRING,
1978  LogTable::ENTRY_TOKEN_STRING
1979  );
1980 
1981  if ($this->request_wrapper->has($action_parameter_token->getName())) {
1982  $this->getTestObject()->getTestLogViewer()->executeLogTableAction(
1983  $url_builder,
1984  $action_parameter_token,
1985  $row_id_token,
1986  $this->getTestObject()->getRefId()
1987  );
1988  }
1989 
1990  $this->toolbar->addComponent(
1991  $this->ui_factory->button()->standard(
1992  $this->lng->txt('export_legacy_logs'),
1993  $this->ctrl->getLinkTargetByClass(self::class, 'exportLegacyLogs')
1994  )
1995  );
1996  $this->tabs_manager->activateTab(TabsManager::TAB_ID_HISTORY);
1997 
1998  list($filter, $table_gui) = $this->getTestObject()->getTestLogViewer()->getLogTable(
1999  $url_builder,
2000  $action_parameter_token,
2001  $row_id_token,
2002  $this->getTestObject()->getRefId()
2003  );
2004 
2005  $this->tpl->setVariable('ADM_CONTENT', $this->ui_renderer->render([$filter, $table_gui]));
2006  }
2007 
2008  public function exportLegacyLogsObject(): void
2009  {
2010  $this->protectByWritePermission();
2011 
2012  $csv_output = $this->getTestObject()->getTestLogViewer()->getLegacyLogExportForObjId($this->getTestObject()->getId());
2013 
2015  $csv_output,
2016  "legacy_logs_for_{$this->getTestObject()->getRefId()}.csv"
2017  );
2018  }
2019 
2023  public function participantsActionObject(): void
2024  {
2025  $command = $this->testrequest->strVal('command');
2026  if ($command === '') {
2027  $method = $command . 'Object';
2028  if (method_exists($this, $method)) {
2029  $this->$method();
2030  return;
2031  }
2032  }
2033  $this->ctrl->redirect($this, 'participants');
2034  }
2035 
2039  public function defaultsObject()
2040  {
2041  $this->protectByWritePermission();
2042 
2043  $this->tabs_manager->activateTab(TabsManager::TAB_ID_SETTINGS);
2044 
2045  $this->toolbar->setFormAction($this->ctrl->getFormAction($this, 'addDefaults'));
2046  $this->toolbar->addFormButton($this->lng->txt('add'), 'addDefaults');
2047  $this->toolbar->addInputItem(new ilTextInputGUI($this->lng->txt('tst_defaults_defaults_of_test'), 'name'), true);
2048  $table = new ilTestPersonalDefaultSettingsTableGUI($this, 'defaults');
2049  $defaults = $this->getTestObject()->getAvailableDefaults();
2050  $table->setData($defaults);
2051  $this->tpl->setContent($table->getHTML());
2052  }
2053 
2057  public function deleteDefaultsObject()
2058  {
2059  $this->protectByWritePermission();
2060 
2061  $defaults_ids = $this->testrequest->retrieveArrayOfIntsFromPost('chb_defaults');
2062  if ($defaults_ids !== null && $defaults_ids !== []) {
2063  foreach ($defaults_ids as $test_default_id) {
2064  $this->getTestObject()->deleteDefaults($test_default_id);
2065  }
2066  } else {
2067  $this->tpl->setOnScreenMessage('info', $this->lng->txt('select_one'));
2068  }
2069  $this->defaultsObject();
2070  }
2071 
2076  {
2077  $this->protectByWritePermission();
2078 
2079  $this->applyDefaultsObject(true);
2080  return;
2081  }
2082 
2086  public function applyDefaultsObject($confirmed = false): void
2087  {
2088  $this->protectByWritePermission();
2089 
2090  $defaults_id = $this->testrequest->retrieveArrayOfIntsFromPost('chb_defaults');
2091  if ($defaults_id === []) {
2092  $this->tpl->setOnScreenMessage('info', $this->lng->txt('tst_defaults_apply_select_one'));
2093  $this->defaultsObject();
2094  return;
2095  }
2096 
2097  // do not apply if user datasets exist
2098  if ($this->getTestObject()->evalTotalPersons() > 0
2099  || ($defaults = $this->getTestObject()->getTestDefaults($defaults_id[0])) === null) {
2100  $this->tpl->setOnScreenMessage('info', $this->lng->txt('tst_defaults_apply_not_possible'));
2101  $this->defaultsObject();
2102  return;
2103  }
2104 
2105  $default_settings = unserialize(
2106  $defaults['defaults'],
2107  ['allowed_classes' => [DateTimeImmutable::class]]
2108  );
2109 
2110  if (isset($default_settings['isRandomTest'])) {
2111  if ($default_settings['isRandomTest']) {
2112  $new_question_set_type = ilObjTest::QUESTION_SET_TYPE_RANDOM;
2113  $this->getTestObject()->setQuestionSetType(ilObjTest::QUESTION_SET_TYPE_RANDOM);
2114  } else {
2115  $new_question_set_type = ilObjTest::QUESTION_SET_TYPE_FIXED;
2116  $this->getTestObject()->setQuestionSetType(ilObjTest::QUESTION_SET_TYPE_FIXED);
2117  }
2118  } elseif (isset($default_settings['questionSetType'])) {
2119  $new_question_set_type = $default_settings['questionSetType'];
2120  }
2121  $old_question_set_type = $this->getTestObject()->getQuestionSetType();
2122  $question_set_type_setting_switched = ($old_question_set_type != $new_question_set_type);
2123 
2124  $old_question_set_config = $this->test_question_set_config_factory->getQuestionSetConfig();
2125 
2126  switch (true) {
2127  case !$question_set_type_setting_switched:
2128  case !$old_question_set_config->doesQuestionSetRelatedDataExist():
2129  case $confirmed:
2130 
2131  break;
2132 
2133  default:
2134 
2135  $confirmation = new ilTestSettingsChangeConfirmationGUI($this->testrequest, $this->getTestObject());
2136 
2137  $confirmation->setFormAction($this->ctrl->getFormAction($this));
2138  $confirmation->setCancel($this->lng->txt('cancel'), 'defaults');
2139  $confirmation->setConfirm($this->lng->txt('confirm'), 'confirmedApplyDefaults');
2140 
2141  $confirmation->setOldQuestionSetType($this->getTestObject()->getQuestionSetType());
2142  $confirmation->setNewQuestionSetType($new_question_set_type);
2143  $confirmation->setQuestionLossInfoEnabled(false);
2144  $confirmation->build();
2145 
2146  $confirmation->populateParametersFromPost();
2147 
2148  $this->tpl->setContent($this->ctrl->getHTML($confirmation));
2149 
2150  return;
2151  }
2152 
2153  if ($question_set_type_setting_switched && !$this->getTestObject()->getOfflineStatus()) {
2154  $this->getTestObject()->setOfflineStatus(true);
2155  $info = $this->lng->txt('tst_set_offline_due_to_switched_question_set_type_setting');
2156  $this->tpl->setOnScreenMessage('info', $info, true);
2157  }
2158 
2159  $info = $this->getTestObject()->applyDefaults($defaults);
2160  if ($info === '') {
2161  $this->tpl->setOnScreenMessage('success', $this->lng->txt('tst_defaults_applied'), true);
2162  } else {
2163  $this->tpl->setOnScreenMessage('info', $this->lng->txt($info), true);
2164  }
2165 
2166 
2167 
2168  if ($question_set_type_setting_switched && $old_question_set_config->doesQuestionSetRelatedDataExist()) {
2169  $old_question_set_config->removeQuestionSetRelatedData();
2170  }
2171 
2172  $this->ctrl->redirect($this, 'defaults');
2173  }
2174 
2178  public function addDefaultsObject(): void
2179  {
2180  $this->protectByWritePermission();
2181 
2182  $name = $this->testrequest->strVal('name');
2183  if ($name !== '') {
2184  $this->getTestObject()->addDefaults($name);
2185  } else {
2186  $this->tpl->setOnScreenMessage('info', $this->lng->txt('tst_defaults_enter_name'));
2187  }
2188  $this->defaultsObject();
2189  }
2190 
2191  private function isCommandClassAnyInfoScreenChild(): bool
2192  {
2193  if (in_array($this->ctrl->getCmdClass(), self::INFO_SCREEN_CHILD_CLASSES)) {
2194  return true;
2195  }
2196 
2197  return false;
2198  }
2199 
2200  private function infoScreenObject(): void
2201  {
2202  $this->ctrl->redirectByClass(
2203  [ilRepositoryGUI::class, self::class, ilInfoScreenGUI::class]
2204  );
2205  }
2206 
2207  private function forwardToInfoScreen(): void
2208  {
2209  if (!$this->access->checkAccess('visible', '', $this->ref_id)
2210  && !$this->access->checkAccess('read', '', $this->ref_id)) {
2211  $this->redirectAfterMissingRead();
2212  }
2213 
2214  if ($this->getTestObject()->getMainSettings()->getAdditionalSettings()->getHideInfoTab()) {
2215  $this->ctrl->redirectByClass([self::class, TestScreenGUI::class], TestScreenGUI::DEFAULT_CMD);
2216  }
2217 
2218  $this->tabs_manager->activateTab(TabsManager::TAB_ID_INFOSCREEN);
2219 
2220  if ($this->access->checkAccess('read', '', $this->ref_id)) {
2221  $this->trackTestObjectReadEvent();
2222  }
2223  $info = new ilInfoScreenGUI($this);
2224 
2225  if ($this->isCommandClassAnyInfoScreenChild()) {
2226  $this->ctrl->forwardCommand($info);
2227  }
2228 
2230  $this->getTestObject(),
2231  $this->test_player_factory->getPlayerGUI(),
2232  $this->test_question_set_config_factory->getQuestionSetConfig(),
2233  $this->test_session_factory->getSession(),
2234  $this->db,
2235  $this->access,
2236  $this->ctrl,
2237  $this->lng,
2240  $this->tpl,
2242  );
2243 
2244  $toolbar->setCloseFormTag(false);
2245 
2246  $toolbar->setSessionLockString('');
2247  $toolbar->build();
2248  $toolbar->sendMessages();
2249 
2250  $info->enablePrivateNotes();
2251 
2252  $info->addSection($this->lng->txt('tst_general_properties'));
2253  $info->addProperty(
2254  $this->lng->txt('author'),
2255  $this->refinery->encode()->htmlSpecialCharsAsEntities()->transform(
2256  $this->getTestObject()->getAuthor()
2257  )
2258  );
2259  $info->addProperty(
2260  $this->lng->txt('title'),
2261  $this->refinery->encode()->htmlSpecialCharsAsEntities()->transform(
2262  $this->getTestObject()->getTitle()
2263  )
2264  );
2265 
2266  if ($this->type !== 'tst') {
2267  $info->hideFurtherSections(false);
2268  }
2269 
2270  $info->addSection($this->lng->txt('tst_sequence_properties'));
2271  $info->addProperty(
2272  $this->lng->txt('tst_sequence'),
2273  $this->lng->txt(
2274  $this->getTestObject()->getMainSettings()->getParticipantFunctionalitySettings()->getPostponedQuestionsMoveToEnd()
2275  ? 'tst_sequence_postpone' : 'tst_sequence_fixed'
2276  )
2277  );
2278 
2279  $info->addSection($this->lng->txt('tst_heading_scoring'));
2280  $info->addProperty(
2281  $this->lng->txt('tst_text_count_system'),
2282  $this->lng->txt(
2283  ($this->getTestObject()->getCountSystem() == SettingsScoring::COUNT_PARTIAL_SOLUTIONS) ? 'tst_count_partial_solutions' : 'tst_count_correct_solutions'
2284  )
2285  );
2286  if ($this->getTestObject()->isRandomTest()) {
2287  $info->addProperty($this->lng->txt('tst_pass_scoring'), $this->lng->txt(($this->getTestObject()->getPassScoring() == ilObjTest::SCORE_BEST_PASS) ? 'tst_pass_best_pass' : 'tst_pass_last_pass'));
2288  }
2289 
2290  $info->addSection($this->lng->txt('tst_score_reporting'));
2291  $info->addProperty(
2292  $this->lng->txt('tst_score_reporting'),
2293  $this->getTestObject()->getScoreSettings()->getResultSummarySettings()
2294  ->getScoreReporting()->getTranslatedValue($this->lng)
2295  );
2296  $reporting_date = $this->getTestObject()
2297  ->getScoreSettings()
2298  ->getResultSummarySettings()
2299  ->getReportingDate();
2300  if ($reporting_date !== null) {
2301  $info->addProperty(
2302  $this->lng->txt('tst_score_reporting_date'),
2303  $reporting_date
2304  ->setTimezone(new DateTimeZone($this->user->getTimeZone()))
2305  ->format($this->user->getDateTimeFormat()->toString())
2306  );
2307  }
2308 
2309  $info->addSection($this->lng->txt('tst_session_settings'));
2310  $info->addProperty($this->lng->txt('tst_nr_of_tries'), $this->getTestObject()->getNrOfTries() === 0 ? $this->lng->txt('unlimited') : (string) $this->getTestObject()->getNrOfTries());
2311  if ($this->getTestObject()->getNrOfTries() != 1) {
2312  $info->addProperty(
2313  $this->lng->txt('tst_nr_of_tries_of_user'),
2314  ($this->test_session_factory->getSession()->getPass() === 0) ?
2315  $this->lng->txt('tst_no_tries') : (string) $this->test_session_factory->getSession()->getPass()
2316  );
2317  }
2318 
2319  if ($this->getTestObject()->getEnableProcessingTime()) {
2320  $info->addProperty($this->lng->txt('tst_processing_time'), $this->getTestObject()->getProcessingTime());
2321  }
2322 
2323  $starting_time = $this->getTestObject()->getStartingTime();
2324  if ($this->getTestObject()->isStartingTimeEnabled() && $starting_time !== 0) {
2325  $info->addProperty($this->lng->txt('tst_starting_time'), ilDatePresentation::formatDate(new ilDateTime($starting_time, IL_CAL_UNIX)));
2326  }
2327  $ending_time = $this->getTestObject()->getEndingTime();
2328  if ($this->getTestObject()->isEndingTimeEnabled() && $ending_time != 0) {
2329  $info->addProperty($this->lng->txt('tst_ending_time'), ilDatePresentation::formatDate(new ilDateTime($ending_time, IL_CAL_UNIX)));
2330  }
2331  $info->addMetaDataSections($this->getTestObject()->getId(), 0, $this->getTestObject()->getType());
2332 
2333  $this->ctrl->forwardCommand($info);
2334  }
2335 
2336  protected function removeImportFailsObject()
2337  {
2338  $qsaImportFails = new ilAssQuestionSkillAssignmentImportFails($this->getTestObject()->getId());
2339  $qsaImportFails->deleteRegisteredImportFails();
2340  $sltImportFails = new ilTestSkillLevelThresholdImportFails($this->getTestObject()->getId());
2341  $sltImportFails->deleteRegisteredImportFails();
2342 
2343  $this->ctrl->redirectByClass([ilRepositoryGUI::class, self::class, ilInfoScreenGUI::class]);
2344  }
2345 
2346  public function addLocatorItems(): void
2347  {
2348  switch ($this->ctrl->getCmd()) {
2349  case "run":
2350  case "infoScreen":
2351  case "redirectToInfoScreen":
2352  case "start":
2353  case "resume":
2354  case "previous":
2355  case "next":
2356  case "summary":
2357  case "finishTest":
2358  case "outCorrectSolution":
2359  case "showAnswersOfUser":
2360  case "outUserResultsOverview":
2361  case "backFromSummary":
2362  case "show_answers":
2363  case "setsolved":
2364  case "resetsolved":
2365  case "outTestSummary":
2366  case "outQuestionSummary":
2367  case "gotoQuestion":
2368  case "selectImagemapRegion":
2369  case "confirmSubmitAnswers":
2370  case "finalSubmission":
2371  case "postpone":
2372  case "outUserPassDetails":
2373  case "checkPassword":
2374  $this->locator->addItem(
2375  $this->getTestObject()->getTitle(),
2376  $this->ctrl->getLinkTargetByClass(
2377  [self::class, TestScreenGUI::class],
2378  TestScreenGUI::DEFAULT_CMD
2379  ),
2380  '',
2381  $this->testrequest->getRefId()
2382  );
2383  break;
2384  case "eval_stat":
2385  case "evalAllUsers":
2386  case "evalUserDetail":
2387  $this->locator->addItem(
2388  $this->getTestObject()->getTitle(),
2389  $this->ctrl->getLinkTarget($this, 'eval_stat'),
2390  '',
2391  $this->testrequest->getRefId()
2392  );
2393  break;
2394  case "importFile":
2395  case "cloneAll":
2396  case "importVerifiedFile":
2397  case "cancelImport":
2398  break;
2399  default:
2400  $this->locator->addItem(
2401  $this->getTestObject()->getTitle(),
2402  $this->ctrl->getLinkTargetByClass(
2403  [self::class, TestScreenGUI::class],
2404  TestScreenGUI::DEFAULT_CMD
2405  ),
2406  '',
2407  $this->testrequest->getRefId()
2408  );
2409  break;
2410  }
2411  }
2412 
2413  public function statisticsObject()
2414  {
2415  }
2416 
2420  public function certificateObject()
2421  {
2422  $this->tabs_manager->activateTab(TabsManager::TAB_ID_SETTINGS);
2423 
2424  $guiFactory = new ilCertificateGUIFactory();
2425  $output_gui = $guiFactory->create($this->getTestObject());
2426 
2427  $output_gui->certificateEditor();
2428  }
2429 
2435  public function getTabs(): void
2436  {
2437  $this->help->setScreenIdComponent("tst");
2438 
2439  if ($this->tabs_manager === null) {
2440  return;
2441  }
2442 
2443  if ($this->getObjectiveOrientedContainer()->isObjectiveOrientedPresentationRequired()) {
2444  $courseLink = ilLink::_getLink($this->getObjectiveOrientedContainer()->getRefId());
2445  $this->tabs_manager->setParentBackLabel($this->lng->txt('back_to_objective_container'));
2446  $this->tabs_manager->setParentBackHref($courseLink);
2447  }
2448 
2449  $this->tabs_manager->perform();
2450  }
2451 
2452  public static function accessViolationRedirect()
2453  {
2455  global $DIC;
2456  $main_tpl = $DIC->ui()->mainTemplate();
2457 
2458  $main_tpl->setOnScreenMessage('failure', $DIC->language()->txt("no_permission"), true);
2459  $DIC->ctrl()->redirectByClass(TestScreenGUI::class, TestScreenGUI::DEFAULT_CMD);
2460  }
2461 
2468  public static function _goto($target)
2469  {
2470  global $DIC;
2471  $main_tpl = $DIC->ui()->mainTemplate();
2472  $ilAccess = $DIC['ilAccess'];
2473  $ilErr = $DIC['ilErr'];
2474  $lng = $DIC['lng'];
2475 
2476  if ($ilAccess->checkAccess('read', '', (int) $target)
2477  || $ilAccess->checkAccess('visible', '', (int) $target)) {
2478  $DIC->ctrl()->setParameterByClass(self::class, 'ref_id', (int) $target);
2479  $DIC->ctrl()->redirectByClass(
2480  [
2481  ilRepositoryGUI::class,
2482  ilObjTestGUI::class,
2483  TestScreenGUI::class
2484  ],
2485  TestScreenGUI::DEFAULT_CMD
2486  );
2487  } elseif ($ilAccess->checkAccess('read', '', ROOT_FOLDER_ID)) {
2488  $main_tpl->setOnScreenMessage('info', sprintf(
2489  $lng->txt('msg_no_perm_read_item'),
2491  ), true);
2493  }
2494 
2495  $ilErr->raiseError($lng->txt('msg_no_perm_read_lm'), $ilErr->FATAL);
2496  }
2497 
2498  public function copyQuestionsToPoolObject()
2499  {
2500  $this->copyQuestionsToPool($this->testrequest->raw('q_id'), $this->testrequest->raw('sel_qpl'));
2501  $this->ctrl->redirect($this, self::SHOW_QUESTIONS_CMD);
2502  }
2503 
2508  public function copyQuestionsToPool(array $question_ids, int $qpl_id): stdClass
2509  {
2510  $target_pool = new ilObjQuestionPool($qpl_id, false);
2511  $new_ids = [];
2512  foreach ($question_ids as $q_id) {
2513  $new_id = $this->copyQuestionToPool(assQuestion::instantiateQuestionGUI($q_id), $target_pool);
2514  $new_ids[$q_id] = $new_id;
2515  }
2516 
2517  $result = new stdClass();
2518  $result->ids = $new_ids;
2519  $result->qpoolid = $qpl_id;
2520 
2521  return $result;
2522  }
2523 
2524  public function copyQuestionToPool(assQuestionGUI $source_question_gui, ilObjQuestionPool $target_pool): int
2525  {
2526  $new_title = $target_pool->appendCounterToQuestionTitleIfNecessary(
2527  $source_question_gui->getObject()->getTitle()
2528  );
2529 
2530  return $source_question_gui->getObject()->createNewOriginalFromThisDuplicate($target_pool->getId(), $new_title);
2531  }
2532 
2534  int $ref_id = null,
2535  array $question_ids = []
2536  ) {
2537 
2538  $ref_id = $ref_id ?? $this->testrequest->int('sel_qpl');
2539  if ($ref_id === null
2540  || $ref_id === 0) {
2541  $this->tpl->setOnScreenMessage('failure', $this->lng->txt("questionpool_not_selected"));
2542  $this->showQuestionsObject();
2543  return;
2544  }
2545 
2546  $qpl_id = $this->obj_data_cache->lookupObjId($ref_id);
2547 
2548 
2549  if ($question_ids === []) {
2550  $question_ids = $this->testrequest->getQuestionIds();
2551  $question_id = $this->testrequest->getQuestionId();
2552  if ($question_ids === [] && $question_id !== 0) {
2553  $question_ids = [$question_id];
2554  }
2555  }
2556 
2557  if ($question_ids === []) {
2558  $this->tpl->setOnScreenMessage('failure', $this->lng->txt("tst_no_question_selected_for_moving_to_qpl"));
2559  $this->ctrl->redirect($this, 'questions');
2560  }
2561 
2562  $result = $this->copyQuestionsToPool($question_ids, $qpl_id);
2563 
2564  foreach ($result->ids as $oldId => $newId) {
2565  $questionInstance = assQuestion::instantiateQuestion($oldId);
2566 
2567  $original_question_id = $questionInstance->getOriginalId();
2568  if ($original_question_id !== null
2569  && $this->test_questions_repository->originalQuestionExists($original_question_id)) {
2570  $oldOriginal = assQuestion::instantiateQuestion($original_question_id);
2571  $oldOriginal->delete($oldOriginal->getId());
2572  }
2573  assQuestion::saveOriginalId($questionInstance->getId(), $newId);
2574  }
2575 
2576  $this->tpl->setOnScreenMessage('success', $this->lng->txt('tst_qst_added_to_pool_' . (count($result->ids) > 1 ? 'p' : 's')), true);
2577  $this->ctrl->redirect($this, self::SHOW_QUESTIONS_CMD);
2578  }
2579 
2580  public function copyToQuestionpoolObject()
2581  {
2582  $this->createQuestionpoolTargetObject('copyQuestionsToPool');
2583  }
2584 
2586  {
2587  if (!$this->access->checkAccess('write', '', $this->object->getRefId())
2588  || !$this->checkPermissionBool('create', '', 'qpl')) {
2589  $this->redirectAfterMissingWrite();
2590  }
2591 
2592  if ($this->testrequest->raw('title')) {
2593  $title = $this->testrequest->raw('title');
2594  } else {
2595  $title = $this->testrequest->raw('txt_qpl');
2596  }
2597 
2598  if (!$title) {
2599  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('questionpool_not_entered'));
2600  $this->createQuestionpoolTargetObject('createQuestionPoolAndCopy');
2601  return;
2602  }
2603 
2604  $question_pool = $this->createQuestionPool($title, $this->testrequest->raw('description'));
2605  $_REQUEST['sel_qpl'] = $question_pool->getRefId();
2606 
2608  }
2609 
2614  public function createQuestionpoolTargetObject(string $cmd): void
2615  {
2616  $this->protectByWritePermission();
2617 
2618  $this->tabs_manager->getQuestionsSubTabs();
2619  $this->tabs_manager->activateSubTab(TabsManager::SUBTAB_ID_QST_LIST_VIEW);
2620 
2621  $questionpools = $this->getTestObject()->getAvailableQuestionpools(
2622  false,
2623  false,
2624  false,
2625  true,
2626  false,
2627  'write'
2628  );
2629 
2630  if ($questionpools === []) {
2631  $form = $this->getTargetQuestionpoolForm($questionpools, 'createQuestionPoolAndCopy');
2632  } else {
2633  $form = $this->getTargetQuestionpoolForm($questionpools, $cmd);
2634 
2635  switch ($cmd) {
2636  case 'copyQuestionsToPool':
2637  break;
2638 
2639  case 'copyAndLinkQuestionsToPool':
2640  $hidden = new ilHiddenInputGUI('link');
2641  $hidden->setValue('1');
2642  $form->addItem($hidden);
2643  break;
2644  }
2645  }
2646 
2647  $this->tpl->setContent($form->getHTML());
2648  }
2649 
2650  protected function getTargetQuestionpoolForm($questionpools, string $cmd): ilPropertyFormGUI
2651  {
2652  $form = new ilPropertyFormGUI();
2653  $form->setFormAction($this->ctrl->getFormAction($this));
2654  $form->addCommandButton($cmd, $this->lng->txt('submit'));
2655  $form->addCommandButton('cancelCreateQuestion', $this->lng->txt('cancel'));
2656 
2657  if (count($questionpools) == 0) {
2658  $form->setTitle($this->lng->txt("tst_enter_questionpool"));
2659 
2660  $title = new ilTextInputGUI($this->lng->txt('title'), 'title');
2661  $title->setRequired(true);
2662  $form->addItem($title);
2663 
2664  $description = new ilTextAreaInputGUI($this->lng->txt('description'), 'description');
2665  $form->addItem($description);
2666  } else {
2667  $form->setTitle($this->lng->txt("tst_select_questionpool"));
2668 
2669  $selectOptions = [
2670  '' => $this->lng->txt('please_select')
2671  ];
2672 
2673  foreach ($questionpools as $key => $value) {
2674  $selectOptions[$key] = $value["title"];
2675  }
2676 
2677  $select = new ilSelectInputGUI($this->lng->txt('tst_source_question_pool'), 'sel_qpl');
2678  $select->setRequired(true);
2679  $select->setOptions($selectOptions);
2680 
2681  $form->addItem($select);
2682  }
2683 
2685  if ($table_query->getTableAction() !== null) {
2686  $question_ids = $table_query->getRowIds($this->object);
2687  } elseif ($this->testrequest->isset('q_id') && is_array($this->testrequest->raw('q_id'))) {
2688  $question_ids = $this->testrequest->raw('q_id');
2689  }
2690 
2691  foreach ($question_ids as $id) {
2692  $hidden = new ilHiddenInputGUI('q_id[]');
2693  $hidden->setValue((string) $id);
2694  $form->addItem($hidden);
2695  }
2696 
2697  return $form;
2698  }
2699 
2700  protected function protectByWritePermission(): void
2701  {
2702  if (!$this->access->checkAccess('write', '', $this->ref_id)) {
2703  $this->tpl->setOnScreenMessage('info', $this->lng->txt('cannot_edit_test'), true);
2704  $this->ctrl->redirectByClass([ilRepositoryGUI::class, self::class, ilInfoScreenGUI::class]);
2705  }
2706  }
2707 
2709  {
2710  if (!ilLOSettings::isObjectiveTest($this->ref_id)) {
2711  return;
2712  }
2713 
2714  $path = $this->tree->getPathFull($this->ref_id);
2715 
2716  while ($parent = array_pop($path)) {
2717  if ($parent['type'] === 'crs') {
2718  $container_ref_id = $parent['ref_id'];
2719  break;
2720  }
2721  }
2722 
2723  $container_obj_id = ilObject2::_lookupObjId($container_ref_id);
2724 
2725  $this->objective_oriented_container->setObjId($container_obj_id);
2726  $this->objective_oriented_container->setRefId($container_ref_id);
2727  }
2728 
2730  {
2732  }
2733 
2735  {
2736  return new TestScreenGUI(
2737  $this->getTestObject(),
2738  $this->user,
2739  $this->ui_factory,
2740  $this->ui_renderer,
2741  $this->lng,
2742  $this->refinery,
2743  $this->ctrl,
2744  $this->tpl,
2745  $this->content_style,
2746  $this->http,
2747  $this->tabs_manager,
2748  $this->access,
2749  $this->test_access,
2750  $this->db,
2751  $this->rbac_system
2752  );
2753  }
2754 
2756  {
2757  if ($this->table_query === null) {
2758  $id = $this->object ? $this->object->getId() : '';
2759  $this->table_query = new QuestionsTableQuery(
2760  $this->http,
2761  $this->refinery,
2762  $this->data_factory,
2763  ['qlist', $id]
2764  );
2765  }
2766  return $this->table_query;
2767  }
2768 
2770  {
2771  if ($this->table_actions === null) {
2772  $this->table_actions = new QuestionsTableActions(
2773  $this->ui_factory,
2774  $this->ui_renderer,
2775  $this->tpl,
2776  $this->request,
2777  $this->getQuestionsTableQuery(),
2778  $this->lng,
2779  $this->ctrl,
2780  $this->test_questions_repository,
2781  new QuestionPrinter(
2782  $this->ui_factory,
2783  $this->tpl,
2784  $this->tabs_manager,
2785  $this->toolbar,
2786  $this->refinery,
2787  $this->lng,
2788  $this->ctrl,
2789  $this->user,
2791  $this->getTestObject()
2792  ),
2793  $this->object,
2794  $this->getTestObject()->getGlobalSettings()->isAdjustingQuestionsWithResultsAllowed(),
2795  $this->getTestObject()->evalTotalPersons() !== 0,
2796  $this->getTestObject()->isRandomTest(),
2797  $this->test_question_set_config_factory
2798  );
2799  }
2800  return $this->table_actions;
2801  }
2802 
2803  protected function getTable(): QuestionsTable
2804  {
2805  return new QuestionsTable(
2806  $this->ui_factory,
2807  $this->refinery,
2808  $this->http->request(),
2809  $this->getQuestionsTableActions(),
2810  $this->lng,
2811  $this->object,
2814  );
2815  }
2816 }
showNextViewAfterQuestionSave(assQuestionGUI $question_gui, string $target)
TestResultRepository $test_pass_result_repository
const ADDITIONAL_CONTENT_EDITING_MODE_IPE
static get(string $a_var)
static _goto($target)
Redirect script to call a test with the test reference id.
Class ilObjectMetaDataGUI.
setCopyToExistingPoolOnSave(?int $pool_ref_id)
Readable part of repository interface to ilComponentDataDB.
TaxonomyService $taxonomy
static formatDate(ilDateTime $date, bool $a_skip_day=false, bool $a_include_wd=false, bool $include_seconds=false, ilObjUser $user=null,)
ilTestQuestionSetConfigFactory $test_question_set_config_factory
QuestionsTableQuery $table_query
This describes commonalities between all forms.
Definition: Form.php:32
TestTopListRepository $toplist_repository
ilTestSessionFactory $test_session_factory
insertQuestionsObject(array $selected_array=null)
const IL_INST_ID
Definition: constants.php:40
setCloseFormTag(bool $a_val)
getTabs()
adds tabs to tab gui object
Export User Interface Class.
This class represents a selection list property in a property form.
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...
fullscreenObject()
show fullscreen view
GeneralQuestionPropertiesRepository $questionrepository
const QUESTION_CREATION_POOL_SELECTION_NO_POOL
GUI class for the workflow of copying objects.
const QUESTION_SET_TYPE_RANDOM
addPostCreationTasksToQuestionGUI(assQuestionGUI $question_gui)
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...
ilUIService $ui_service
prepareOutput(bool $show_sub_objects=true)
ilComponentFactory $component_factory
const SYSTEM_ROLE_ID
Definition: constants.php:29
afterSave(ilObject $new_object)
save object public
static stripSlashes(string $a_str, bool $a_strip_html=true, string $a_allow="")
static getQuestionTypeByTypeId($type_id)
buildInputPosition(array $questions)
importVerifiedFileObject(bool $skip_retrieve_selected_questions=false)
imports question(s) into the questionpool (after verification)
Help GUI class.
createQuestionpoolTargetObject(string $cmd)
Called when a new question should be created from a test Important: $cmd may be overwritten if no que...
TestQuestionsRepository $test_questions_repository
buildImportQuestionsSelectionForm(string $form_cmd, string $importdir, string $qtifile, string $path_to_uploaded_file_in_temp_dir=null)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This describes select field.
Definition: Select.php:28
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Import class.
executeAfterQuestionSaveTasks(assQuestionGUI $question_gui)
This is what a radio-input looks like.
Definition: Radio.php:28
downloadFileObject()
download file
ilDBInterface $db
static deliverData(string $a_data, string $a_filename, string $mime="application/octet-stream")
TitleColumnsBuilder $title_builder
const IL_CAL_UNIX
UIRenderer $ui_renderer
ParticipantRepository $participant_repository
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Refinery $refinery
static _getQuestionGUI(string $question_type='', int $question_id=-1)
Creates a question gui representation and returns the alias to the question gui.
forwardCommandToQuestionPreview(string $cmd, assQuestionGUI $question_gui=null)
addDefaultsObject()
Adds the defaults of this test to the defaults.
Base Exception for all Exceptions relating to Modules/Test.
buildResultsFilePath(string $importdir, string $subdir)
importObject(?object $a_new_obj, string $a_tmp_file, string $a_filename, string $a_type, string $a_comp="", bool $a_copy_file=false)
$ilErr
Definition: raiseError.php:17
$path
Definition: ltiservices.php:30
participantsActionObject()
Evaluates the actions on the participants page.
ilObjectDataCache $obj_data_cache
static _lookupObjId(int $ref_id)
editQuestion(bool $checkonly=false, ?bool $is_save_cmd=null)
setCreationMode(bool $mode=true)
If true, a creation screen is displayed the current [ref_id] does belong to the parent class The mode...
ResultsDataFactory $results_data_factory
Interface ilCtrlBaseClassInterface describes ilCtrl base classes.
deleteUploadedImportFile(string $path_to_uploaded_file_in_temp_dir)
defaultsObject()
Displays the settings page for test defaults.
HTTPServices $http
ContentStyle $content_style
executeAfterQuestionCreationTasks(assQuestionGUI $question_gui)
ilLanguage $lng
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static instantiateQuestion(int $question_id)
Importer class for files.
ilTestParticipantAccessFilterFactory $participant_access_filter_factory
static http()
Fetches the global http state from ILIAS.
createQuestionFormObject(Form $form=null)
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')
ilGlobalTemplateInterface $tpl
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _lookupTitle(int $obj_id)
ilNavigationHistory $navigation_history
GUI class for LTI provider object settings.
const INFO_SCREEN_CHILD_CLASSES
copyQuestionsToPool(array $question_ids, int $qpl_id)
getTargetQuestionpoolForm($questionpools, string $cmd)
ilTestObjectiveOrientedContainer $objective_oriented_container
applyDefaultsObject($confirmed=false)
Applies the selected test defaults.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
download_paragraphObject()
download source code paragraph
DataFactory $data_factory
ilTestPageGUI: ilPageEditorGUI, ilEditClipboardGUI, ilMDEditorGUI ilTestPageGUI: ilPublicUserProfile...
This describes switchable group inputs.
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
ilTestPlayerFactory $test_player_factory
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)
createQuestionPool($name="dummy", $description="")
ilTestAccess $test_access
Class ilObjFile.
global $DIC
Definition: shib_login.php:25
showEditTestPageGUI(string $cmd)
Output class for assessment test evaluation.
ilToolbarGUI $toolbar
ResponseHandler $response_handler
populateQuestionBrowserToolbarButtons(ilToolbarGUI $toolbar)
QPLRequestDataCollector $qplrequest
addQuestionTitleToObjectTitle(string $question_title)
RequestDataCollector $testrequest
setRequired(bool $a_required)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
withValue($value)
Get an input like this with another value displayed on the client side.
Definition: Group.php:59
Last visited history for repository items.
importFile(string $file_to_import, string $path_to_uploaded_file_in_temp_dir)
static saveOriginalId(int $questionId, int $originalId)
withValue($value)
Get an input like this with another value displayed on the client side.
copyQuestionToPool(assQuestionGUI $source_question_gui, ilObjQuestionPool $target_pool)
checkPermissionBool(string $perm, string $cmd="", string $type="", ?int $ref_id=null)
static isObjectiveTest(int $a_trst_ref_id)
Check if test ref_id is used in an objective course.
static redirect(string $a_script)
Class that handles PDF generation for test and assessment.
executeCommand()
execute command
exportObject()
Gateway for exports initiated from workspace, as there is a generic forward to {objTypeMainGUI}::expo...
const QUESTION_CREATION_POOL_SELECTION_EXISTING_POOL
QuestionsTableActions $table_actions
retrieveAdditionalDidacticTemplateOptions()
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
SkillService $skills_service
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
setMoveAfterQuestionId(?int $question_id)
appendCounterToQuestionTitleIfNecessary(string $title)
certificateObject()
Shows the certificate editor.
retrieveSelectedQuestionsFromImportQuestionsSelectionForm(string $form_cmd, string $importdir, string $qtifile, ServerRequestInterface $request)
sendParagraph(string $par_id, string $filename)
__construct(Container $dic, ilPlugin $plugin)
getReturnLocation(string $cmd, string $default_location="")
Get return location for command (command is method name without "Object", e.g.
initCreateForm(string $new_type)
This class represents a text area property in a property form.
const ADDITIONAL_CONTENT_EDITING_MODE_RTE
ilAccessHandler $access
setTestAccess(ilTestAccess $test_access)
setCopyToNewPoolOnSave(?string $pool_title)
ResultsPresentationFactory $results_presentation_factory
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
const QUESTION_SET_TYPE_FIXED
Class ilTestParticipantsGUI.
This describes commonalities between all inputs.
Definition: Input.php:46
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
ExportRepository $export_repository
ExportImportFactory $export_factory
setupToolBarAndMessage(bool $has_started_test_runs)
array buildImportDirectoriesFromImportFile(string $file_to_import)
getSelectedPersonalDefaultsSettingsFromForm()
Service GUI class for tests.
redirectTo_SettingsMainGUI_showForm_Object()
const QUESTION_CREATION_POOL_SELECTION_NEW_POOL
GlobalScreen $global_screen
deleteDefaultsObject()
Deletes selected test defaults.
copyAndLinkQuestionsToPoolObject(int $ref_id=null, array $question_ids=[])
URLBuilder.
Definition: URLBuilder.php:39
TabsManager $tabs_manager
parseDidacticTemplateVar(string $var, string $type)
ILIAS: ilPropertyFormGUI ILIAS: ilConfirmationGUI ILIAS: ilTestSettingsChangeConfirmationGUI ...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
addHeaderAction()
Add header action menu.
static clear(string $a_var)
forwardCommandToQuestion(string $cmd)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static set(string $a_var, $a_val)
Set a value.
showMediaFullscreen(int $a_style_id=0)
show fullscreen view of media object
static _getAvailableQuestionpools(bool $use_object_id=false, bool $equal_points=false, bool $could_be_offline=false, bool $showPath=false, bool $with_questioncount=false, string $permission='read', int $usr_id=0)
Returns the available question pools for the active user.
static getInstanceFromAjaxCall()
(Re-)Build instance from ajax call
addAdditionalCmd(string $label, string $cmd)
const SCORE_BEST_PASS
static _gotoRepositoryRoot(bool $raise_error=false)
Goto repository root.
ilComponentRepository $component_repository