From b77a497d65e4de38f3d627d474f99a3d1806af4e Mon Sep 17 00:00:00 2001 From: Nils Haagen Date: Mon, 28 Mar 2022 16:41:05 +0200 Subject: [PATCH] TA 26290, block forms if pool-sync is currently in place --- .../class.ilTestRandomQuestionSetConfig.php | 27 +--- ...class.ilTestRandomQuestionSetConfigGUI.php | 138 +++++++++++++----- lang/ilias_de.lang | 1 + lang/ilias_en.lang | 1 + 4 files changed, 111 insertions(+), 56 deletions(-) diff --git a/Modules/Test/classes/class.ilTestRandomQuestionSetConfig.php b/Modules/Test/classes/class.ilTestRandomQuestionSetConfig.php index 9d1a45139a61..6b380da0336b 100644 --- a/Modules/Test/classes/class.ilTestRandomQuestionSetConfig.php +++ b/Modules/Test/classes/class.ilTestRandomQuestionSetConfig.php @@ -290,27 +290,14 @@ private function insertDbRecord($testId) // ----------------------------------------------------------------------------------------------------------------- - public function isQuestionSetConfigured() + public function isQuestionSetConfigured() : bool { - // fau: delayCopyRandomQuestions - question set is not configured if date of last synchronisation is empty - if ($this->getLastQuestionSyncTimestamp() == 0) { - return false; - } - // fau. - - if (!$this->isQuestionAmountConfigComplete()) { - return false; - } - - if (!$this->hasSourcePoolDefinitions()) { - return false; - } - - if (!$this->isQuestionSetBuildable()) { - return false; - } - - return true; + return ( + $this->getLastQuestionSyncTimestamp() != 0 + && $this->isQuestionAmountConfigComplete() + && $this->hasSourcePoolDefinitions() + && $this->isQuestionSetBuildable() + ); } public function isQuestionAmountConfigComplete() diff --git a/Modules/Test/classes/class.ilTestRandomQuestionSetConfigGUI.php b/Modules/Test/classes/class.ilTestRandomQuestionSetConfigGUI.php index 11814687398d..6c80607fd398 100644 --- a/Modules/Test/classes/class.ilTestRandomQuestionSetConfigGUI.php +++ b/Modules/Test/classes/class.ilTestRandomQuestionSetConfigGUI.php @@ -41,6 +41,7 @@ class ilTestRandomQuestionSetConfigGUI const CMD_BUILD_QUESTION_STAGE = 'buildQuestionStage'; const CMD_SELECT_DERIVATION_TARGET = 'selectPoolDerivationTarget'; const CMD_DERIVE_NEW_POOLS = 'deriveNewPools'; + const CMD_RESET_POOLSYNC = 'resetPoolSync'; const HTTP_PARAM_AFTER_REBUILD_QUESTION_STAGE_CMD = 'afterRebuildQuestionStageCmd'; /** @@ -122,6 +123,11 @@ class ilTestRandomQuestionSetConfigGUI */ private $processLockerFactory; + /** + * @var ArrayAccess + */ + protected $dic; + public function __construct( ilCtrl $ctrl, ilAccessHandler $access, @@ -142,8 +148,11 @@ public function __construct( $this->db = $db; $this->tree = $tree; $this->pluginAdmin = $pluginAdmin; - $this->objDefinition = $GLOBALS['DIC']['objDefinition']; $this->testOBJ = $testOBJ; + + global $DIC; + $this->dic = $DIC; + $this->objDefinition = $this->dic['objDefinition']; $this->questionSetConfig = new ilTestRandomQuestionSetConfig( $this->tree, @@ -151,6 +160,7 @@ public function __construct( $this->pluginAdmin, $this->testOBJ ); + $this->questionSetConfig->loadFromDb(); $this->sourcePoolDefinitionFactory = new ilTestRandomQuestionSetSourcePoolDefinitionFactory( $this->db, @@ -305,7 +315,7 @@ private function buildQuestionStageCmd() : void { if ($this->sourcePoolDefinitionList->areAllUsedPoolsAvailable()) { $locker = $this->processLockerFactory->retrieveLockerForNamedOperation(); - $locker->executeNamedOperation(__FUNCTION__, function() : void { + $locker->executeNamedOperation(__FUNCTION__, function () : void { $this->stagingPool->rebuild($this->sourcePoolDefinitionList); $this->sourcePoolDefinitionList->saveDefinitions(); @@ -337,38 +347,40 @@ private function fetchAfterRebuildQuestionStageCmdParameter() private function showGeneralConfigFormCmd(ilTestRandomQuestionSetGeneralConfigFormGUI $form = null) { + $disabled_form = $this->preventFormBecauseOfSync(); + if ($form === null) { $this->questionSetConfig->loadFromDb(); - $form = $this->buildGeneralConfigFormGUI(); + $form = $this->buildGeneralConfigFormGUI($disabled_form); } - + $this->tpl->setContent($this->ctrl->getHTML($form)); - $this->configStateMessageHandler->setContext( - ilTestRandomQuestionSetConfigStateMessageHandler::CONTEXT_GENERAL_CONFIG - ); - - $this->configStateMessageHandler->handle(); - - if ($this->configStateMessageHandler->hasValidationReports()) { - if ($this->configStateMessageHandler->isValidationFailed()) { - ilUtil::sendFailure( - $this->configStateMessageHandler->getValidationReportHtml() - ); - } else { - ilUtil::sendInfo($this->configStateMessageHandler->getValidationReportHtml()); + if (!$disabled_form) { + $this->configStateMessageHandler->setContext( + ilTestRandomQuestionSetConfigStateMessageHandler::CONTEXT_GENERAL_CONFIG + ); + + $this->configStateMessageHandler->handle(); + + if ($this->configStateMessageHandler->hasValidationReports()) { + if ($this->configStateMessageHandler->isValidationFailed()) { + ilUtil::sendFailure( + $this->configStateMessageHandler->getValidationReportHtml() + ); + } else { + ilUtil::sendInfo($this->configStateMessageHandler->getValidationReportHtml()); + } + } + + if (isset($_GET['modified']) && (int) $_GET['modified']) { + ilUtil::sendSuccess($this->getGeneralModificationSuccessMessage()); } - } - - if (isset($_GET['modified']) && (int) $_GET['modified']) { - ilUtil::sendSuccess($this->getGeneralModificationSuccessMessage()); } } private function saveGeneralConfigFormCmd() { - $this->questionSetConfig->loadFromDb(); - $form = $this->buildGeneralConfigFormGUI(); $errors = !$form->checkInput(); // ALWAYS CALL BEFORE setValuesByPost() @@ -389,7 +401,7 @@ private function saveGeneralConfigFormCmd() $this->ctrl->redirect($this, self::CMD_SHOW_GENERAL_CONFIG_FORM); } - private function buildGeneralConfigFormGUI() + private function buildGeneralConfigFormGUI(bool $disabled = false) : ilTestRandomQuestionSetGeneralConfigFormGUI { require_once 'Modules/Test/classes/forms/class.ilTestRandomQuestionSetGeneralConfigFormGUI.php'; @@ -401,9 +413,18 @@ private function buildGeneralConfigFormGUI() $this->questionSetConfig ); + //TODO: should frozen config not lead to 'completely disabled' as well?! $form->setEditModeEnabled(!$this->isFrozenConfigRequired()); - + + if ($disabled) { + $form->setEditModeEnabled(false); + } + $form->build(); + + if ($disabled) { + $form->clearCommandButtons(); + } return $form; } @@ -412,25 +433,31 @@ private function showSourcePoolDefinitionListCmd() { $this->questionSetConfig->loadFromDb(); + $disabled_form = $this->preventFormBecauseOfSync(); + $content = ''; - if (!$this->isFrozenConfigRequired()) { + if (!$this->isFrozenConfigRequired() && !$disabled_form) { $toolbar = $this->buildSourcePoolDefinitionListToolbarGUI(); $content .= $this->ctrl->getHTML($toolbar); } - $table = $this->buildSourcePoolDefinitionListTableGUI(); + $table = $this->buildSourcePoolDefinitionListTableGUI($disabled_form); $table->init($this->sourcePoolDefinitionList); $content .= $this->ctrl->getHTML($table); - - if (!$this->sourcePoolDefinitionList->areAllUsedPoolsAvailable()) { + + if ($this->sourcePoolDefinitionList->areAllUsedPoolsAvailable()) { $table = $this->buildNonAvailablePoolsTableGUI(); $table->init($this->sourcePoolDefinitionList); $content .= $this->ctrl->getHTML($table); } - + $this->tpl->setContent($content); + if ($disabled_form) { + return; + } + $this->configStateMessageHandler->setContext( ilTestRandomQuestionSetConfigStateMessageHandler::CONTEXT_POOL_SELECTION ); @@ -493,7 +520,7 @@ private function buildSourcePoolDefinitionListToolbarGUI() return $toolbar; } - private function buildSourcePoolDefinitionListTableGUI() + private function buildSourcePoolDefinitionListTableGUI(bool $disabled = false) : ilTestRandomQuestionSetSourcePoolDefinitionListTableGUI { require_once 'Modules/Test/classes/tables/class.ilTestRandomQuestionSetSourcePoolDefinitionListTableGUI.php'; @@ -523,6 +550,9 @@ private function buildSourcePoolDefinitionListTableGUI() $translater->loadLabels($this->sourcePoolDefinitionList); $table->setTaxonomyFilterLabelTranslater($translater); + if ($disabled) { + $table->setDefinitionEditModeEnabled(false); + } $table->build(); return $table; @@ -763,10 +793,7 @@ private function fetchQuestionPoolIdParameter() } if (isset($_GET['quest_pool_ref']) && (int) $_GET['quest_pool_ref']) { - global $DIC; /* @var ILIAS\DI\Container $DIC */ - /* @var ilObjectDataCache $objCache */ - $objCache = $DIC['ilObjDataCache']; - + $objCache = $this->dic['ilObjDataCache']; return $objCache->lookupObjId((int) $_GET['quest_pool_ref']); } @@ -895,7 +922,7 @@ private function deriveNewPoolsCmd() $deriver = new ilTestRandomQuestionSetPoolDeriver($this->db, $this->pluginAdmin, $this->testOBJ); $deriver->setSourcePoolDefinitionList($this->sourcePoolDefinitionList); $deriver->setTargetContainerRef($targetRef); - $deriver->setOwnerId($GLOBALS['DIC']['ilUser']->getId()); + $deriver->setOwnerId($this->dic['ilUser']->getId()); $newPool = $deriver->derive($lostPool); $srcPoolDefinition = $this->sourcePoolDefinitionList->getDefinitionBySourcePoolId($newPool->getId()); @@ -940,4 +967,43 @@ public function getPoolConfigTabLabel() { return $this->lng->txt('tst_rnd_quest_cfg_tab_pool'); } + + + protected function preventFormBecauseOfSync() : bool + { + $return = false; + $last_sync = $this->questionSetConfig->getLastQuestionSyncTimestamp(); + if ($last_sync != 0) { + $return = true; + + $sync_date = new ilDateTime($last_sync, IL_CAL_UNIX); + $msg = sprintf( + $this->lng->txt('tst_msg_rand_quest_set_stage_pool_last_sync'), + ilDatePresentation::formatDate($sync_date) + ); + + $href = $this->ctrl->getLinkTarget($this, self::CMD_RESET_POOLSYNC); + $label = $this->lng->txt('tst_btn_reset_pool_sync'); + + $buttons = [ + $this->dic->ui()->factory()->button()->standard($label, $href) + ]; + + $msgbox = $this->dic->ui()->factory()->messageBox() + ->info($msg) + ->withButtons($buttons); + $message = $this->dic->ui()->renderer()->render($msgbox); + $this->dic->ui()->mainTemplate()->setCurrentBlock('mess'); + $this->dic->ui()->mainTemplate()->setVariable('MESSAGE', $message); + $this->dic->ui()->mainTemplate()->parseCurrentBlock(); + } + return $return; + } + + public function resetPoolSyncCmd() : void + { + $this->questionSetConfig->setLastQuestionSyncTimestamp(0); + $this->questionSetConfig->saveToDb(); + $this->ctrl->redirect($this, self::CMD_SHOW_GENERAL_CONFIG_FORM); + } } diff --git a/lang/ilias_de.lang b/lang/ilias_de.lang index cfe9481b84c0..c3969d305bf2 100644 --- a/lang/ilias_de.lang +++ b/lang/ilias_de.lang @@ -1152,6 +1152,7 @@ assessment#:#tst_msg_random_qsc_modified_add_new_rule#:#Die Konfiguration für d assessment#:#tst_msg_random_question_set_config_modified#:#Die Konfiguration für den Test mit zufälliger Fragenauswahl wurde erfolgreich geändert. assessment#:#tst_msg_random_question_set_synced#:#Die Fragen zur aktuellen Konfiguration des Tests mit zufälliger Fragenauswahl wurde erfolgreich synchronisiert. assessment#:#tst_btn_rebuild_random_question_stage#:#Synchronisiere Fragen aus den Pools +assessment#:#tst_btn_reset_pool_sync#:#Bearbeiten/Synchronisation aufheben assessment#:#tst_msg_rand_quest_set_stage_pool_last_sync#:#Zeitpunkt der letzten Synchronisierung der Fragen aus den ausgewählten Fragenpools: %s assessment#:#tst_msg_rand_quest_set_pass_buildable#:#Ein Test mit zufälliger Fragenauswahl ist mit der aktuellen Konfiguration möglich. assessment#:#tst_msg_rand_quest_set_pass_not_buildable#:#Mit der aktuellen Auswahl an Fragenpools und der Fragenanzahl kann kein Test mit zufälliger Fragenauswahl erzeugt werden.
diff --git a/lang/ilias_en.lang b/lang/ilias_en.lang index 277602eb2466..bc53220014d9 100644 --- a/lang/ilias_en.lang +++ b/lang/ilias_en.lang @@ -1108,6 +1108,7 @@ assessment#:#tst_msg_random_qsc_modified_add_new_rule#:#The configuration for th assessment#:#tst_msg_random_question_set_config_modified#:#The configuration for the random set of questions has been modified successfully. assessment#:#tst_msg_random_question_set_synced#:#The questions for the current configuration has been synchronized successfully. assessment#:#tst_btn_rebuild_random_question_stage#:#Synchronize Questions from Pool +assessment#:#tst_btn_reset_pool_sync#:#Edit/Cancel Synchronisation assessment#:#tst_msg_rand_quest_set_stage_pool_last_sync#:#Date of last synchronisation of selected question pools: %s assessment#:#tst_msg_rand_quest_set_pass_buildable#:#A test with a random set of questions is possible with the current configuration. assessment#:#tst_msg_rand_quest_set_pass_not_buildable#:#A test with a random set of questions is not possible with the current selection of question pools and the amount of questions.