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