ILIAS  release_9 Revision v9.13-25-g2c18ec4c24f
class.ilPageQuestionProcessor.php
Go to the documentation of this file.
1 <?php
2 
25 {
26  public function __construct()
27  {
28  }
29 
30 
31  public static function saveQuestionAnswer(
32  string $a_type,
33  int $a_id,
34  string $a_answer
35  ): void {
36  global $DIC;
37 
38  $ilUser = $DIC->user();
39  $ilLog = $DIC["ilLog"];
40  $ilDB = $DIC->database();
41  $ilLog->write($a_type);
42  $ilLog->write($a_id);
43  $ilLog->write($a_answer);
44  $answer = json_decode($a_answer, false, 512, JSON_THROW_ON_ERROR);
45  $passed = $answer->passed;
46  $choice = $answer->choice ?? [];
47  $points = self::calculatePoints($a_type, $a_id, $choice);
48  $ilLog->write("Points: " . $points);
49 
50  $set = $ilDB->query(
51  "SELECT * FROM page_qst_answer WHERE " .
52  " qst_id = " . $ilDB->quote($a_id, "integer") . " AND " .
53  " user_id = " . $ilDB->quote($ilUser->getId(), "integer")
54  );
55 
56  // #15146
57  if (!$ilDB->fetchAssoc($set)) {
58  $ilDB->replace(
59  "page_qst_answer",
60  array(
61  "qst_id" => array("integer", $a_id),
62  "user_id" => array("integer", $ilUser->getId())
63  ),
64  array(
65  "try" => array("integer", 1),
66  "passed" => array("integer", $passed),
67  "points" => array("float", $points)
68  )
69  );
70  } else {
71  $ilDB->manipulate(
72  "UPDATE page_qst_answer SET " .
73  " try = try + 1," .
74  " passed = " . $ilDB->quote($passed, "integer") . "," .
75  " points = " . $ilDB->quote($points, "float") .
76  " WHERE qst_id = " . $ilDB->quote($a_id, "integer") .
77  " AND user_id = " . $ilDB->quote($ilUser->getId(), "integer")
78  );
79  }
80  }
81 
82  public static function getQuestionStatistics(
83  int $a_q_id
84  ): array {
85  global $DIC;
86 
87  $ilDB = $DIC->database();
88 
89  $set = $ilDB->query(
90  "SELECT count(user_id) usr_cnt FROM page_qst_answer WHERE " .
91  " qst_id = " . $ilDB->quote($a_q_id, "integer")
92  );
93  $rec = $ilDB->fetchAssoc($set);
94  $all = $rec["usr_cnt"];
95 
96  $first = false;
97  $second = false;
98  $third_or_more = false;
99 
100  if ($all > 0) {
101  $set = $ilDB->query(
102  "SELECT count(user_id) usr_cnt FROM page_qst_answer WHERE " .
103  " qst_id = " . $ilDB->quote($a_q_id, "integer") . " AND " .
104  " passed = " . $ilDB->quote(1, "integer") . " AND " .
105  " try = " . $ilDB->quote(1, "integer")
106  );
107  $rec = $ilDB->fetchAssoc($set);
108  $first = $rec["usr_cnt"];
109 
110  $set = $ilDB->query(
111  "SELECT count(user_id) usr_cnt FROM page_qst_answer WHERE " .
112  " qst_id = " . $ilDB->quote($a_q_id, "integer") . " AND " .
113  " passed = " . $ilDB->quote(1, "integer") . " AND " .
114  " try = " . $ilDB->quote(2, "integer")
115  );
116  $rec = $ilDB->fetchAssoc($set);
117  $second = $rec["usr_cnt"];
118 
119  $set = $ilDB->query(
120  $q = "SELECT count(user_id) usr_cnt FROM page_qst_answer WHERE " .
121  " qst_id = " . $ilDB->quote($a_q_id, "integer") . " AND " .
122  " passed = " . $ilDB->quote(1, "integer") . " AND " .
123  " try >= " . $ilDB->quote(3, "integer")
124  );
125  $rec = $ilDB->fetchAssoc($set);
126  $third_or_more = $rec["usr_cnt"];
127  }
128 
129  return array("all" => $all, "first" => $first, "second" => $second, "third_or_more" => $third_or_more);
130  }
131 
139  public static function calculatePoints(
140  string $a_type,
141  int $a_id,
142  array $a_choice
143  ): int {
144  $points = 0;
145 
146  switch ($a_type) {
147  case "assSingleChoice":
148  $q = new assSingleChoice();
149  $q->loadFromDb($a_id);
150  $points = 0;
151  foreach ($q->getAnswers() as $key => $answer) {
152  if (isset($a_choice[0]) && $key == $a_choice[0]) {
153  $points += $answer->getPoints();
154  }
155  }
156  break;
157 
158  case "assMultipleChoice":
159  $q = new assMultipleChoice();
160  $q->loadFromDb($a_id);
161  $points = 0;
162  foreach ($q->getAnswers() as $key => $answer) {
163  if (is_array($a_choice) && in_array($key, $a_choice)) {
164  $points += $answer->getPoints();
165  } else {
166  $points += $answer->getPointsUnchecked();
167  }
168  }
169  break;
170 
171  case "assClozeTest":
172  $q = new assClozeTest();
173  $q->loadFromDb($a_id);
174  $points = 0;
175  foreach ($q->getGaps() as $id => $gap) {
176  $choice = $a_choice[$id];
177  switch ($gap->getType()) {
178  case CLOZE_TEXT:
179  $gappoints = 0;
180  for ($order = 0; $order < $gap->getItemCount(); $order++) {
181  $answer = $gap->getItem($order);
182  $gotpoints = $q->getTextgapPoints(
183  $answer->getAnswertext(),
184  $choice,
185  $answer->getPoints()
186  );
187  if ($gotpoints > $gappoints) {
188  $gappoints = $gotpoints;
189  }
190  }
191  $points += $gappoints;
192  //$ilLog->write("ct: ".$gappoints);
193  break;
194 
195  case CLOZE_NUMERIC:
196  $gappoints = 0;
197  for ($order = 0; $order < $gap->getItemCount(); $order++) {
198  $answer = $gap->getItem($order);
199  $gotpoints = $q->getNumericgapPoints(
200  $answer->getAnswertext(),
201  $choice,
202  $answer->getPoints(),
203  $answer->getLowerBound(),
204  $answer->getUpperBound()
205  );
206  if ($gotpoints > $gappoints) {
207  $gappoints = $gotpoints;
208  }
209  }
210  $points += $gappoints;
211  //$ilLog->write("cn: ".$gappoints);
212  break;
213 
214  case CLOZE_SELECT:
215  for ($order = 0; $order < $gap->getItemCount(); $order++) {
216  $answer = $gap->getItem($order);
217  if ($choice == $answer->getOrder()) {
218  $answerpoints = $answer->getPoints();
219  $points += $answerpoints;
220  //$ilLog->write("cs: ".$answerpoints);
221  }
222  }
223  break;
224  }
225  }
226  break;
227 
228  case "assMatchingQuestion":
229  $q = new assMatchingQuestion();
230  $q->loadFromDb($a_id);
231  $points = 0;
232  for ($i = 0; $i < $q->getMatchingPairCount(); $i++) {
233  $pair = $q->getMatchingPair($i);
234  if (is_array($a_choice) && in_array($pair->getDefinition()->getIdentifier() . "-" . $pair->getTerm()->getIdentifier(), $a_choice)) {
235  $points += $pair->points;
236  }
237  }
238  break;
239 
240  case "assOrderingQuestion":
241 
242  // TODO-LSD: change calculation strategy according to lsd cleanup changes
243 
244  $q = new assOrderingQuestion();
245  $q->loadFromDb($a_id);
246  $points = 0;
247  $cnt = 1;
248  $right = true;
249  foreach ($q->getOrderElements() as $answer) {
250  if ($a_choice[$cnt - 1] != $cnt) {
251  $right = false;
252  }
253  $cnt++;
254  }
255  if ($right) {
256  $points = $q->getPoints();
257  }
258  break;
259 
260  case "assImagemapQuestion":
261  $q = new assImagemapQuestion();
262  $q->loadFromDb($a_id);
263  $points = 0;
264 
265  foreach ($q->getAnswers() as $key => $answer) {
266  if (is_array($a_choice) && in_array($key, $a_choice)) {
267  $points += $answer->getPoints();
268  }
269  }
270  break;
271  }
272 
273  if ($points < 0) {
274  $points = 0;
275  }
276 
277  return (int) $points;
278  }
279 
283  public static function getAnswerStatus(
284  $a_q_id,
285  int $a_user_id = 0
286  ): array {
287  global $DIC;
288 
289  $ilDB = $DIC->database();
290 
291  $qst = (is_array($a_q_id))
292  ? $ilDB->in("qst_id", $a_q_id, false, "integer")
293  : " qst_id = " . $ilDB->quote($a_q_id, "integer");
294 
295  $and = ($a_user_id > 0)
296  ? " AND user_id = " . $ilDB->quote($a_user_id, "integer")
297  : "";
298 
299  $set = $ilDB->query(
300  "SELECT * FROM page_qst_answer WHERE " .
301  $qst .
302  $and
303  );
304 
305  if (is_array($a_q_id) || $a_user_id == 0) {
306  $recs = array();
307  while ($rec = $ilDB->fetchAssoc($set)) {
308  $key = ($a_user_id == 0)
309  ? $rec["qst_id"] . ":" . $rec["user_id"]
310  : $rec["qst_id"];
311  $recs[$key] = $rec;
312  }
313  return $recs;
314  }
315 
316  if ($rec = $ilDB->fetchAssoc($set)) {
317  return $rec;
318  }
319  return [
320  "try" => 0,
321  "passed" => false
322  ];
323  }
324 
328  public static function resetTries(
329  int $a_q_id,
330  int $a_user_id
331  ): void {
332  global $DIC;
333 
334  $ilDB = $DIC->database();
335 
336  $ilDB->manipulate(
337  $q = "UPDATE page_qst_answer SET " .
338  " try = " . $ilDB->quote(0, "integer") . "," .
339  " passed = " . $ilDB->quote(0, "integer") . "," .
340  " points = " . $ilDB->quote(0, "integer") . "," .
341  " unlocked = " . $ilDB->quote(0, "integer") .
342  " WHERE qst_id = " . $ilDB->quote($a_q_id, "integer") .
343  " AND user_id = " . $ilDB->quote($a_user_id, "integer")
344  );
345  }
346 
350  public static function unlock(
351  int $a_q_id,
352  int $a_user_id
353  ): void {
354  global $DIC;
355 
356  $ilDB = $DIC->database();
357 
358  $ilDB->manipulate(
359  $q = "UPDATE page_qst_answer SET " .
360  " unlocked = " . $ilDB->quote(1, "integer") .
361  " WHERE qst_id = " . $ilDB->quote($a_q_id, "integer") .
362  " AND user_id = " . $ilDB->quote($a_user_id, "integer")
363  );
364  }
365 }
static resetTries(int $a_q_id, int $a_user_id)
Reset tries for user and question.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
const CLOZE_TEXT
Cloze question constants.
static getAnswerStatus( $a_q_id, int $a_user_id=0)
static saveQuestionAnswer(string $a_type, int $a_id, string $a_answer)
Class for multiple choice tests.
Class for matching questions.
global $DIC
Definition: feed.php:28
const CLOZE_SELECT
Class for single choice questions.
string $key
Consumer key/client ID value.
Definition: System.php:193
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static unlock(int $a_q_id, int $a_user_id)
Unlock question for user.
static calculatePoints(string $a_type, int $a_id, array $a_choice)
Calculate points.
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
$q
Definition: shib_logout.php:21
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
const CLOZE_NUMERIC