ILIAS  trunk Revision v11.0_alpha-1689-g66c127b4ae8
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
class.ilAssQuestionUserSolutionAdopter.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
28 {
35 
37  private ?int $user_id = null;
38  protected ?int $active_id = null;
39  protected ?int $target_pass = null;
40 
44  protected array $question_ids = [];
45 
46  public function __construct(
47  private ilDBInterface $db,
48  ilSetting $ass_settings
49  ) {
50  $this->process_locker_factory = new ilAssQuestionProcessLockerFactory($ass_settings, $db);
51  }
52 
53  public function getUserId(): ?int
54  {
55  return $this->user_id;
56  }
57 
58  public function setUserId(int $user_id): void
59  {
60  $this->user_id = $user_id;
61  }
62 
63  public function getActiveId(): ?int
64  {
65  return $this->active_id;
66  }
67 
68  public function setActiveId(int $active_id): void
69  {
70  $this->active_id = $active_id;
71  }
72 
73  public function getTargetPass(): ?int
74  {
75  return $this->target_pass;
76  }
77 
78  public function setTargetPass(int $target_pass): void
79  {
80  $this->target_pass = $target_pass;
81  }
82 
83  public function getQuestionIds(): array
84  {
85  return $this->question_ids;
86  }
87 
91  public function setQuestionIds(array $question_ids): void
92  {
93  $this->question_ids = $question_ids;
94  }
95 
96  public function perform(): void
97  {
98  $this->process_locker_factory->setUserId($this->getUserId());
99 
100  foreach ($this->getQuestionIds() as $question_id) {
101  $this->process_locker_factory->setQuestionId($question_id);
102  $processLocker = $this->process_locker_factory->getLocker();
103 
104  $processLocker->executeUserTestResultUpdateLockOperation(function () use ($question_id) {
105  $this->adoptQuestionAnswer($question_id);
106  });
107  }
108  }
109 
110  protected function adoptQuestionAnswer(int $question_id): void
111  {
112  $this->resetTargetSolution($question_id);
113  $this->resetTargetResult($question_id);
114 
115  $source_pass = $this->adoptSourceSolution($question_id);
116 
117  if ($source_pass !== null) {
118  $this->adoptSourceResult($question_id, $source_pass);
119  }
120  }
121 
122  protected function resetTargetSolution(int $question_id): void
123  {
124  $this->db->execute(
126  [$this->getActiveId(), $question_id, $this->getTargetPass()]
127  );
128  }
129 
130  protected function resetTargetResult(int $question_id): void
131  {
132  $this->db->execute(
134  [$this->getActiveId(), $question_id, $this->getTargetPass()]
135  );
136  }
137 
138  protected function adoptSourceSolution(int $question_id): ?int
139  {
140  $res = $this->db->execute(
142  [$this->getActiveId(), $question_id, $this->getTargetPass()]
143  );
144 
145  $source_pass = null;
146 
147  while ($row = $this->db->fetchAssoc($res)) {
148  if ($source_pass === null) {
149  $source_pass = $row['pass'];
150  } elseif ($row['pass'] < $source_pass) {
151  break;
152  }
153 
154  $solution_id = $this->db->nextId('tst_solutions');
155 
156  $this->db->execute($this->getPreparedInsertSolutionRecordStatement(), [
157  $solution_id, $this->getActiveId(), $question_id, $this->getTargetPass(), time(),
158  $row['points'], $row['value1'], $row['value2']
159  ]);
160  }
161 
162  return $source_pass;
163  }
164 
165  protected function adoptSourceResult(int $question_id, int $source_pass): void
166  {
167  $res = $this->db->execute(
169  [$this->getActiveId(), $question_id, $source_pass]
170  );
171 
172  $row = $this->db->fetchAssoc($res);
173 
174  $result_id = $this->db->nextId('tst_test_result');
175 
176  $this->db->execute($this->getPreparedInsertResultRecordStatement(), [
177  $result_id, $this->getActiveId(), $question_id, $this->getTargetPass(), time(),
178  $row['points'], $row['manual'], $row['hint_count'], $row['hint_points'], $row['answered']
179  ]);
180  }
181 
183  {
184  if (self::$prepared_delete_solution_records_statement === null) {
185  self::$prepared_delete_solution_records_statement = $this->db->prepareManip(
186  "DELETE FROM tst_solutions WHERE active_fi = ? AND question_fi = ? AND pass = ?",
187  ['integer', 'integer', 'integer']
188  );
189  }
190 
191  return self::$prepared_delete_solution_records_statement;
192  }
193 
195  {
196  if (self::$prepared_select_solution_records_statement === null) {
197  $query = "
198  SELECT pass, points, value1, value2 FROM tst_solutions
199  WHERE active_fi = ? AND question_fi = ? AND pass < ? ORDER BY pass DESC
200  ";
201 
202  self::$prepared_select_solution_records_statement = $this->db->prepare(
203  $query,
204  ['integer', 'integer', 'integer']
205  );
206  }
207 
208  return self::$prepared_select_solution_records_statement;
209  }
210 
212  {
213  if (self::$prepared_insert_solution_record_statement === null) {
214  $query = "
215  INSERT INTO tst_solutions (
216  solution_id, active_fi, question_fi, pass, tstamp, points, value1, value2
217  ) VALUES (
218  ?, ?, ?, ?, ?, ?, ?, ?
219  )
220  ";
221 
222  self::$prepared_insert_solution_record_statement = $this->db->prepareManip(
223  $query,
224  ['integer', 'integer', 'integer', 'integer', 'integer', 'integer', 'text', 'text']
225  );
226  }
227 
228  return self::$prepared_insert_solution_record_statement;
229  }
230 
232  {
233  if (self::$prepared_delete_result_record_statement === null) {
234  self::$prepared_delete_result_record_statement = $this->db->prepareManip(
235  "DELETE FROM tst_test_result WHERE active_fi = ? AND question_fi = ? AND pass = ?",
236  ['integer', 'integer', 'integer']
237  );
238  }
239 
240  return self::$prepared_delete_result_record_statement;
241  }
242 
244  {
245  if (self::$prepared_select_result_record_statement === null) {
246  $query = "
247  SELECT points, manual, hint_count, hint_points, answered FROM tst_test_result
248  WHERE active_fi = ? AND question_fi = ? AND pass = ?
249  ";
250 
251  self::$prepared_select_result_record_statement = $this->db->prepare(
252  $query,
253  ['integer', 'integer', 'integer']
254  );
255  }
256 
257  return self::$prepared_select_result_record_statement;
258  }
259 
261  {
262  if (self::$prepared_insert_result_record_statement === null) {
263  $query = "
264  INSERT INTO tst_test_result (
265  test_result_id, active_fi, question_fi, pass, tstamp,
266  points, manual, hint_count, hint_points, answered
267  ) VALUES (
268  ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
269  )
270  ";
271 
272  self::$prepared_insert_result_record_statement = $this->db->prepareManip(
273  $query,
274  ['integer', 'integer', 'integer', 'integer', 'integer', 'integer', 'integer', 'integer', 'integer', 'integer']
275  );
276  }
277 
278  return self::$prepared_insert_result_record_statement;
279  }
280 }
$res
Definition: ltiservices.php:66
adoptSourceResult(int $question_id, int $source_pass)
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
ilAssQuestionProcessLockerFactory $process_locker_factory
__construct(private ilDBInterface $db, ilSetting $ass_settings)