ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.ilTestRandomQuestionSetConfigGUI.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
21use ILIAS\Data\Factory as DataFactory;
30use ILIAS\UI\Factory as UIFactory;
31use ILIAS\UI\Renderer as UIRenderer;
32
46{
47 public const CMD_SHOW_GENERAL_CONFIG_FORM = 'showGeneralConfigForm';
48 public const CMD_SAVE_GENERAL_CONFIG_FORM = 'saveGeneralConfigForm';
49 public const CMD_SHOW_SRC_POOL_DEF_LIST = 'showSourcePoolDefinitionList';
50 public const CMD_SAVE_SRC_POOL_DEF_LIST = 'saveSourcePoolDefinitionList';
51 public const CMD_DELETE_SRC_POOL_DEF = 'deleteSourcePoolDefinition';
52 public const CMD_SHOW_POOL_SELECTOR_EXPLORER = 'showPoolSelectorExplorer';
53 public const CMD_SHOW_CREATE_SRC_POOL_DEF_FORM = 'showCreateSourcePoolDefinitionForm';
54 public const CMD_SAVE_CREATE_SRC_POOL_DEF_FORM = 'saveCreateSourcePoolDefinitionForm';
55 public const CMD_SAVE_AND_NEW_CREATE_SRC_POOL_DEF_FORM = 'saveCreateAndNewSourcePoolDefinitionForm';
56 public const CMD_SHOW_EDIT_SRC_POOL_DEF_FORM = 'showEditSourcePoolDefinitionForm';
57 public const CMD_SAVE_EDIT_SRC_POOL_DEF_FORM = 'saveEditSourcePoolDefinitionForm';
58 public const CMD_BUILD_QUESTION_STAGE = 'buildQuestionStage';
59 public const CMD_SELECT_DERIVATION_TARGET = 'selectPoolDerivationTarget';
60 public const CMD_DERIVE_NEW_POOLS = 'deriveNewPools';
61 public const CMD_RESET_POOLSYNC = 'resetPoolSync';
62
63 public const HTTP_PARAM_AFTER_REBUILD_QUESTION_STAGE_CMD = 'afterRebuildQuestionStageCmd';
64
70
71 public function __construct(
72 private readonly ilObjTest $test_obj,
73 private readonly ilCtrl $ctrl,
74 private readonly ilObjUser $user,
75 private readonly ilAccessHandler $access,
76 private readonly UIFactory $ui_factory,
77 private readonly UIRenderer $ui_renderer,
78 private readonly DataFactory $data_factory,
79 private readonly TabsManager $tabs_manager,
80 private readonly ilLanguage $lng,
81 private readonly TestLogger $logger,
82 private readonly ilGlobalTemplateInterface $tpl,
83 private readonly ilDBInterface $db,
84 private readonly ilTree $tree,
85 private readonly ilComponentRepository $component_repository,
86 private readonly ilObjectDefinition $obj_definition,
87 private readonly ilObjectDataCache $obj_cache,
88 private ilTestProcessLockerFactory $processLockerFactory,
89 private readonly RequestDataCollector $testrequest,
90 private readonly TitleColumnsBuilder $title_builder,
91 private readonly GeneralQuestionPropertiesRepository $questionrepository
92 ) {
93 $this->question_set_config = new ilTestRandomQuestionSetConfig(
94 $this->tree,
95 $this->db,
96 $this->lng,
97 $this->logger,
98 $this->component_repository,
99 $this->test_obj,
100 $this->questionrepository
101 );
102 $this->question_set_config->loadFromDb();
103
104 $this->source_pool_definition_factory = new ilTestRandomQuestionSetSourcePoolDefinitionFactory(
105 $this->db,
106 $this->test_obj
107 );
108
109 $this->source_pool_definition_list = new ilTestRandomQuestionSetSourcePoolDefinitionList(
110 $this->db,
111 $this->test_obj,
112 $this->source_pool_definition_factory
113 );
114
115 $this->source_pool_definition_list->loadDefinitions();
116
117 $this->stagingPool = new ilTestRandomQuestionSetStagingPoolBuilder(
118 $this->db,
119 $this->logger,
120 $this->test_obj
121 );
122
123 $this->configStateMessageHandler = new ilTestRandomQuestionSetConfigStateMessageHandler(
124 $this->lng,
125 $this->ui_factory,
126 $this->ui_renderer,
127 $this->ctrl
128 );
129
130 $this->configStateMessageHandler->setTargetGUI($this);
131 $this->configStateMessageHandler->setQuestionSetConfig($this->question_set_config);
132 $this->configStateMessageHandler->setParticipantDataExists($this->test_obj->participantDataExist());
133 $this->configStateMessageHandler->setLostPools($this->source_pool_definition_list->getLostPools());
134 $this->processLockerFactory = $processLockerFactory;
135 }
136
137 public function executeCommand(): void
138 {
139 if (!$this->access->checkAccess("write", "", $this->test_obj->getRefId())) {
140 $this->tpl->setOnScreenMessage('failure', $this->lng->txt("cannot_edit_test"), true);
141 $this->ctrl->redirectByClass([ilRepositoryGUI::class, ilObjTestGUI::class, ilInfoScreenGUI::class]);
142 }
143
145 $this->tpl->setOnScreenMessage('failure', $this->lng->txt("tst_msg_cannot_modify_random_question_set_conf_due_to_part"), true);
146 $this->ctrl->redirect($this);
147 }
148
149 $this->tabs_manager->getQuestionsSubTabs();
150 $this->activateTabs();
151 $next_class = $this->ctrl->getNextClass();
152
153 switch ($next_class) {
154 case 'iltestrandomquestionsetpooldefinitionformgui':
155 $this->question_set_config->loadFromDb();
156 $pool_id = $this->fetchQuestionPoolIdParameter();
157 $source_pool_definition = $this->getSourcePoolDefinitionByAvailableQuestionPoolId($pool_id);
158 $available_taxonomy_ids = ilObjTaxonomy::getUsageOfObject($source_pool_definition->getPoolId());
160 $form->build($source_pool_definition, $available_taxonomy_ids);
161
162 $this->ctrl->forwardCommand($form);
163 break;
164
165 default:
166 $cmd = $this->ctrl->getCmd(self::CMD_SHOW_GENERAL_CONFIG_FORM) . 'Cmd';
167 $this->$cmd();
168 }
169 }
170
171 private function isAvoidManipulationRedirectRequired(): bool
172 {
173 if (!$this->isFrozenConfigRequired()) {
174 return false;
175 }
176
177 if (!$this->isManipulationCommand()) {
178 return false;
179 }
180
181 return true;
182 }
183
184 private function isFrozenConfigRequired(): bool
185 {
186 if ($this->test_obj->participantDataExist()) {
187 return true;
188 }
189
190 if ($this->source_pool_definition_list->hasLostPool()) {
191 return true;
192 }
193
194 return false;
195 }
196
197 private function isManipulationCommand(): bool
198 {
199 if (in_array(
200 $this->ctrl->getCmd(self::CMD_SHOW_GENERAL_CONFIG_FORM),
201 [
202 self::CMD_SAVE_GENERAL_CONFIG_FORM,
203 self::CMD_SAVE_SRC_POOL_DEF_LIST,
204 self::CMD_DELETE_SRC_POOL_DEF,
205 self::CMD_SAVE_CREATE_SRC_POOL_DEF_FORM,
206 self::CMD_SAVE_EDIT_SRC_POOL_DEF_FORM,
207 self::CMD_SAVE_AND_NEW_CREATE_SRC_POOL_DEF_FORM,
208 self::CMD_BUILD_QUESTION_STAGE
209 ]
210 )) {
211 return true;
212 }
213
214 return false;
215 }
216
217 private function activateTabs(): void
218 {
219 $this->tabs_manager->activateTab('assQuestions');
220
221 switch ($this->ctrl->getCmd(self::CMD_SHOW_GENERAL_CONFIG_FORM)) {
224 $this->tabs_manager->activateSubTab('tstRandQuestSetGeneralConfig');
225 break;
226
234 $this->tabs_manager->activateSubTab('tstRandQuestSetPoolConfig');
235 break;
236 }
237 }
238
239 private function buildQuestionStageCmd(): void
240 {
241 if ($this->source_pool_definition_list->areAllUsedPoolsAvailable()) {
242 $locker = $this->processLockerFactory->retrieveLockerForNamedOperation();
243 $locker->executeNamedOperation(__FUNCTION__, function (): void {
244 $this->stagingPool->rebuild($this->source_pool_definition_list);
245 $this->source_pool_definition_list->saveDefinitions();
246
247 $this->question_set_config->loadFromDb();
248 $this->question_set_config->setLastQuestionSyncTimestamp(time());
249 $this->question_set_config->saveToDb();
250
251 $this->test_obj->saveCompleteStatus($this->question_set_config);
252
253 $this->ctrl->setParameterByClass(self::class, 'modified', 'sync');
254 });
255 if ($this->logger->isLoggingEnabled()) {
256 $this->logger->logTestAdministrationInteraction(
257 $this->logger->getInteractionFactory()->buildTestAdministrationInteraction(
258 $this->test_obj->getRefId(),
259 $this->user->getId(),
260 TestAdministrationInteractionTypes::QUESTIONS_SYNCHRONISED,
261 []
262 )
263 );
264 }
265 }
266
267 $this->ctrl->redirect($this, $this->fetchAfterRebuildQuestionStageCmdParameter());
268 }
269
271 {
272 if (!$this->testrequest->isset(self::HTTP_PARAM_AFTER_REBUILD_QUESTION_STAGE_CMD)) {
274 }
275
276 if (!strlen($this->testrequest->raw(self::HTTP_PARAM_AFTER_REBUILD_QUESTION_STAGE_CMD))) {
278 }
279
280 return $this->testrequest->raw(self::HTTP_PARAM_AFTER_REBUILD_QUESTION_STAGE_CMD);
281 }
282
284 {
285 $disabled_form = $this->preventFormBecauseOfSync();
286
287 if ($form === null) {
288 $this->question_set_config->loadFromDb();
289 $form = $this->buildGeneralConfigFormGUI($disabled_form);
290 }
291
292 $this->tpl->setContent($this->ctrl->getHTML($form));
293
294 $this->configStateMessageHandler->setContext(
296 );
297
298 $this->configStateMessageHandler->handle();
299
301 if ($message !== '') {
303 }
304 }
305
306 private function saveGeneralConfigFormCmd(): void
307 {
308 $form = $this->buildGeneralConfigFormGUI();
309
310 $errors = !$form->checkInput(); // ALWAYS CALL BEFORE setValuesByPost()
311 $form->setValuesByPost(); // NEVER CALL THIS BEFORE checkInput()
312
313 if ($errors) {
314 $this->showGeneralConfigFormCmd($form);
315 return;
316 }
317
318 $log_array = $form->save($this->logger->getAdditionalInformationGenerator());
319
320 $this->question_set_config->setLastQuestionSyncTimestamp(0);
321 $this->question_set_config->saveToDb();
322
323 if ($this->logger->isLoggingEnabled()) {
324 $this->logger->logTestAdministrationInteraction(
325 $this->logger->getInteractionFactory()->buildTestAdministrationInteraction(
326 $this->test_obj->getRefId(),
327 $this->user->getId(),
328 TestAdministrationInteractionTypes::QUESTION_SELECTION_CRITERIA_MODIFIED,
329 $log_array
330 )
331 );
332 }
333
334 $this->test_obj->saveCompleteStatus($this->question_set_config);
335
336 $this->ctrl->setParameter($this, 'modified', 'save');
337 $this->ctrl->redirect($this, self::CMD_SHOW_GENERAL_CONFIG_FORM);
338 }
339
340
342 {
344 $this,
345 $this->question_set_config
346 );
347
348 //TODO: should frozen config not lead to 'completely disabled' as well?!
349 $form->setEditModeEnabled(!$this->isFrozenConfigRequired());
350
351 if ($disabled) {
352 $form->setEditModeEnabled(false);
353 }
354
355 $form->build();
356
357 if ($disabled) {
358 $form->clearCommandButtons();
359 }
360
361 return $form;
362 }
363
364 private function showSourcePoolDefinitionListCmd(): void
365 {
366 $disabled_form = $this->preventFormBecauseOfSync();
367
368 $this->question_set_config->loadFromDb();
369
370 $content = '';
371
372 if (!$this->isFrozenConfigRequired() && !$disabled_form) {
373 $toolbar = $this->buildSourcePoolDefinitionListToolbarGUI();
374 $content .= $this->ctrl->getHTML($toolbar);
375 }
376
377 $table = $this->buildSourcePoolDefinitionListTableGUI($disabled_form);
378 $content .= $this->ui_renderer->render($table->getComponent());
379
380 if (!$this->source_pool_definition_list->areAllUsedPoolsAvailable()) {
382 $this->ctrl,
383 $this->lng,
384 $this->ui_factory,
385 $this->data_factory,
386 $this->testrequest->getRequest(),
387 $this->source_pool_definition_list
388 );
389 $content .= $this->ui_renderer->render($table->getComponent());
390 }
391
392 $this->tpl->setContent($content);
393
394 $this->configStateMessageHandler->setContext(
396 );
397
398 $this->configStateMessageHandler->handle();
399
401 if ($message) {
403 }
404 }
405
406 private function saveSourcePoolDefinitionListCmd(): void
407 {
408 $this->question_set_config->loadFromDb();
409
411 $table->applySubmit($this->testrequest);
412
413 $this->source_pool_definition_list->reindexPositions();
414 $this->source_pool_definition_list->saveDefinitions();
415
416 $this->question_set_config->setLastQuestionSyncTimestamp(0);
417 $this->question_set_config->saveToDb();
418
419 $this->test_obj->saveCompleteStatus($this->question_set_config);
420
421 $this->ctrl->setParameter($this, 'modified', 'save');
422 $this->ctrl->redirect($this, self::CMD_SHOW_SRC_POOL_DEF_LIST);
423 }
424
426 {
428 $this->ctrl,
429 $this->lng,
430 $this,
431 $this->question_set_config
432 );
433
434 $toolbar->build();
435
436 return $toolbar;
437 }
438
440 {
441 $translator = new ilTestQuestionFilterLabelTranslator($this->db, $this->lng);
442 $translator->loadLabels($this->source_pool_definition_list);
443
445 $this->ctrl,
446 $this->lng,
447 $this->ui_factory,
448 $this->data_factory,
449 $this->testrequest->getRequest(),
450 $this->title_builder,
451 $translator,
452 $this->source_pool_definition_list,
453 !$this->isFrozenConfigRequired() && !$disabled,
454 $this->question_set_config->isQuestionAmountConfigurationModePerPool()
455 );
456 }
457
458 private function deleteSourcePoolDefinitionCmd(): void
459 {
460 $definition_ids = $this->fetchMultiSourcePoolDefinitionIdsParameter();
461 foreach ($definition_ids as $definition_id) {
462 $definition = $this->source_pool_definition_factory->getSourcePoolDefinitionByDefinitionId($definition_id);
463 $definition->deleteFromDb();
464 }
465
466 $this->source_pool_definition_list->reindexPositions();
467 $this->source_pool_definition_list->saveDefinitions();
468
469 $this->question_set_config->loadFromDb();
470 $this->question_set_config->setLastQuestionSyncTimestamp(0);
471 $this->question_set_config->saveToDb();
472
473 $this->test_obj->saveCompleteStatus($this->question_set_config);
474
475 $this->ctrl->setParameterByClass(self::class, 'modified', 'remove');
476 $this->ctrl->redirect($this, self::CMD_SHOW_SRC_POOL_DEF_LIST);
477 }
478
479 protected function showPoolSelectorExplorerCmd(): void
480 {
481 $this->question_set_config->loadFromDb();
482
484 $this,
485 self::CMD_SHOW_POOL_SELECTOR_EXPLORER,
486 self::CMD_SHOW_CREATE_SRC_POOL_DEF_FORM,
487 $this->obj_cache
488 );
489
490 $selector->setAvailableQuestionPools(
491 array_keys($this->question_set_config->getSelectableQuestionPools())
492 );
493
494 if ($selector->handleCommand()) {
495 return;
496 }
497
498 $this->tpl->setContent($selector->getHTML(true));
499 }
500
502 {
503 $this->question_set_config->loadFromDb();
504
505 $pool_id = $this->fetchQuestionPoolIdParameter();
506
507 $source_pool_definition = $this->getSourcePoolDefinitionByAvailableQuestionPoolId($pool_id);
508 $available_taxonomy_ids = ilObjTaxonomy::getUsageOfObject($source_pool_definition->getPoolId());
509
510 if ($form === null) {
512 $form->build($source_pool_definition, $available_taxonomy_ids);
513 }
514
515 $this->tpl->setContent($this->ctrl->getHTML($form));
516 }
517
519 {
521 }
522
526 private function saveCreateSourcePoolDefinitionFormCmd($redirect_back_to_form = false): void
527 {
528 $this->question_set_config->loadFromDb();
529
530 $pool_id = $this->fetchQuestionPoolIdParameter();
531 $source_pool_definition = $this->getSourcePoolDefinitionByAvailableQuestionPoolId($pool_id);
532 $available_taxonomy_ids = ilObjTaxonomy::getUsageOfObject($source_pool_definition->getPoolId());
533
535 $form->build($source_pool_definition, $available_taxonomy_ids);
536
537 $errors = !$form->checkInput(); // ALWAYS CALL BEFORE setValuesByPost()
538 $form->setValuesByPost(); // NEVER CALL THIS BEFORE checkInput()
539
540 if ($errors) {
542 return;
543 }
544
545 $log_array = $form->applySubmit($source_pool_definition, $available_taxonomy_ids);
546
547 $source_pool_definition->setSequencePosition($this->source_pool_definition_list->getNextPosition());
548 $source_pool_definition->saveToDb();
549 $this->source_pool_definition_list->addDefinition($source_pool_definition);
550
551 $this->source_pool_definition_list->saveDefinitions();
552
553 $this->question_set_config->setLastQuestionSyncTimestamp(0);
554 $this->question_set_config->saveToDb();
555
556 $this->test_obj->saveCompleteStatus($this->question_set_config);
557
558 if ($this->logger->isLoggingEnabled()) {
559 $this->logger->logTestAdministrationInteraction(
560 $this->logger->getInteractionFactory()->buildTestAdministrationInteraction(
561 $this->test_obj->getRefId(),
562 $this->user->getId(),
563 TestAdministrationInteractionTypes::QUESTION_SELECTION_CRITERIA_MODIFIED,
564 $log_array
565 )
566 );
567 }
568
569 if ($redirect_back_to_form) {
570 $this->tpl->setOnScreenMessage('success', $this->lng->txt("tst_msg_random_qsc_modified_add_new_rule"), true);
571 $this->ctrl->setParameter($this, 'src_pool_def_id', $source_pool_definition->getId());
572 $this->ctrl->setParameter($this, 'quest_pool_id', $source_pool_definition->getPoolId());
573 $this->ctrl->redirect($this, self::CMD_SHOW_CREATE_SRC_POOL_DEF_FORM);
574 return;
575 }
576
577 $this->ctrl->setParameterByClass(self::class, 'modified', 'save');
578 $this->ctrl->redirect($this, self::CMD_SHOW_SRC_POOL_DEF_LIST);
579 }
580
582 {
584 $this->ctrl,
585 $this->lng,
586 $this->test_obj,
587 $this,
588 $this->question_set_config
589 );
590
591 $form->setSaveCommand(self::CMD_SAVE_CREATE_SRC_POOL_DEF_FORM);
592 $form->setSaveAndNewCommand(self::CMD_SAVE_AND_NEW_CREATE_SRC_POOL_DEF_FORM);
593
594 return $form;
595 }
596
598 {
599 $this->question_set_config->loadFromDb();
600
602 $source_pool_definition = $this->source_pool_definition_factory->getSourcePoolDefinitionByDefinitionId($defId);
603 $available_taxonomy_ids = ilObjTaxonomy::getUsageOfObject($source_pool_definition->getPoolId());
604
605 if ($form === null) {
607 $form->build($source_pool_definition, $available_taxonomy_ids);
608 }
609
610 $this->tpl->setContent($this->ctrl->getHTML($form));
611 }
612
613 private function saveEditSourcePoolDefinitionFormCmd(): void
614 {
615 $this->question_set_config->loadFromDb();
616
618 $source_pool_definition = $this->source_pool_definition_factory->getSourcePoolDefinitionByDefinitionId($defId);
619 $available_taxonomy_ids = ilObjTaxonomy::getUsageOfObject($source_pool_definition->getPoolId());
620
622 $form->build($source_pool_definition, $available_taxonomy_ids);
623
624 $errors = !$form->checkInput(); // ALWAYS CALL BEFORE setValuesByPost()
625 $form->setValuesByPost(); // NEVER CALL THIS BEFORE checkInput()
626
627 if ($errors) {
629 return;
630 }
631
632 $log_array = $form->applySubmit($source_pool_definition, $available_taxonomy_ids);
633
634 $source_pool_definition->saveToDb();
635
636 $this->question_set_config->setLastQuestionSyncTimestamp(0);
637 $this->question_set_config->saveToDb();
638
639 $this->test_obj->saveCompleteStatus($this->question_set_config);
640
641 if ($this->logger->isLoggingEnabled()) {
642 $this->logger->logTestAdministrationInteraction(
643 $this->logger->getInteractionFactory()->buildTestAdministrationInteraction(
644 $this->test_obj->getRefId(),
645 $this->user->getId(),
646 TestAdministrationInteractionTypes::QUESTIONS_SYNCHRONISATION_RESET,
647 $log_array
648 )
649 );
650 }
651
652 $this->ctrl->setParameterByClass(self::class, 'modified', 'save');
653 $this->ctrl->redirect($this, self::CMD_SHOW_SRC_POOL_DEF_LIST);
654 }
655
657 {
659 $this->ctrl,
660 $this->lng,
661 $this->test_obj,
662 $this,
663 $this->question_set_config
664 );
665
666 $form->setSaveCommand(self::CMD_SAVE_EDIT_SRC_POOL_DEF_FORM);
667
668 return $form;
669 }
670
672 {
673 if ($this->testrequest->isset('quest_pool_id') && (int) $this->testrequest->raw('quest_pool_id')) {
674 return (int) $this->testrequest->raw('quest_pool_id');
675 }
676
677 if ($this->testrequest->isset('quest_pool_ref') && (int) $this->testrequest->raw('quest_pool_ref')) {
678 return $this->obj_cache->lookupObjId((int) $this->testrequest->raw('quest_pool_ref'));
679 }
680
682 }
683
685 {
686 if (!$this->testrequest->isset('src_pool_def_id')) {
687 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('tst_please_select_source_pool'), true);
688 $this->ctrl->redirect($this, self::CMD_SHOW_SRC_POOL_DEF_LIST);
689 return [];
690 }
691
692 $definition_ids = is_array($this->testrequest->raw('src_pool_def_id'))
693 ? array_map('intval', $this->testrequest->raw('src_pool_def_id'))
694 : [(int) $this->testrequest->raw('src_pool_def_id')];
695
696 foreach ($definition_ids as $definition_id) {
697 if ($definition_id === 0) {
699 }
700 }
701 return $definition_ids;
702 }
703
705 {
706 //even a single id can be an array (set by table actions) or a single value (set by form actions)
707 $definition_ids = $this->fetchMultiSourcePoolDefinitionIdsParameter();
708 if (count($definition_ids) !== 1) {
710 }
711 return $definition_ids[0];
712 }
713
715 {
716 $availablePools = $this->test_obj->getAvailableQuestionpools(
717 true,
718 $this->question_set_config->arePoolsWithHomogeneousScoredQuestionsRequired(),
719 false,
720 true,
721 true
722 );
723
724 if (isset($availablePools[$pool_id])) {
725 $originalPoolData = $availablePools[$pool_id];
726
727 $originalPoolData['qpl_path'] = $this->question_set_config->getQuestionPoolPathString($pool_id);
728 $originalPoolData['qpl_ref_id'] = $this->question_set_config->getFirstQuestionPoolRefIdByObjId($pool_id);
729
730 return $this->source_pool_definition_factory->getSourcePoolDefinitionByOriginalPoolData($originalPoolData);
731 }
732
734 }
735
739 protected function fetchPoolIdsParameter(): array
740 {
741 $pool_ids = [];
742 if ($this->testrequest->isset('derive_pool_ids') && is_array($this->testrequest->raw('derive_pool_ids'))) {
743 $pool_ids = [];
744
745 foreach ($this->testrequest->raw('derive_pool_ids') as $pool_id) {
746 $pool_ids[] = (int) $pool_id;
747 }
748 } elseif ($this->testrequest->isset('derive_pool_ids') && preg_match('/^\d+(\:\d+)*$/', $this->testrequest->raw('derive_pool_ids'))) {
749 $pool_ids = array_map(
750 fn(int $id) => (int) $id,
751 explode(':', $this->testrequest->raw('derive_pool_ids'))
752 );
753 } elseif ($this->testrequest->isset('derive_pool_id') && (int) $this->testrequest->raw('derive_pool_id')) {
754 $pool_ids = [(int) $this->testrequest->raw('derive_pool_id')];
755 }
756
757 return $pool_ids;
758 }
759
760 protected function fetchTargetRefParameter(): ?int
761 {
762 if ($this->testrequest->isset('target_ref') && (int) $this->testrequest->raw('target_ref')) {
763 return (int) $this->testrequest->raw('target_ref');
764 }
765 return null;
766 }
767
768 private function selectPoolDerivationTargetCmd(): void
769 {
770 $this->ctrl->setParameter($this, 'derive_pool_ids', implode(':', $this->fetchPoolIdsParameter()));
771
772 $explorer = new ilRepositorySelectorExplorerGUI(
773 $this,
774 self::CMD_SELECT_DERIVATION_TARGET,
775 $this,
776 self::CMD_DERIVE_NEW_POOLS,
777 'target_ref'
778 );
779 $explorer->setClickableTypes($this->obj_definition->getExplorerContainerTypes());
780 $explorer->setSelectableTypes([]);
781
782 if (!$explorer->handleCommand()) {
783 $this->tpl->setOnScreenMessage('info', $this->lng->txt('tst_please_select_target_for_pool_derives'));
784 $this->tpl->setContent($this->ctrl->getHTML($explorer));
785 }
786 }
787
788 private function deriveNewPoolsCmd(): void
789 {
790 $pool_ids = $this->fetchPoolIdsParameter();
791 $target_ref = $this->fetchTargetRefParameter();
792 if (!$this->access->checkAccess('write', '', $target_ref)) {
793 $this->tpl->setOnScreenMessage('failure', $this->lng->txt("no_permission"), true);
794 $this->ctrl->setParameterByClass(ilObjTestGUI::class, 'ref_id', $this->test_obj->getRefId());
795 $this->ctrl->redirectByClass(ilObjTestGUI::class);
796 }
797
798 if ($pool_ids !== []) {
799 foreach ($pool_ids as $pool_id) {
800 $lost_pool = $this->source_pool_definition_list->getLostPool($pool_id);
801
803 $this->db,
804 $this->component_repository,
805 $this->test_obj,
806 $this->source_pool_definition_list,
807 $this->user->getId(),
808 $target_ref
809 );
810 $new_pool = $deriver->derive($lost_pool);
811
812 $srcPoolDefinition = $this->source_pool_definition_list->getDefinitionBySourcePoolId($new_pool->getId());
813 $srcPoolDefinition->setPoolTitle($new_pool->getTitle());
814 $srcPoolDefinition->setPoolPath($this->question_set_config->getQuestionPoolPathString($new_pool->getId()));
815 $srcPoolDefinition->setPoolRefId($this->question_set_config->getFirstQuestionPoolRefIdByObjId($new_pool->getId()));
816 $srcPoolDefinition->saveToDb();
817
819 $this->test_obj->getTestId(),
820 $lost_pool->getId(),
821 $new_pool->getId()
822 );
823 }
824
825 $this->tpl->setOnScreenMessage('success', $this->lng->txt('tst_non_available_pool_newly_derived'), true);
826 }
827
828 $this->ctrl->redirect($this, self::CMD_SHOW_SRC_POOL_DEF_LIST);
829 }
830
831 protected function preventFormBecauseOfSync(): bool
832 {
833 $return = false;
834 $last_sync = $this->question_set_config->getLastQuestionSyncTimestamp();
835
836 if ($last_sync !== null && $last_sync !== 0 &&
837 !$this->isFrozenConfigRequired() && $this->question_set_config->isQuestionSetBuildable()) {
838 return true;
839 }
840 return false;
841 }
842
843 public function resetPoolSyncCmd(): void
844 {
845 $this->question_set_config->setLastQuestionSyncTimestamp(0);
846 $this->question_set_config->saveToDb();
847 if ($this->logger->isLoggingEnabled()) {
848 $this->logger->logTestAdministrationInteraction(
849 $this->logger->getInteractionFactory()->buildTestAdministrationInteraction(
850 $this->test_obj->getRefId(),
851 $this->user->getId(),
852 TestAdministrationInteractionTypes::QUESTIONS_SYNCHRONISATION_RESET,
853 []
854 )
855 );
856 }
857 $this->ctrl->redirect($this, self::CMD_SHOW_GENERAL_CONFIG_FORM);
858 }
859
860 protected function buildOnScreenMessage(): string
861 {
864
865 return $message;
866 }
867
868 protected function buildFormResultMessage(): string
869 {
870 $message = '';
871
872 if ($this->testrequest->isset('modified')) {
873 $action = $this->testrequest->raw('modified');
874 if ($action === 'save') {
875 $success_message = $this->ui_factory->messageBox()->success($this->lng->txt('tst_msg_random_question_set_config_modified'));
876 } elseif ($action === 'remove') {
877 $success_message = $this->ui_factory->messageBox()->success($this->lng->txt('tst_msg_source_pool_definitions_deleted'));
878 } elseif ($action === 'sync') {
879 $success_message = $this->ui_factory->messageBox()->success($this->lng->txt('tst_msg_random_question_set_synced'));
880 }
881 $message .= $this->ui_renderer->render(
882 $success_message
883 );
884 }
885
886 return $message;
887 }
888
889 protected function buildValidationMessage(): string
890 {
891 if ($this->configStateMessageHandler->isValidationFailed()) {
892 return $this->ui_renderer->render(
893 $this->ui_factory->messageBox()->failure($this->configStateMessageHandler->getValidationReportHtml())
894 );
895 }
896
897 if ($this->configStateMessageHandler->hasValidationReports()) {
898 return $this->ui_renderer->render(
899 $this->ui_factory->messageBox()->info($this->configStateMessageHandler->getValidationReportHtml())
900 );
901 }
902
903 return $this->configStateMessageHandler->getSyncInfoMessage();
904 }
905
910 {
911 $this->tpl->setCurrentBlock('mess');
912 $this->tpl->setVariable('MESSAGE', $message);
913 $this->tpl->parseCurrentBlock();
914 }
915}
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
Builds a Color from either hex- or rgb values.
Definition: Factory.php:31
Builds data types.
Definition: Factory.php:36
Class ilCtrl provides processing control methods.
language handling
static getUsageOfObject(int $a_obj_id, bool $a_include_titles=false)
User class.
class ilObjectDataCache
parses the objects.xml it handles the xml-description of all ilias objects
Explorer for selecting repository items.
ilTestRandomQuestionSetStagingPoolBuilder $stagingPool
ilTestRandomQuestionSetSourcePoolDefinitionFactory $source_pool_definition_factory
showGeneralConfigFormCmd(?ilTestRandomQuestionSetGeneralConfigFormGUI $form=null)
saveCreateSourcePoolDefinitionFormCmd($redirect_back_to_form=false)
ilTestRandomQuestionSetSourcePoolDefinitionList $source_pool_definition_list
showCreateSourcePoolDefinitionFormCmd(?ilTestRandomQuestionSetPoolDefinitionFormGUI $form=null)
showEditSourcePoolDefinitionFormCmd(?ilTestRandomQuestionSetPoolDefinitionFormGUI $form=null)
ilTestRandomQuestionSetConfigStateMessageHandler $configStateMessageHandler
__construct(private readonly ilObjTest $test_obj, private readonly ilCtrl $ctrl, private readonly ilObjUser $user, private readonly ilAccessHandler $access, private readonly UIFactory $ui_factory, private readonly UIRenderer $ui_renderer, private readonly DataFactory $data_factory, private readonly TabsManager $tabs_manager, private readonly ilLanguage $lng, private readonly TestLogger $logger, private readonly ilGlobalTemplateInterface $tpl, private readonly ilDBInterface $db, private readonly ilTree $tree, private readonly ilComponentRepository $component_repository, private readonly ilObjectDefinition $obj_definition, private readonly ilObjectDataCache $obj_cache, private ilTestProcessLockerFactory $processLockerFactory, private readonly RequestDataCollector $testrequest, private readonly TitleColumnsBuilder $title_builder, private readonly GeneralQuestionPropertiesRepository $questionrepository)
Tree class data representation in hierachical trees using the Nested Set Model with Gaps by Joe Celco...
An entity that renders components to a string output.
Definition: Renderer.php:31
Interface ilAccessHandler This interface combines all available interfaces which can be called via gl...
Readable part of repository interface to ilComponentDataDB.
Interface ilDBInterface.
global $lng
Definition: privfeed.php:31
$message
Definition: xapiexit.php:31