Skip to content

Commit 61bb2c7

Browse files
committed
Test: Don't Recalc All Results On Single Change
See: https://mantis.ilias.de/view.php?id=48302
1 parent 2949396 commit 61bb2c7

7 files changed

Lines changed: 91 additions & 118 deletions

File tree

components/ILIAS/Test/classes/class.ilObjTest.php

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,8 +1023,7 @@ public function removeQuestionsWithResults(array $question_ids): void
10231023
$scoring = new TestScoring(
10241024
$this,
10251025
$this->user,
1026-
$this->db,
1027-
$this->lng
1026+
$this->db
10281027
);
10291028

10301029
array_walk(
@@ -4050,7 +4049,11 @@ public function onMarkSchemaSaved(): void
40504049
$this->saveCompleteStatus($this->question_set_config_factory->getQuestionSetConfig());
40514050

40524051
if ($this->participantDataExist()) {
4053-
$this->recalculateScores(true);
4052+
(new TestScoring(
4053+
$this,
4054+
$this->user,
4055+
$this->db
4056+
))->recalculateSolutions();
40544057
}
40554058
}
40564059

@@ -7208,13 +7211,6 @@ public function participantDataExist(): bool
72087211
return $this->participantDataExist;
72097212
}
72107213

7211-
public function recalculateScores($preserve_manscoring = false)
7212-
{
7213-
$scoring = new TestScoring($this, $this->user, $this->db, $this->lng);
7214-
$scoring->setPreserveManualScores($preserve_manscoring);
7215-
$scoring->recalculateSolutions();
7216-
}
7217-
72187214
public static function getTestObjIdsWithActiveForUserId($userId): array
72197215
{
72207216
global $DIC;

components/ILIAS/Test/classes/class.ilTestCorrectionsGUI.php

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -101,12 +101,12 @@ protected function buildQuestionCorrectionForm(assQuestionGUI $question_gui): il
101101
$scoring = new TestScoring(
102102
$this->test_obj,
103103
$this->scorer,
104-
$this->database,
105-
$this->language
104+
$this->database
106105
);
107-
$scoring->setQuestionId($question_gui->getObject()->getId());
108106

109-
if ($scoring->getNumManualScorings()) {
107+
if ($scoring->getNumManualScorings(
108+
$question_gui->getObject()->getId()
109+
)) {
110110
$form->addCommandButton('confirmManualScoringReset', $this->language->txt('save'));
111111
} else {
112112
$form->addCommandButton('saveQuestion', $this->language->txt('save'));
@@ -122,14 +122,14 @@ protected function confirmManualScoringReset()
122122
$scoring = new TestScoring(
123123
$this->test_obj,
124124
$this->scorer,
125-
$this->database,
126-
$this->language
125+
$this->database
127126
);
128-
$scoring->setQuestionId($this->question_gui->getObject()->getId());
129127

130128
$confirmation = sprintf(
131129
$this->language->txt('tst_corrections_manscore_reset_warning'),
132-
$scoring->getNumManualScorings(),
130+
$scoring->getNumManualScorings(
131+
$this->question_gui->getObject()->getId()
132+
),
133133
$this->question_gui->getObject()->getTitleForHTMLOutput(),
134134
$this->question_gui->getObject()->getId()
135135
);
@@ -164,15 +164,14 @@ protected function saveQuestion()
164164
$question_gui->setObject($question);
165165
$question_gui->getObject()->saveToDb();
166166

167-
$scoring = new TestScoring(
167+
(new TestScoring(
168168
$this->test_obj,
169169
$this->scorer,
170-
$this->database,
171-
$this->language
170+
$this->database
171+
))->recalculateSolutions(
172+
false,
173+
$question_gui->getObject()->getId()
172174
);
173-
$scoring->setPreserveManualScores(false);
174-
$scoring->setQuestionId($question_gui->getObject()->getId());
175-
$scoring->recalculateSolutions();
176175

177176
if ($this->logger->isLoggingEnabled()) {
178177
$this->logger->logQuestionAdministrationInteraction(
@@ -290,15 +289,11 @@ protected function addAnswer()
290289
$question->saveToDb();
291290
}
292291

293-
$scoring = new TestScoring(
292+
$participant_results = (new TestScoring(
294293
$this->test_obj,
295294
$this->scorer,
296-
$this->database,
297-
$this->language
298-
);
299-
$scoring->setPreserveManualScores(true);
300-
$scoring->setQuestionId($question_index);
301-
$participant_results = $scoring->recalculateSolutions();
295+
$this->database
296+
))->recalculateSolutions(true, $question_index);
302297

303298
if ($this->logger->isLoggingEnabled()) {
304299
$this->logger->logQuestionAdministrationInteraction(

components/ILIAS/Test/classes/class.ilTestExportGUI.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ public function createTestArchiveExport()
153153
$test_ref
154154
);
155155

156-
$scoring = new TestScoring($this->obj, $this->user, $this->db, $this->lng);
156+
$scoring = new TestScoring($this->obj, $this->user, $this->db);
157157
$best_solution = $scoring->calculateBestSolutionForTest();
158158

159159
$tmpFileName = ilFileUtils::ilTempnam();

components/ILIAS/Test/src/Scoring/Manual/TestScoring.php

Lines changed: 56 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,6 @@
4444
*/
4545
class TestScoring
4646
{
47-
private bool $preserve_manual_scores = false;
48-
private int $question_id = 0;
4947
private \ilTestEvaluationFactory $evaluation_factory;
5048

5149
/**
@@ -56,39 +54,25 @@ class TestScoring
5654
public function __construct(
5755
private \ilObjTest $test,
5856
private \ilObjUser $scorer,
59-
private \ilDBInterface $db,
60-
private \ilLanguage $lng
57+
private \ilDBInterface $db
6158
) {
6259
$this->evaluation_factory = new \ilTestEvaluationFactory($this->db, $this->test);
6360
}
6461

65-
public function setPreserveManualScores(bool $preserve_manual_scores): void
66-
{
67-
$this->preserve_manual_scores = $preserve_manual_scores;
68-
}
69-
70-
public function getPreserveManualScores(): bool
71-
{
72-
return $this->preserve_manual_scores;
73-
}
74-
75-
public function getQuestionId(): int
76-
{
77-
return $this->question_id;
78-
}
79-
80-
public function setQuestionId(int $question_id): void
81-
{
82-
$this->question_id = $question_id;
83-
}
84-
85-
public function recalculateSolutions(): array
86-
{
62+
public function recalculateSolutions(
63+
bool $preserve_manual_scoring = false,
64+
?int $question_id = null
65+
): array {
8766
$participants = $this->evaluation_factory->getCorrectionsEvaluationData()->getParticipants();
8867

8968
foreach ($participants as $active_id => $userdata) {
9069
if ($userdata instanceof \ilTestEvaluationUserData) {
91-
$this->recalculatePasses($userdata, $active_id);
70+
$this->recalculatePasses(
71+
$userdata,
72+
$active_id,
73+
$preserve_manual_scoring,
74+
$question_id
75+
);
9276
\ilLPStatusWrapper::_updateStatus($this->test->getId(), $userdata->getUserID());
9377
}
9478
}
@@ -108,16 +92,29 @@ public function recalculateSolution(int $active_id, int $pass): void
10892
$user_data->getPass($pass),
10993
$user_data->getUserID(),
11094
$active_id,
111-
$pass
95+
$pass,
96+
true,
97+
null
11298
);
11399
$this->test->updateTestResultCache($active_id);
114100
}
115101

116-
private function recalculatePasses(\ilTestEvaluationUserData $userdata, int $active_id): void
117-
{
102+
private function recalculatePasses(
103+
\ilTestEvaluationUserData $userdata,
104+
int $active_id,
105+
bool $preserve_manual_scoring,
106+
?int $question_id
107+
): void {
118108
foreach ($userdata->getPasses() as $pass => $passdata) {
119109
if ($passdata instanceof \ilTestEvaluationPassData) {
120-
$this->recalculatePass($passdata, $userdata->getUserID(), $active_id, $pass);
110+
$this->recalculatePass(
111+
$passdata,
112+
$userdata->getUserID(),
113+
$active_id,
114+
$pass,
115+
$preserve_manual_scoring,
116+
$question_id
117+
);
121118
}
122119
}
123120
$this->test->updateTestResultCache($active_id);
@@ -127,11 +124,15 @@ private function recalculatePass(
127124
\ilTestEvaluationPassData $passdata,
128125
int $user_id,
129126
int $active_id,
130-
int $pass
127+
int $pass,
128+
bool $preserve_manual_scoring,
129+
?int $question_id
131130
): void {
132131
$reached_points_changed = false;
133132
foreach ($passdata->getAnsweredQuestions() as $question_data) {
134-
if ($this->getQuestionId() !== 0 || $this->getQuestionId() === $question_data['id']) {
133+
if ($question_id === null && $question_data['manual'] !== 1
134+
|| $question_id === $question_data['id']
135+
&& (!$preserve_manual_scoring || $question_data['manual'] !== 1)) {
135136
$reached_points_changed = $this->recalculateQuestionScore(
136137
$user_id,
137138
$active_id,
@@ -149,10 +150,6 @@ private function recalculateQuestionScore(
149150
int $pass,
150151
array $questiondata
151152
): bool {
152-
if ($this->preserve_manual_scores && $questiondata['manual'] === 1) {
153-
return false;
154-
}
155-
156153
$q_id = $questiondata['id'];
157154
$this->question_cache[$q_id] ??= $this->test->createQuestionGUI('', $q_id)->getObject();
158155
/** @var \assQuestion $question */
@@ -293,30 +290,28 @@ public function updatePassAndTestResults(array $active_ids): void
293290
}
294291
}
295292

296-
public function getNumManualScorings(): int
297-
{
298-
$query = "
299-
SELECT COUNT(*) num_manual_scorings
300-
FROM tst_test_result tres
301-
INNER JOIN tst_active tact
302-
ON tact.active_id = tres.active_fi
303-
WHERE tact.test_fi = %s
304-
AND tres.manual = 1
305-
";
306-
307-
$types = ['integer'];
308-
$values = [$this->test->getTestId()];
309-
310-
if ($this->getQuestionId()) {
311-
$query .= "
312-
AND tres.question_fi = %s
313-
";
314-
315-
$types[] = 'integer';
316-
$values[] = $this->getQuestionId();
317-
}
318-
319-
$res = $this->db->queryF($query, $types, $values);
293+
public function getNumManualScorings(
294+
int $question_id
295+
): int {
296+
$res = $this->db->queryF(
297+
"
298+
SELECT COUNT(*) num_manual_scorings
299+
FROM tst_test_result tres
300+
INNER JOIN tst_active tact
301+
ON tact.active_id = tres.active_fi
302+
WHERE tact.test_fi = %s
303+
AND tres.manual = 1
304+
AND tres.question_fi = %s
305+
",
306+
[
307+
\ilDBConstants::T_INTEGER,
308+
\ilDBConstants::T_INTEGER
309+
],
310+
[
311+
$this->test->getTestId(),
312+
$question_id
313+
]
314+
);
320315

321316
while ($row = $this->db->fetchAssoc($res)) {
322317
return (int) $row['num_manual_scorings'];

components/ILIAS/Test/src/Scoring/Manual/class.TestScoringByParticipantGUI.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -329,9 +329,11 @@ private function saveManScoringParticipantScreen(bool $redirect = true): bool
329329
$notification->send();
330330
}
331331

332-
$scorer = new TestScoring($this->object, $this->user, $this->db, $this->lng);
333-
$scorer->setPreserveManualScores(true);
334-
$scorer->recalculateSolution($active_id, $attempt);
332+
(new TestScoring(
333+
$this->object,
334+
$this->user,
335+
$this->db
336+
))->recalculateSolution($active_id, $attempt);
335337

336338
if ($this->object->getAnonymity() == 0) {
337339
$user_name = \ilObjUser::_lookupName(\ilObjTestAccess::_getParticipantId($active_id));

components/ILIAS/Test/src/Settings/ScoreReporting/class.SettingsScoringGUI.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,15 @@
2121
namespace ILIAS\Test\Settings\ScoreReporting;
2222

2323
use ILIAS\Test\Settings\TestSettingsGUI;
24+
use ILIAS\Test\Scoring\Manual\TestScoring;
2425
use ILIAS\Test\Scoring\Settings\Settings as SettingsScoring;
2526
use ILIAS\Test\Logging\TestLogger;
2627
use ILIAS\Test\Logging\TestAdministrationInteractionTypes;
2728
use ILIAS\Test\Presentation\TabsManager;
2829
use ILIAS\UI\Factory as UIFactory;
2930
use ILIAS\UI\Renderer as UIRenderer;
3031
use ILIAS\Refinery\Factory as Refinery;
31-
use ILIAS\Data\Factory as DataFactory;
3232
use ILIAS\UI\Component\Input\Container\Form\Form;
33-
use ilInfoScreenGUI;
34-
use ilObjTestGUI;
3533
use Psr\Http\Message\ServerRequestInterface as Request;
3634

3735
/**
@@ -116,7 +114,11 @@ public function executeCommand()
116114
->withRequest($this->getRelayedRequest())
117115
->getData();
118116
$this->storeScoreSettings($settings);
119-
$this->test_object->recalculateScores(true);
117+
(new TestScoring(
118+
$this,
119+
$this->user,
120+
$this->db
121+
))->recalculateSolutions();
120122
$this->tpl->setOnScreenMessage('success', $this->lng->txt("msg_score_settings_modified_and_recalc"), true);
121123
$this->ctrl->redirect($this, self::CMD_SHOW_FORM);
122124
break;

components/ILIAS/Test/tests/TestScoringTest.php

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -35,29 +35,12 @@ protected function setUp(): void
3535
$this->testObj = new TestScoring(
3636
$this->getTestObjMock(),
3737
$this->createMock(ilObjUser::class),
38-
$this->createMock(ilDBInterface::class),
39-
$this->createMock(ilLanguage::class)
38+
$this->createMock(ilDBInterface::class)
4039
);
4140
}
4241

4342
public function test_instantiateObject_shouldReturnInstance(): void
4443
{
4544
$this->assertInstanceOf(TestScoring::class, $this->testObj);
4645
}
47-
48-
public function testPreserveManualScores(): void
49-
{
50-
$this->testObj->setPreserveManualScores(false);
51-
$this->assertFalse($this->testObj->getPreserveManualScores());
52-
53-
$this->testObj->setPreserveManualScores(true);
54-
$this->assertTrue($this->testObj->getPreserveManualScores());
55-
}
56-
57-
public function testQuestionId(): void
58-
{
59-
$questionId = 20;
60-
$this->testObj->setQuestionId($questionId);
61-
$this->assertEquals($questionId, $this->testObj->getQuestionId());
62-
}
6346
}

0 commit comments

Comments
 (0)