19 declare(strict_types=1);
32 private \ilDBInterface
$db;
39 return 'Update test attempt results on manual scoring after 1st of May 2024. We do this in one step to avoid creating tables and this might take a while.';
50 new \ilDatabaseInitializedObjective(),
51 new \ilSettingsFactoryExistsObjective()
60 ->settingsFor(
'assessment');
61 $this->manual_scoring_enabled = $this->
settings->get(
'assessment_manual_scoring',
'') !==
'';
62 $this->migration_already_run = $this->
settings->get(self::MIGRATION_ALLREADY_RUN_SETTING,
'0') ===
'1';
70 if (!$this->manual_scoring_enabled) {
74 $result = $this->db->query(
75 'SELECT DISTINCT(active_fi), pass, question_set_type, (SELECT MAX(tstamp) FROM ' 76 . self::TABLE_NAME .
' ms2 WHERE ms1.active_fi = ms2.active_fi) tstamp FROM ' 77 . self::TABLE_NAME .
' ms1 ' 78 .
'INNER JOIN tst_active ta ON ms1.active_fi = ta.active_id ' 79 .
'INNER JOIN tst_tests tt ON ta.test_fi = tt.test_id ' 83 while (($row = $this->db->fetchObject($result))) {
84 if ($row->tstamp <= self::START_DATE) {
91 $this->
settings->set(self::MIGRATION_ALLREADY_RUN_SETTING,
'1');
96 if (!$this->manual_scoring_enabled || $this->migration_already_run) {
107 $result = $this->db->queryF(
108 'SELECT SUM(points) reachedpoints, 109 SUM(hint_count) hint_count, 110 SUM(hint_points) hint_points, 111 COUNT(DISTINCT(question_fi)) answeredquestions 115 [
'integer',
'integer'],
119 $row = $this->db->fetchAssoc($result);
121 if ($row[
'reachedpoints'] === null
122 || $row[
'reachedpoints'] < 0.0) {
123 $row[
'reachedpoints'] = 0.0;
125 if ($row[
'hint_count'] === null) {
126 $row[
'hint_count'] = 0;
128 if ($row[
'hint_points'] === null) {
129 $row[
'hint_points'] = 0.0;
137 'active_fi' => [
'integer', $active_id],
138 'pass' => [
'integer', $pass]
141 'points' => [
'float', $row[
'reachedpoints']],
142 'maxpoints' => [
'float',
$data[
'points']],
143 'questioncount' => [
'integer',
$data[
'count']],
144 'answeredquestions' => [
'integer', $row[
'answeredquestions']],
145 'tstamp' => [
'integer', time()],
146 'hint_count' => [
'integer', $row[
'hint_count']],
147 'hint_points' => [
'float', $row[
'hint_points']]
157 SELECT tst_pass_result.*, 158 tst_active.last_finished_pass, 161 INNER JOIN tst_active 162 on tst_pass_result.active_fi = tst_active.active_id 167 $result = $this->db->queryF(
169 [
'integer',
'integer'],
173 $test_pass_result_row = $this->db->fetchAssoc($result);
175 if (!is_array($test_pass_result_row)) {
176 $test_pass_result_row = [];
178 $max = (float) ($test_pass_result_row[
'maxpoints'] ?? 0);
179 $reached = (float) ($test_pass_result_row[
'points'] ?? 0);
180 $percentage = ($max <= 0.0 || $reached <= 0.0) ? 0 : ($reached / $max) * 100.0;
181 $obligations_answered = (
int) ($test_pass_result_row[
'obligations_answered'] ?? 1);
183 $mark_schema = new \ASS_MarkSchema($this->db,
new class (
'en') extends \
ilLanguage {
188 $mark_schema->loadFromDb($test_pass_result_row[
'test_fi']);
189 $mark = $mark_schema->getMatchingMark($percentage);
190 $is_passed = $pass <= $test_pass_result_row[
'last_finished_pass'] && $mark->getPassed();
192 $hint_count = $test_pass_result_row[
'hint_count'] ?? 0;
193 $hint_points = $test_pass_result_row[
'hint_points'] ?? 0.0;
195 $passed_once_before = 0;
196 $query =
'SELECT passed_once FROM tst_result_cache WHERE active_fi = %s';
197 $res = $this->db->queryF($query, [
'integer'], [$active_id]);
198 while ($passed_once_result_row = $this->db->fetchAssoc(
$res)) {
199 $passed_once_before = (
int) $passed_once_result_row[
'passed_once'];
202 $passed_once = (
int) ($is_passed || $passed_once_before);
204 $this->db->manipulateF(
205 'DELETE FROM tst_result_cache WHERE active_fi = %s',
210 if ($reached < 0.0) {
214 $mark_short_name = $mark->getShortName();
215 if ($mark_short_name ===
'') {
216 $mark_short_name =
' ';
219 $mark_official_name = $mark->getOfficialName();
220 if ($mark_official_name ===
'') {
221 $mark_official_name =
' ';
227 'active_fi' => [
'integer', $active_id],
228 'pass' => [
'integer', $pass ?? 0],
229 'max_points' => [
'float', $max],
230 'reached_points' => [
'float', $reached],
231 'mark_short' => [
'text', $mark_short_name],
232 'mark_official' => [
'text', $mark_official_name],
233 'passed_once' => [
'integer', $passed_once],
234 'passed' => [
'integer', (
int) $is_passed],
235 'failed' => [
'integer', (
int) !$is_passed],
236 'tstamp' => [
'integer', time()],
237 'hint_count' => [
'integer', $hint_count],
238 'hint_points' => [
'float', $hint_points],
239 'obligations_answered' => [
'integer', $obligations_answered]
246 $res = $this->db->queryF(
248 SELECT tst_test_rnd_qst.pass, 249 COUNT(tst_test_rnd_qst.question_fi) qcount, 250 SUM(qpl_questions.points) qsum 252 FROM tst_test_rnd_qst, 255 WHERE tst_test_rnd_qst.question_fi = qpl_questions.question_id 256 AND tst_test_rnd_qst.active_fi = %s 259 GROUP BY tst_test_rnd_qst.active_fi, 260 tst_test_rnd_qst.pass 262 [
'integer',
'integer'],
266 $row = $this->db->fetchAssoc(
$res);
268 if (is_array($row)) {
269 return [
"count" => $row[
"qcount"],
"points" => $row[
"qsum"]];
272 return [
"count" => 0,
"points" => 0];
const QUESTION_SET_TYPE_RANDOM
const MIGRATION_ALLREADY_RUN_SETTING
bool $manual_scoring_enabled
A migration is a potentially long lasting operation that can be broken into discrete steps...
step(Environment $environment)
prepare(Environment $environment)
Prepare the migration by means of some environment.
getPreconditions(Environment $environment)
Objectives the migration depend on.
bool $migration_already_run
__construct()
Constructor setup ILIAS global object public.
getResource(string $id)
Consumers of this method should check if the result is what they expect, e.g.
updateTestPassResults(int $active_id, int $pass)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
getDefaultAmountOfStepsPerRun()
Tell the default amount of steps to be executed for one run of the migration.
An environment holds resources to be used in the setup process.
getQuestionCountAndPointsForPassOfParticipant($active_id, $pass)
const RESOURCE_SETTINGS_FACTORY
getRemainingAmountOfSteps()
Count up how many "things" need to be migrated.
updateTestResultCache(int $active_id, int $pass)