1<?php 2/* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */ 3 4require_once 'Modules/Test/classes/class.ilTestSettingsGUI.php'; 5 6/** 7 * GUI class that manages the editing of general test settings/properties 8 * shown on "general" subtab 9 * 10 * @author Björn Heyser <bheyser@databay.de> 11 * @version $Id$ 12 * 13 * @package Modules/Test 14 * 15 * @ilCtrl_Calls ilObjTestSettingsScoringResultsGUI: ilPropertyFormGUI, ilConfirmationGUI 16 */ 17class ilObjTestSettingsScoringResultsGUI extends ilTestSettingsGUI 18{ 19 /** 20 * command constants 21 */ 22 const CMD_SHOW_FORM = 'showForm'; 23 const CMD_SAVE_FORM = 'saveForm'; 24 const CMD_CONFIRMED_SAVE_FORM = 'confirmedSaveForm'; 25 26 /** @var ilCtrl $ctrl */ 27 protected $ctrl = null; 28 29 /** @var ilAccess $access */ 30 protected $access = null; 31 32 /** @var ilLanguage $lng */ 33 protected $lng = null; 34 35 /** @var ilGlobalTemplateInterface $tpl */ 36 protected $tpl = null; 37 38 /** @var ilTree $tree */ 39 protected $tree = null; 40 41 /** @var ilDBInterface $db */ 42 protected $db = null; 43 44 /** @var ilPluginAdmin $pluginAdmin */ 45 protected $pluginAdmin = null; 46 47 /** @var ilObjTest $testOBJ */ 48 protected $testOBJ = null; 49 50 /** @var ilObjTestGUI $testGUI */ 51 protected $testGUI = null; 52 53 /** @var ilTestQuestionSetConfigFactory $testQuestionSetConfigFactory Factory for question set config. */ 54 private $testQuestionSetConfigFactory = null; 55 56 /** 57 * object instance for currently active settings template 58 * 59 * @var $settingsTemplate ilSettingsTemplate 60 */ 61 protected $settingsTemplate = null; 62 63 /** 64 * Constructor 65 * 66 * @param ilCtrl $ctrl 67 * @param ilAccessHandler $access 68 * @param ilLanguage $lng 69 * @param ilTemplate $tpl 70 * @param ilDBInterface $db 71 * @param ilObjTestGUI $testGUI 72 * 73 * @return \ilObjTestSettingsGeneralGUI 74 */ 75 public function __construct( 76 ilCtrl $ctrl, 77 ilAccessHandler $access, 78 ilLanguage $lng, 79 ilTree $tree, 80 ilDBInterface $db, 81 ilPluginAdmin $pluginAdmin, 82 ilObjTestGUI $testGUI 83 ) { 84 global $DIC; /* @var ILIAS\DI\Container $DIC */ 85 86 $this->ctrl = $ctrl; 87 $this->access = $access; 88 $this->lng = $lng; 89 $this->tpl = $DIC->ui()->mainTemplate(); 90 $this->tree = $tree; 91 $this->db = $db; 92 $this->pluginAdmin = $pluginAdmin; 93 94 $this->testGUI = $testGUI; 95 $this->testOBJ = $testGUI->object; 96 97 require_once 'Modules/Test/classes/class.ilTestQuestionSetConfigFactory.php'; 98 $this->testQuestionSetConfigFactory = new ilTestQuestionSetConfigFactory($this->tree, $this->db, $this->pluginAdmin, $this->testOBJ); 99 100 $templateId = $this->testOBJ->getTemplate(); 101 102 if ($templateId) { 103 include_once "Services/Administration/classes/class.ilSettingsTemplate.php"; 104 $this->settingsTemplate = new ilSettingsTemplate($templateId, ilObjAssessmentFolderGUI::getSettingsTemplateConfig()); 105 } 106 } 107 108 /** 109 * Command Execution 110 */ 111 public function executeCommand() 112 { 113 // allow only write access 114 115 if (!$this->access->checkAccess('write', '', $this->testGUI->ref_id)) { 116 ilUtil::sendInfo($this->lng->txt('cannot_edit_test'), true); 117 $this->ctrl->redirect($this->testGUI, 'infoScreen'); 118 } 119 120 global $DIC; /* @var ILIAS\DI\Container $DIC */ 121 122 $DIC->tabs()->activateTab(ilTestTabsManager::TAB_ID_SETTINGS); 123 124 // process command 125 126 $nextClass = $this->ctrl->getNextClass(); 127 128 switch ($nextClass) { 129 default: 130 $cmd = $this->ctrl->getCmd(self::CMD_SHOW_FORM) . 'Cmd'; 131 $this->$cmd(); 132 } 133 } 134 135 private function showFormCmd(ilPropertyFormGUI $form = null) 136 { 137 //$this->tpl->addJavascript("./Services/JavaScript/js/Basic.js"); 138 139 if ($form === null) { 140 $form = $this->buildForm(); 141 } 142 143 $this->tpl->setContent($this->ctrl->getHTML($form)); 144 } 145 146 private function confirmedSaveFormCmd() 147 { 148 return $this->saveFormCmd(true); 149 } 150 151 private function saveFormCmd($isConfirmedSave = false) 152 { 153 $form = $this->buildForm(); 154 155 // form validation and initialisation 156 157 $errors = !$form->checkInput(); // ALWAYS CALL BEFORE setValuesByPost() 158 $form->setValuesByPost(); // NEVER CALL THIS BEFORE checkInput() 159 160 // return to form when any form validation errors exist 161 162 if ($errors) { 163 ilUtil::sendFailure($this->lng->txt('form_input_not_valid')); 164 return $this->showFormCmd($form); 165 } 166 167 // check for required confirmation and redirect if neccessary 168 169 if (!$isConfirmedSave && $this->isScoreRecalculationRequired($form)) { 170 return $this->showConfirmation($form); 171 } 172 173 // saving the form leads to isScoreRecalculationRequired($form) 174 // returning false, so remember whether recalculation is needed 175 176 $recalcRequired = $this->isScoreRecalculationRequired($form); 177 178 // perform save 179 180 $this->performSaveForm($form); 181 182 if ($recalcRequired) { 183 $this->testOBJ->recalculateScores(true); 184 } 185 186 // redirect to form output 187 188 ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true); 189 $this->ctrl->redirect($this, self::CMD_SHOW_FORM); 190 } 191 192 private function performSaveForm(ilPropertyFormGUI $form) 193 { 194 $this->saveScoringSettingsFormSection($form); 195 $this->saveResultSummarySettings($form); 196 $this->saveResultDetailsSettings($form); 197 $this->saveResultMiscOptionsSettings($form); 198 199 // store settings to db 200 $this->testOBJ->saveToDb(true); 201 } 202 203 private function showConfirmation(ilPropertyFormGUI $form) 204 { 205 require_once 'Services/Utilities/classes/class.ilConfirmationGUI.php'; 206 $confirmation = new ilConfirmationGUI(); 207 208 $confirmation->setHeaderText($this->lng->txt('tst_trigger_result_refreshing')); 209 210 $confirmation->setFormAction($this->ctrl->getFormAction($this)); 211 $confirmation->setCancel($this->lng->txt('cancel'), self::CMD_SHOW_FORM); 212 $confirmation->setConfirm($this->lng->txt('confirm'), self::CMD_CONFIRMED_SAVE_FORM); 213 214 foreach ($form->getInputItemsRecursive() as $key => $item) { 215 //vd("$key // {$item->getType()} // ".json_encode($_POST[$item->getPostVar()])); 216 217 switch ($item->getType()) { 218 case 'section_header': 219 220 break; 221 222 case 'datetime': 223 224 $datetime = $item->getDate(); 225 if ($datetime instanceof ilDateTime) { 226 list($date, $time) = explode(' ', $datetime->get(IL_CAL_DATETIME)); 227 if (!($date instanceof ilDate)) { 228 $confirmation->addHiddenItem($item->getPostVar(), $date . ' ' . $time); 229 } else { 230 $confirmation->addHiddenItem($item->getPostVar(), $date); 231 } 232 } else { 233 $confirmation->addHiddenItem($item->getPostVar(), ''); 234 } 235 236 break; 237 238 case 'duration': 239 240 $confirmation->addHiddenItem("{$item->getPostVar()}[MM]", (int) $item->getMonths()); 241 $confirmation->addHiddenItem("{$item->getPostVar()}[dd]", (int) $item->getDays()); 242 $confirmation->addHiddenItem("{$item->getPostVar()}[hh]", (int) $item->getHours()); 243 $confirmation->addHiddenItem("{$item->getPostVar()}[mm]", (int) $item->getMinutes()); 244 $confirmation->addHiddenItem("{$item->getPostVar()}[ss]", (int) $item->getSeconds()); 245 246 break; 247 248 case 'checkboxgroup': 249 250 if (is_array($item->getValue())) { 251 foreach ($item->getValue() as $option) { 252 $confirmation->addHiddenItem("{$item->getPostVar()}[]", $option); 253 } 254 } 255 256 break; 257 258 case 'checkbox': 259 260 if ($item->getChecked()) { 261 $confirmation->addHiddenItem($item->getPostVar(), 1); 262 } 263 264 break; 265 266 default: 267 268 $confirmation->addHiddenItem($item->getPostVar(), $item->getValue()); 269 } 270 } 271 272 $this->tpl->setContent($this->ctrl->getHTML($confirmation)); 273 } 274 275 private function buildForm() 276 { 277 include_once 'Services/Form/classes/class.ilPropertyFormGUI.php'; 278 $form = new ilPropertyFormGUI(); 279 $form->setFormAction($this->ctrl->getFormAction($this)); 280 $form->setTableWidth('100%'); 281 $form->setId('test_scoring_results'); 282 283 $this->addScoringSettingsFormSection($form); 284 $this->addResultSummarySettingsFormSection($form); 285 $this->addResultDetailsSettingsFormSection($form); 286 $this->addMiscSettingsFormSection($form); 287 288 // remove items when using template 289 if ($this->settingsTemplate) { 290 foreach ($this->settingsTemplate->getSettings() as $id => $item) { 291 if ($item["hide"]) { 292 $form->removeItemByPostVar($id); 293 } 294 } 295 } 296 297 $form->addCommandButton(self::CMD_SAVE_FORM, $this->lng->txt('save')); 298 299 return $form; 300 } 301 302 private function addScoringSettingsFormSection(ilPropertyFormGUI $form) 303 { 304 $fields = array( 305 'count_system', 'mc_scoring', 'score_cutting', 'pass_scoring', 'pass_deletion_allowed' 306 ); 307 308 if ($this->isSectionHeaderRequired($fields)) { 309 // scoring settings 310 $header = new ilFormSectionHeaderGUI(); 311 $header->setTitle($this->lng->txt('test_scoring')); 312 $form->addItem($header); 313 } 314 315 // scoring system 316 $count_system = new ilRadioGroupInputGUI($this->lng->txt('tst_text_count_system'), 'count_system'); 317 $count_system->addOption($opt = new ilRadioOption($this->lng->txt('tst_count_partial_solutions'), 0, '')); 318 $opt->setInfo($this->lng->txt('tst_count_partial_solutions_desc')); 319 $count_system->addOption($opt = new ilRadioOption($this->lng->txt('tst_count_correct_solutions'), 1, '')); 320 $opt->setInfo($this->lng->txt('tst_count_correct_solutions_desc')); 321 $count_system->setValue($this->testOBJ->getCountSystem()); 322 $form->addItem($count_system); 323 324 // mc questions 325 $mc_scoring = new ilRadioGroupInputGUI($this->lng->txt('tst_score_mcmr_questions'), 'mc_scoring'); 326 $mc_scoring->addOption($opt = new ilRadioOption($this->lng->txt('tst_score_mcmr_zero_points_when_unanswered'), 0, '')); 327 $opt->setInfo($this->lng->txt('tst_score_mcmr_zero_points_when_unanswered_desc')); 328 $mc_scoring->addOption($opt = new ilRadioOption($this->lng->txt('tst_score_mcmr_use_scoring_system'), 1, '')); 329 $opt->setInfo($this->lng->txt('tst_score_mcmr_use_scoring_system_desc')); 330 $mc_scoring->setValue($this->testOBJ->getMCScoring()); 331 // fau: testNav - set the deprecated mc scoring option to disabled 332 $mc_scoring->setDisabled(true); 333 // fau. 334 $form->addItem($mc_scoring); 335 336 // score cutting 337 $score_cutting = new ilRadioGroupInputGUI($this->lng->txt('tst_score_cutting'), 'score_cutting'); 338 $score_cutting->addOption($opt = new ilRadioOption($this->lng->txt('tst_score_cut_question'), 0, '')); 339 $opt->setInfo($this->lng->txt('tst_score_cut_question_desc')); 340 $score_cutting->addOption($opt = new ilRadioOption($this->lng->txt('tst_score_cut_test'), 1, '')); 341 $opt->setInfo($this->lng->txt('tst_score_cut_test_desc')); 342 $score_cutting->setValue($this->testOBJ->getScoreCutting()); 343 $form->addItem($score_cutting); 344 345 // pass scoring 346 $pass_scoring = new ilRadioGroupInputGUI($this->lng->txt('tst_pass_scoring'), 'pass_scoring'); 347 $pass_scoring->addOption($opt = new ilRadioOption($this->lng->txt('tst_pass_last_pass'), 0, '')); 348 $opt->setInfo($this->lng->txt('tst_pass_last_pass_desc')); 349 $pass_scoring->addOption($opt = new ilRadioOption($this->lng->txt('tst_pass_best_pass'), 1, '')); 350 $opt->setInfo($this->lng->txt('tst_pass_best_pass_desc')); 351 $pass_scoring->setValue($this->testOBJ->getPassScoring()); 352 $form->addItem($pass_scoring); 353 354 // deletion of test results 355 $passDeletion = new ilRadioGroupInputGUI($this->lng->txt('tst_pass_deletion'), 'pass_deletion_allowed'); 356 $passDeletion->addOption(new ilRadioOption($this->lng->txt('tst_pass_deletion_not_allowed'), 0, '')); 357 $passDeletion->addOption(new ilRadioOption($this->lng->txt('tst_pass_deletion_allowed'), 1, '')); 358 $passDeletion->setValue($this->testOBJ->isPassDeletionAllowed()); 359 $form->addItem($passDeletion); 360 361 // disable scoring settings 362 if (!$this->areScoringSettingsWritable()) { 363 $count_system->setDisabled(true); 364 $mc_scoring->setDisabled(true); 365 $score_cutting->setDisabled(true); 366 $pass_scoring->setDisabled(true); 367 } 368 } 369 370 /** 371 * @param ilPropertyFormGUI $form 372 */ 373 private function saveScoringSettingsFormSection(ilPropertyFormGUI $form) 374 { 375 if ($this->areScoringSettingsWritable()) { 376 if ($this->formPropertyExists($form, 'count_system')) { 377 $this->testOBJ->setCountSystem($form->getItemByPostVar('count_system')->getValue()); 378 } 379 380 if ($this->formPropertyExists($form, 'mc_scoring')) { 381 $this->testOBJ->setMCScoring($form->getItemByPostVar('mc_scoring')->getValue()); 382 } 383 384 if ($this->formPropertyExists($form, 'score_cutting')) { 385 $this->testOBJ->setScoreCutting($form->getItemByPostVar('score_cutting')->getValue()); 386 } 387 388 if ($this->formPropertyExists($form, 'pass_scoring')) { 389 $this->testOBJ->setPassScoring($form->getItemByPostVar('pass_scoring')->getValue()); 390 } 391 } 392 393 if ($this->formPropertyExists($form, 'pass_deletion_allowed')) { 394 $this->testOBJ->setPassDeletionAllowed((bool) $form->getItemByPostVar('pass_deletion_allowed')->getValue()); 395 } 396 } 397 398 private function addResultSummarySettingsFormSection(ilPropertyFormGUI $form) 399 { 400 // HEADER: result settings 401 $header_tr = new ilFormSectionHeaderGUI(); 402 $header_tr->setTitle($this->lng->txt('test_results')); 403 $form->addItem($header_tr); 404 405 // access to test results 406 $resultsAccessEnabled = new ilCheckboxInputGUI($this->lng->txt('tst_results_access_enabled'), 'results_access_enabled'); 407 $resultsAccessEnabled->setInfo($this->lng->txt('tst_results_access_enabled_desc')); 408 $resultsAccessEnabled->setChecked($this->testOBJ->isScoreReportingEnabled()); 409 $resultsAccessSetting = new ilRadioGroupInputGUI($this->lng->txt('tst_results_access_setting'), 'results_access_setting'); 410 $resultsAccessSetting->setRequired(true); 411 $optAlways = new ilRadioOption($this->lng->txt('tst_results_access_always')); 412 $optAlways->setInfo($this->lng->txt('tst_results_access_always_desc')); 413 $optAlways->setValue(ilObjTest::SCORE_REPORTING_IMMIDIATLY); 414 $resultsAccessSetting->addOption($optAlways); 415 $optFinished = $opt = new ilRadioOption($this->lng->txt('tst_results_access_finished')); 416 $optFinished->setInfo($this->lng->txt('tst_results_access_finished_desc')); 417 $optFinished->setValue(ilObjTest::SCORE_REPORTING_FINISHED); 418 $resultsAccessSetting->addOption($optFinished); 419 $optPassed = $opt = new ilRadioOption($this->lng->txt('tst_results_access_passed')); 420 $optPassed->setInfo($this->lng->txt('tst_results_access_passed_desc')); 421 $optPassed->setValue(ilObjTest::SCORE_REPORTING_AFTER_PASSED); 422 $resultsAccessSetting->addOption($optPassed); 423 $optionDate = new ilRadioOption($this->lng->txt('tst_results_access_date')); 424 $optionDate->setInfo($this->lng->txt('tst_results_access_date_desc')); 425 $optionDate->setValue(ilObjTest::SCORE_REPORTING_DATE); 426 // access date 427 $reportingDate = new ilDateTimeInputGUI($this->lng->txt('tst_reporting_date'), 'reporting_date'); 428 $reportingDate->setRequired(true); 429 $reportingDate->setShowTime(true); 430 if (strlen($this->testOBJ->getReportingDate())) { 431 $reportingDate->setDate(new ilDateTime($this->testOBJ->getReportingDate(), IL_CAL_TIMESTAMP)); 432 } else { 433 $reportingDate->setDate(new ilDateTime(time(), IL_CAL_UNIX)); 434 } 435 $optionDate->addSubItem($reportingDate); 436 $resultsAccessSetting->addOption($optionDate); 437 $resultsAccessSetting->setValue($this->testOBJ->getScoreReporting()); 438 $resultsAccessEnabled->addSubItem($resultsAccessSetting); 439 // show pass details 440 $showPassDetails = new ilCheckboxInputGUI($this->lng->txt('tst_show_pass_details'), 'pass_details'); 441 $showPassDetails->setInfo($this->lng->txt('tst_show_pass_details_desc')); 442 $showPassDetails->setChecked($this->testOBJ->getShowPassDetails()); 443 $resultsAccessEnabled->addSubItem($showPassDetails); 444 $form->addItem($resultsAccessEnabled); 445 446 // grading 447 $chb_only_passed_failed = new ilCheckboxInputGUI($this->lng->txt('tst_results_grading_opt_show_status'), 'grading_status'); 448 $chb_only_passed_failed->setInfo($this->lng->txt('tst_results_grading_opt_show_status_desc')); 449 $chb_only_passed_failed->setValue(1); 450 $chb_only_passed_failed->setChecked($this->testOBJ->isShowGradingStatusEnabled()); 451 $resultsAccessEnabled->addSubItem($chb_only_passed_failed); 452 453 $chb_resulting_mark_only = new ilCheckboxInputGUI($this->lng->txt('tst_results_grading_opt_show_mark'), 'grading_mark'); 454 $chb_resulting_mark_only->setInfo($this->lng->txt('tst_results_grading_opt_show_mark_desc')); 455 $chb_resulting_mark_only->setValue(1); 456 $chb_resulting_mark_only->setChecked($this->testOBJ->isShowGradingMarkEnabled()); 457 $resultsAccessEnabled->addSubItem($chb_resulting_mark_only); 458 } 459 460 /** 461 * @param ilPropertyFormGUI $form 462 */ 463 private function saveResultSummarySettings(ilPropertyFormGUI $form) 464 { 465 if ($this->formPropertyExists($form, 'results_access_enabled')) { 466 if ($form->getItemByPostVar('results_access_enabled')->getChecked()) { 467 $this->testOBJ->setScoreReporting($form->getItemByPostVar('results_access_setting')->getValue()); 468 469 if ($this->testOBJ->getScoreReporting() == ilObjTest::SCORE_REPORTING_DATE) { 470 $reporting_date = $form->getItemByPostVar('reporting_date')->getDate(); 471 if ($reporting_date instanceof ilDateTime) { 472 $this->testOBJ->setReportingDate($reporting_date->get(IL_CAL_FKT_DATE, 'YmdHis')); 473 } else { 474 $this->testOBJ->setReportingDate(''); 475 } 476 } else { 477 $this->testOBJ->setReportingDate(''); 478 } 479 480 $this->testOBJ->setShowPassDetails($form->getItemByPostVar('pass_details')->getChecked()); 481 } else { 482 $this->testOBJ->setScoreReporting(ilObjTest::SCORE_REPORTING_DISABLED); 483 $this->testOBJ->setShowPassDetails(false); 484 $this->testOBJ->setReportingDate(''); 485 } 486 } 487 488 if ($this->formPropertyExists($form, 'grading_status')) { 489 $this->testOBJ->setShowGradingStatusEnabled( 490 $form->getItemByPostVar('grading_status')->getChecked() 491 ); 492 } 493 494 if ($this->formPropertyExists($form, 'grading_mark')) { 495 $this->testOBJ->setShowGradingMarkEnabled( 496 (int) $form->getItemByPostVar('grading_mark')->getChecked() 497 ); 498 } 499 } 500 501 private function addResultDetailsSettingsFormSection(ilPropertyFormGUI $form) 502 { 503 // HEADER: result settings 504 $header_tr = new ilFormSectionHeaderGUI(); 505 $header_tr->setTitle($this->lng->txt('tst_results_details_options')); 506 $form->addItem($header_tr); 507 508 // show solution details 509 $showSolutionDetails = new ilCheckboxInputGUI($this->lng->txt('tst_show_solution_details'), 'solution_details'); 510 $showSolutionDetails->setInfo($this->lng->txt('tst_show_solution_details_desc')); 511 $showSolutionDetails->setChecked($this->testOBJ->getShowSolutionDetails()); 512 $form->addItem($showSolutionDetails); 513 514 // best solution in test results 515 $results_print_best_solution = new ilCheckboxInputGUI($this->lng->txt('tst_results_print_best_solution'), 'print_bs_with_res'); 516 $results_print_best_solution->setInfo($this->lng->txt('tst_results_print_best_solution_info')); 517 $results_print_best_solution->setChecked((bool) $this->testOBJ->isBestSolutionPrintedWithResult()); 518 $showSolutionDetails->addSubItem($results_print_best_solution); 519 520 // show solution feedback ==> solution feedback in test results 521 $showSolutionFeedbackOption = new ilCheckboxInputGUI($this->lng->txt('tst_show_solution_feedback'), 'solution_feedback'); 522 $showSolutionFeedbackOption->setInfo($this->lng->txt('tst_show_solution_feedback_desc')); 523 $showSolutionFeedbackOption->setChecked($this->testOBJ->getShowSolutionFeedback()); 524 $form->addItem($showSolutionFeedbackOption); 525 526 // show suggested solution 527 $showSuggestedSolutionOption = new ilCheckboxInputGUI($this->lng->txt('tst_show_solution_suggested'), 'solution_suggested'); 528 $showSuggestedSolutionOption->setInfo($this->lng->txt('tst_show_solution_suggested_desc')); 529 $showSuggestedSolutionOption->setChecked($this->testOBJ->getShowSolutionSuggested()); 530 $form->addItem($showSuggestedSolutionOption); 531 532 // show solution printview ==> list of answers 533 $showSolutionPrintview = new ilCheckboxInputGUI($this->lng->txt('tst_show_solution_printview'), 'solution_printview'); 534 $showSolutionPrintview->setInfo($this->lng->txt('tst_show_solution_printview_desc')); 535 $showSolutionPrintview->setChecked($this->testOBJ->getShowSolutionPrintview()); 536 $form->addItem($showSolutionPrintview); 537 538 // show best solution in list of answers 539 $solutionCompareInput = new ilCheckboxInputGUI($this->lng->txt('tst_show_solution_compare'), 'solution_compare'); 540 $solutionCompareInput->setInfo($this->lng->txt('tst_show_solution_compare_desc')); 541 $solutionCompareInput->setChecked($this->testOBJ->getShowSolutionListComparison()); 542 $showSolutionPrintview->addSubItem($solutionCompareInput); 543 544 // solution answers only ==> printview of results (answers only) 545 $solutionAnswersOnly = new ilCheckboxInputGUI($this->lng->txt('tst_show_solution_answers_only'), 'solution_answers_only'); 546 $solutionAnswersOnly->setInfo($this->lng->txt('tst_show_solution_answers_only_desc')); 547 $solutionAnswersOnly->setChecked($this->testOBJ->getShowSolutionAnswersOnly()); 548 $showSolutionPrintview->addSubItem($solutionAnswersOnly); 549 550 // high score 551 $highscore = new ilCheckboxInputGUI($this->lng->txt("tst_highscore_enabled"), "highscore_enabled"); 552 $highscore->setValue(1); 553 $highscore->setChecked($this->testOBJ->getHighscoreEnabled()); 554 $highscore->setInfo($this->lng->txt("tst_highscore_description")); 555 $form->addItem($highscore); 556 $highscore_tables = new ilRadioGroupInputGUI($this->lng->txt('tst_highscore_mode'), 'highscore_mode'); 557 $highscore_tables->setRequired(true); 558 $highscore_tables->setValue($this->testOBJ->getHighscoreMode()); 559 $highscore_table_own = new ilRadioOption($this->lng->txt('tst_highscore_own_table'), ilObjTest::HIGHSCORE_SHOW_OWN_TABLE); 560 $highscore_table_own->setInfo($this->lng->txt('tst_highscore_own_table_description')); 561 $highscore_tables->addOption($highscore_table_own); 562 $highscore_table_other = new ilRadioOption($this->lng->txt('tst_highscore_top_table'), ilObjTest::HIGHSCORE_SHOW_TOP_TABLE); 563 $highscore_table_other->setInfo($this->lng->txt('tst_highscore_top_table_description')); 564 $highscore_tables->addOption($highscore_table_other); 565 $highscore_table_other = new ilRadioOption($this->lng->txt('tst_highscore_all_tables'), ilObjTest::HIGHSCORE_SHOW_ALL_TABLES); 566 $highscore_table_other->setInfo($this->lng->txt('tst_highscore_all_tables_description')); 567 $highscore_tables->addOption($highscore_table_other); 568 $highscore->addSubItem($highscore_tables); 569 $highscore_top_num = new ilNumberInputGUI($this->lng->txt("tst_highscore_top_num"), "highscore_top_num"); 570 $highscore_top_num->setSize(4); 571 $highscore_top_num->setRequired(true); 572 $highscore_top_num->setMinValue(1); 573 $highscore_top_num->setSuffix($this->lng->txt("tst_highscore_top_num_unit")); 574 $highscore_top_num->setValue($this->testOBJ->getHighscoreTopNum(null)); 575 $highscore_top_num->setInfo($this->lng->txt("tst_highscore_top_num_description")); 576 $highscore->addSubItem($highscore_top_num); 577 $highscore_anon = new ilCheckboxInputGUI($this->lng->txt("tst_highscore_anon"), "highscore_anon"); 578 $highscore_anon->setValue(1); 579 $highscore_anon->setChecked($this->testOBJ->getHighscoreAnon()); 580 $highscore_anon->setInfo($this->lng->txt("tst_highscore_anon_description")); 581 $highscore->addSubItem($highscore_anon); 582 $highscore_achieved_ts = new ilCheckboxInputGUI($this->lng->txt("tst_highscore_achieved_ts"), "highscore_achieved_ts"); 583 $highscore_achieved_ts->setValue(1); 584 $highscore_achieved_ts->setChecked($this->testOBJ->getHighscoreAchievedTS()); 585 $highscore_achieved_ts->setInfo($this->lng->txt("tst_highscore_achieved_ts_description")); 586 $highscore->addSubItem($highscore_achieved_ts); 587 $highscore_score = new ilCheckboxInputGUI($this->lng->txt("tst_highscore_score"), "highscore_score"); 588 $highscore_score->setValue(1); 589 $highscore_score->setChecked($this->testOBJ->getHighscoreScore()); 590 $highscore_score->setInfo($this->lng->txt("tst_highscore_score_description")); 591 $highscore->addSubItem($highscore_score); 592 $highscore_percentage = new ilCheckboxInputGUI($this->lng->txt("tst_highscore_percentage"), "highscore_percentage"); 593 $highscore_percentage->setValue(1); 594 $highscore_percentage->setChecked($this->testOBJ->getHighscorePercentage()); 595 $highscore_percentage->setInfo($this->lng->txt("tst_highscore_percentage_description")); 596 $highscore->addSubItem($highscore_percentage); 597 $highscore_hints = new ilCheckboxInputGUI($this->lng->txt("tst_highscore_hints"), "highscore_hints"); 598 $highscore_hints->setValue(1); 599 $highscore_hints->setChecked($this->testOBJ->getHighscoreHints()); 600 $highscore_hints->setInfo($this->lng->txt("tst_highscore_hints_description")); 601 $highscore->addSubItem($highscore_hints); 602 $highscore_wtime = new ilCheckboxInputGUI($this->lng->txt("tst_highscore_wtime"), "highscore_wtime"); 603 $highscore_wtime->setValue(1); 604 $highscore_wtime->setChecked($this->testOBJ->getHighscoreWTime()); 605 $highscore_wtime->setInfo($this->lng->txt("tst_highscore_wtime_description")); 606 $highscore->addSubItem($highscore_wtime); 607 608 // show signature placeholder 609 $showSignaturePlaceholder = new ilCheckboxInputGUI($this->lng->txt('tst_show_solution_signature'), 'solution_signature'); 610 $showSignaturePlaceholder->setInfo($this->lng->txt('tst_show_solution_signature_desc')); 611 $showSignaturePlaceholder->setChecked($this->testOBJ->getShowSolutionSignature()); 612 if ($this->testOBJ->getAnonymity()) { 613 $showSignaturePlaceholder->setDisabled(true); 614 } 615 $form->addItem($showSignaturePlaceholder); 616 617 // show signature placeholder 618 $showExamId = new ilCheckboxInputGUI($this->lng->txt('examid_in_test_res'), 'examid_in_test_res'); 619 $showExamId->setInfo($this->lng->txt('examid_in_test_res_desc')); 620 $showExamId->setChecked($this->testOBJ->isShowExamIdInTestResultsEnabled()); 621 $form->addItem($showExamId); 622 623 // export settings 624 $export_settings = new ilCheckboxInputGUI($this->lng->txt('tst_exp_sc_short'), 'exp_sc_short'); 625 $export_settings->setInfo($this->lng->txt('tst_exp_sc_short_desc')); 626 $export_settings->setChecked($this->testOBJ->getExportSettingsSingleChoiceShort()); 627 $form->addItem($export_settings); 628 } 629 630 /** 631 * @param ilPropertyFormGUI $form 632 */ 633 private function saveResultDetailsSettings(ilPropertyFormGUI $form) 634 { 635 if ($this->formPropertyExists($form, 'solution_details')) { 636 if ($form->getItemByPostVar('solution_details')->getChecked()) { 637 $this->testOBJ->setShowSolutionDetails(1); 638 $this->testOBJ->setPrintBestSolutionWithResult( 639 (int) $form->getItemByPostVar('print_bs_with_res')->getChecked() 640 ); 641 } else { 642 $this->testOBJ->setShowSolutionDetails(0); 643 $this->testOBJ->setPrintBestSolutionWithResult(0); 644 } 645 } 646 647 if ($this->formPropertyExists($form, 'solution_feedback')) { 648 $this->testOBJ->setShowSolutionFeedback($form->getItemByPostVar('solution_feedback')->getChecked()); 649 } 650 651 if ($this->formPropertyExists($form, 'solution_suggested')) { 652 $this->testOBJ->setShowSolutionSuggested($form->getItemByPostVar('solution_suggested')->getChecked()); 653 } 654 655 if ($this->formPropertyExists($form, 'solution_printview')) { 656 if ($form->getItemByPostVar('solution_printview')->getChecked()) { 657 $this->testOBJ->setShowSolutionPrintview(1); 658 $this->testOBJ->setShowSolutionListComparison( 659 (bool) $form->getItemByPostVar('solution_compare')->getChecked() 660 ); 661 $this->testOBJ->setShowSolutionAnswersOnly( 662 (int) $form->getItemByPostVar('solution_answers_only')->getChecked() 663 ); 664 } else { 665 $this->testOBJ->setShowSolutionPrintview(0); 666 $this->testOBJ->setShowSolutionListComparison(false); 667 $this->testOBJ->setShowSolutionAnswersOnly(0); 668 } 669 } 670 671 if ($this->formPropertyExists($form, 'highscore_enabled')) { 672 // highscore settings 673 $this->testOBJ->setHighscoreEnabled((bool) $form->getItemByPostVar('highscore_enabled')->getChecked()); 674 $this->testOBJ->setHighscoreAnon((bool) $form->getItemByPostVar('highscore_anon')->getChecked()); 675 $this->testOBJ->setHighscoreAchievedTS((bool) $form->getItemByPostVar('highscore_achieved_ts')->getChecked()); 676 $this->testOBJ->setHighscoreScore((bool) $form->getItemByPostVar('highscore_score')->getChecked()); 677 $this->testOBJ->setHighscorePercentage((bool) $form->getItemByPostVar('highscore_percentage')->getChecked()); 678 $this->testOBJ->setHighscoreHints((bool) $form->getItemByPostVar('highscore_hints')->getChecked()); 679 $this->testOBJ->setHighscoreWTime((bool) $form->getItemByPostVar('highscore_wtime')->getChecked()); 680 $this->testOBJ->setHighscoreMode((int) $form->getItemByPostVar('highscore_mode')->getValue()); 681 $this->testOBJ->setHighscoreTopNum((int) $form->getItemByPostVar('highscore_top_num')->getValue()); 682 } 683 684 if ($this->formPropertyExists($form, 'solution_signature')) { 685 $this->testOBJ->setShowSolutionSignature($form->getItemByPostVar('solution_signature')->getChecked()); 686 } 687 688 if ($this->formPropertyExists($form, 'examid_in_test_res')) { 689 $this->testOBJ->setShowExamIdInTestResultsEnabled($form->getItemByPostVar('examid_in_test_res')->getChecked()); 690 } 691 692 if ($this->formPropertyExists($form, 'exp_sc_short')) { 693 $this->testOBJ->setExportSettingsSingleChoiceShort((int) $form->getItemByPostVar('exp_sc_short')->getChecked()); 694 } 695 } 696 697 private function addMiscSettingsFormSection(ilPropertyFormGUI $form) 698 { 699 if ($this->testQuestionSetConfigFactory->getQuestionSetConfig()->isResultTaxonomyFilterSupported()) { 700 // misc settings 701 $header_misc = new ilFormSectionHeaderGUI(); 702 $header_misc->setTitle($this->lng->txt('misc')); 703 $form->addItem($header_misc); 704 } 705 706 // result filter taxonomies 707 if ($this->testQuestionSetConfigFactory->getQuestionSetConfig()->isResultTaxonomyFilterSupported()) { 708 $availableTaxonomyIds = $this->getAvailableTaxonomyIds(); 709 710 if (count($availableTaxonomyIds)) { 711 require_once 'Modules/Test/classes/class.ilTestTaxonomyFilterLabelTranslater.php'; 712 $labelTranslater = new ilTestTaxonomyFilterLabelTranslater($this->db); 713 $labelTranslater->loadLabelsFromTaxonomyIds($availableTaxonomyIds); 714 715 $results_presentation = new ilCheckboxGroupInputGUI($this->lng->txt('tst_results_tax_filters'), 'results_tax_filters'); 716 717 foreach ($availableTaxonomyIds as $taxonomyId) { 718 $results_presentation->addOption(new ilCheckboxOption( 719 $labelTranslater->getTaxonomyTreeLabel($taxonomyId), 720 $taxonomyId, 721 '' 722 )); 723 } 724 725 $results_presentation->setValue($this->testOBJ->getResultFilterTaxIds()); 726 727 $form->addItem($results_presentation); 728 } 729 } 730 } 731 732 /** 733 * @param ilPropertyFormGUI $form 734 */ 735 private function saveResultMiscOptionsSettings(ilPropertyFormGUI $form) 736 { 737 // result filter taxonomies 738 if ($this->testQuestionSetConfigFactory->getQuestionSetConfig()->isResultTaxonomyFilterSupported()) { 739 if (!$this->isHiddenFormItem('results_tax_filters') && count($this->getAvailableTaxonomyIds())) { 740 $taxFilters = array(); 741 742 if (is_array($form->getItemByPostVar('results_tax_filters')->getValue())) { 743 $taxFilters = array_intersect( 744 $this->getAvailableTaxonomyIds(), 745 $form->getItemByPostVar('results_tax_filters')->getValue() 746 ); 747 } 748 749 $this->testOBJ->setResultFilterTaxIds($taxFilters); 750 } 751 } 752 } 753 754 private function isScoreReportingAvailable() 755 { 756 if (!$this->testOBJ->getScoreReporting()) { 757 return false; 758 } 759 760 if ( 761 $this->testOBJ->getScoreReporting() == ilObjTest::SCORE_REPORTING_DATE 762 && $this->testOBJ->getReportingDate() > time() 763 ) { 764 return false; 765 } 766 767 return true; 768 } 769 770 private function areScoringSettingsWritable() 771 { 772 if (!$this->testOBJ->participantDataExist()) { 773 return true; 774 } 775 776 if (!$this->isScoreReportingAvailable()) { 777 return true; 778 } 779 780 return false; 781 } 782 783 private function isScoreRecalculationRequired(ilPropertyFormGUI $form) 784 { 785 if (!$this->testOBJ->participantDataExist()) { 786 return false; 787 } 788 789 if (!$this->areScoringSettingsWritable()) { 790 return false; 791 } 792 793 if (!$this->hasScoringSettingsChanged($form)) { 794 return false; 795 } 796 797 return true; 798 } 799 800 private function hasScoringSettingsChanged(ilPropertyFormGUI $form) 801 { 802 $countSystem = $form->getItemByPostVar('count_system'); 803 if (is_object($countSystem) && $countSystem->getValue() != $this->testOBJ->getCountSystem()) { 804 return true; 805 } 806 807 $mcScoring = $form->getItemByPostVar('mc_scoring'); 808 if (is_object($mcScoring) && $mcScoring->getValue() != $this->testOBJ->getMCScoring()) { 809 return true; 810 } 811 812 $scoreCutting = $form->getItemByPostVar('score_cutting'); 813 if (is_object($scoreCutting) && $scoreCutting->getValue() != $this->testOBJ->getScoreCutting()) { 814 return true; 815 } 816 817 $passScoring = $form->getItemByPostVar('pass_scoring'); 818 if (is_object($passScoring) && $passScoring->getValue() != $this->testOBJ->getPassScoring()) { 819 return true; 820 } 821 822 return false; 823 } 824 825 private $availableTaxonomyIds = null; 826 827 private function getAvailableTaxonomyIds() 828 { 829 if ($this->getAvailableTaxonomyIds === null) { 830 require_once 'Services/Taxonomy/classes/class.ilObjTaxonomy.php'; 831 $this->availableTaxonomyIds = (array) ilObjTaxonomy::getUsageOfObject($this->testOBJ->getId()); 832 } 833 834 return $this->availableTaxonomyIds; 835 } 836} 837