ILIAS  release_9 Revision v9.13-25-g2c18ec4c24f
class.assMarkSchema.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
21 require_once './Modules/Test/classes/inc.AssessmentConstants.php';
22 
34 {
35  public array $mark_steps;
36 
37  public function __construct(
38  protected ilDBInterface $db,
39  protected ilLanguage $lng,
40  protected int $current_user_id
41  ) {
42  $this->mark_steps = [];
43  }
44 
60  public function createSimpleSchema(
61  string $txt_failed_short = "failed",
62  string $txt_failed_official = "failed",
63  float $percentage_failed = 0,
64  int $failed_passed = 0,
65  string $txt_passed_short = "passed",
66  string $txt_passed_official = "passed",
67  float $percentage_passed = 50,
68  int $passed_passed = 1
69  ) {
70  $this->flush();
71  $this->addMarkStep($txt_failed_short, $txt_failed_official, $percentage_failed, $failed_passed);
72  $this->addMarkStep($txt_passed_short, $txt_passed_official, $percentage_passed, $passed_passed);
73  }
74 
86  public function addMarkStep(string $txt_short = "", string $txt_official = "", float $percentage = 0, int $passed = 0): void
87  {
88  $mark = new ASS_Mark($txt_short, $txt_official, $percentage, $passed);
89  array_push($this->mark_steps, $mark);
90  }
91 
92  public function saveToDb(int $test_id): void
93  {
94  $oldmarks = [];
96  $result = $this->db->queryF(
97  "SELECT * FROM tst_mark WHERE test_fi = %s ORDER BY minimum_level",
98  array('integer'),
99  array($test_id)
100  );
101  if ($result->numRows()) {
103  while ($row = $this->db->fetchAssoc($result)) {
104  $oldmarks[$row["minimum_level"]] = $row;
105  }
106  }
107  }
108 
109  if (!$test_id) {
110  return;
111  }
112  // Delete all entries
113  $this->db->manipulateF(
114  "DELETE FROM tst_mark WHERE test_fi = %s",
115  array('integer'),
116  array($test_id)
117  );
118  if (count($this->mark_steps) == 0) {
119  return;
120  }
121 
122  // Write new datasets
123  foreach ($this->mark_steps as $key => $value) {
124  $next_id = $this->db->nextId('tst_mark');
125  $this->db->manipulateF(
126  "INSERT INTO tst_mark (mark_id, test_fi, short_name, official_name, minimum_level, passed, tstamp) VALUES (%s, %s, %s, %s, %s, %s, %s)",
127  array('integer','integer','text','text','float','text','integer'),
128  array(
129  $next_id,
130  $test_id,
131  substr($value->getShortName(), 0, 15),
132  substr($value->getOfficialName(), 0, 50),
133  $value->getMinimumLevel(),
134  $value->getPassed(),
135  time()
136  )
137  );
138  }
140  $result = $this->db->queryF(
141  "SELECT * FROM tst_mark WHERE test_fi = %s ORDER BY minimum_level",
142  array('integer'),
143  array($test_id)
144  );
145  $newmarks = array();
146  if ($result->numRows()) {
148  while ($row = $this->db->fetchAssoc($result)) {
149  $newmarks[$row["minimum_level"]] = $row;
150  }
151  }
152  foreach ($oldmarks as $level => $row) {
153  if (array_key_exists($level, $newmarks)) {
154  $difffields = array();
155  foreach ($row as $key => $value) {
156  if ($value !== $newmarks[$level][$key]) {
157  switch ($key) {
158  case "mark_id":
159  case "tstamp":
160  break;
161  default:
162  array_push($difffields, "$key: $value => " . $newmarks[$level][$key]);
163  break;
164  }
165  }
166  }
167  if (count($difffields)) {
168  $this->logAction($test_id, $this->lng->txtlng("assessment", "log_mark_changed", ilObjAssessmentFolder::_getLogLanguage()) . ": " . join(", ", $difffields));
169  }
170  } else {
171  $this->logAction($test_id, $this->lng->txtlng("assessment", "log_mark_removed", ilObjAssessmentFolder::_getLogLanguage()) . ": " .
172  $this->lng->txtlng("assessment", "tst_mark_minimum_level", ilObjAssessmentFolder::_getLogLanguage()) . " = " . $row["minimum_level"] . ", " .
173  $this->lng->txtlng("assessment", "tst_mark_short_form", ilObjAssessmentFolder::_getLogLanguage()) . " = " . $row["short_name"] . ", " .
174  $this->lng->txtlng("assessment", "tst_mark_official_form", ilObjAssessmentFolder::_getLogLanguage()) . " = " . $row["official_name"] . ", " .
175  $this->lng->txtlng("assessment", "tst_mark_passed", ilObjAssessmentFolder::_getLogLanguage()) . " = " . $row["passed"]);
176  }
177  }
178  foreach ($newmarks as $level => $row) {
179  if (!array_key_exists($level, $oldmarks)) {
180  $this->logAction($test_id, $this->lng->txtlng("assessment", "log_mark_added", ilObjAssessmentFolder::_getLogLanguage()) . ": " .
181  $this->lng->txtlng("assessment", "tst_mark_minimum_level", ilObjAssessmentFolder::_getLogLanguage()) . " = " . $row["minimum_level"] . ", " .
182  $this->lng->txtlng("assessment", "tst_mark_short_form", ilObjAssessmentFolder::_getLogLanguage()) . " = " . $row["short_name"] . ", " .
183  $this->lng->txtlng("assessment", "tst_mark_official_form", ilObjAssessmentFolder::_getLogLanguage()) . " = " . $row["official_name"] . ", " .
184  $this->lng->txtlng("assessment", "tst_mark_passed", ilObjAssessmentFolder::_getLogLanguage()) . " = " . $row["passed"]);
185  }
186  }
187  }
188  }
189 
190  public function loadFromDb(int $test_id): void
191  {
192  if (!$test_id) {
193  return;
194  }
195  $result = $this->db->queryF(
196  "SELECT * FROM tst_mark WHERE test_fi = %s ORDER BY minimum_level",
197  array('integer'),
198  array($test_id)
199  );
200  if ($result->numRows() > 0) {
202  while ($data = $this->db->fetchAssoc($result)) {
203  $this->addMarkStep(
204  $data["short_name"] ?? '',
205  $data["official_name"] ?? '',
206  (float) $data["minimum_level"],
207  (int) $data["passed"]
208  );
209  }
210  }
211  }
212 
213  public function flush(): void
214  {
215  $this->mark_steps = array();
216  }
217 
223  public function sort(): void
224  {
225  function level_sort($a, $b): int
226  {
227  if ($a->getMinimumLevel() == $b->getMinimumLevel()) {
228  $res = strcmp($a->getShortName(), $b->getShortName());
229  if ($res == 0) {
230  return strcmp($a->getOfficialName(), $b->getOfficialName());
231  } else {
232  return $res;
233  }
234  }
235  return ($a->getMinimumLevel() < $b->getMinimumLevel()) ? -1 : 1;
236  }
237  usort($this->mark_steps, 'level_sort');
238  }
239 
247  public function deleteMarkStep($index = 0)
248  {
249  if ($index < 0) {
250  return;
251  }
252  if (count($this->mark_steps) < 1) {
253  return;
254  }
255  if ($index >= count($this->mark_steps)) {
256  return;
257  }
258  unset($this->mark_steps[$index]);
259  $this->mark_steps = array_values($this->mark_steps);
260  }
261 
266  public function deleteMarkSteps(array $indexes): void
267  {
268  foreach ($indexes as $key => $index) {
269  if (!(($index < 0) or (count($this->mark_steps) < 1))) {
270  unset($this->mark_steps[$index]);
271  }
272  }
273  $this->mark_steps = array_values($this->mark_steps);
274  }
275 
285  public function getMatchingMark($percentage)
286  {
287  for ($i = count($this->mark_steps) - 1; $i >= 0; $i--) {
288  $curMinLevel = $this->mark_steps[$i]->getMinimumLevel();
289  $reached = round($percentage, 2);
290  $level = round($curMinLevel, 2);
291  if ($reached >= $level) {
292  return $this->mark_steps[$i];
293  }
294  }
295  return false;
296  }
297 
305  public function checkMarks()
306  {
307  $minimum_percentage = 100;
308  $passed = 0;
309  for ($i = 0; $i < count($this->mark_steps); $i++) {
310  if ($this->mark_steps[$i]->getMinimumLevel() < $minimum_percentage) {
311  $minimum_percentage = $this->mark_steps[$i]->getMinimumLevel();
312  }
313  if ($this->mark_steps[$i]->getPassed()) {
314  $passed++;
315  }
316  }
317 
318  if ($minimum_percentage != 0) {
319  return "min_percentage_ne_0";
320  }
321 
322  if ($passed == 0) {
323  return "no_passed_mark";
324  }
325  return true;
326  }
327 
331  public function getMarkSteps(): array
332  {
333  return $this->mark_steps;
334  }
335 
339  public function setMarkSteps(array $mark_steps): void
340  {
341  $this->mark_steps = $mark_steps;
342  }
343 
347  public function logAction($test_id, string $logtext = ""): void
348  {
349  ilObjAssessmentFolder::_addLog($this->current_user_id, ilObjTest::_getObjectIDFromTestID($test_id), $logtext, "", "", true);
350  }
351 }
createSimpleSchema(string $txt_failed_short="failed", string $txt_failed_official="failed", float $percentage_failed=0, int $failed_passed=0, string $txt_passed_short="passed", string $txt_passed_official="passed", float $percentage_passed=50, int $passed_passed=1)
Creates a simple mark schema for two mark steps: failed and passed.
$res
Definition: ltiservices.php:69
static _addLog( $user_id, $object_id, $logtext, $question_id=0, $original_id=0, $test_only=false, $test_ref_id=0)
Add an assessment log entry.
static _getObjectIDFromTestID($test_id)
Returns the ILIAS test object id for a given test id.
sort()
Sorts the mark schema using the minimum level values.
A class defining marks for assessment test objects.
logAction($test_id, string $logtext="")
Logs an action into the Test&Assessment log.
$lng
saveToDb(int $test_id)
string $key
Consumer key/client ID value.
Definition: System.php:193
__construct(protected ilDBInterface $db, protected ilLanguage $lng, protected int $current_user_id)
deleteMarkSteps(array $indexes)
Deletes multiple mark steps using their index positions.
checkMarks()
Check the marks for consistency.
$a
thx to https://mlocati.github.io/php-cs-fixer-configurator for the examples
loadFromDb(int $test_id)
A class defining mark schemas for assessment test objects.
addMarkStep(string $txt_short="", string $txt_official="", float $percentage=0, int $passed=0)
Adds a mark step to the mark schema.
deleteMarkStep($index=0)
Deletes the mark step with a given index.
getMatchingMark($percentage)
Returns the matching mark for a given percentage.
setMarkSteps(array $mark_steps)