ILIAS  trunk Revision v11.0_alpha-1702-gfd3ecb7f852
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
class.ilTestResultsImportParser.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
22 
24 {
25  private $table;
28  private string $user_criteria_field = '';
29  private string $user_criteria_type = '';
30  private bool $user_criteria_checked = false;
31 
33 
37  public function __construct(
38  ?string $a_xml_file,
39  private ilObjTest $test_obj,
40  private ilDBInterface $db,
41  private TestLogger $log
42  ) {
43  parent::__construct($a_xml_file, true);
44  $this->table = '';
45  $this->active_id_mapping = [];
46  $this->question_id_mapping = [];
47  $this->user_criteria_checked = false;
48  $this->src_pool_def_id_mapping = [];
49  }
50 
54  public function getQuestionIdMapping(): array
55  {
57  }
58 
62  public function setQuestionIdMapping(array $question_id_mapping): void
63  {
64  $this->question_id_mapping = $question_id_mapping;
65  }
66 
70  public function getSrcPoolDefIdMapping(): array
71  {
73  }
74 
78  public function setSrcPoolDefIdMapping(array $src_pool_def_id_mapping): void
79  {
80  $this->src_pool_def_id_mapping = $src_pool_def_id_mapping;
81  }
82 
88  public function setHandlers($a_xml_parser): void
89  {
90  xml_set_element_handler($a_xml_parser, $this->handlerBeginTag(...), $this->handlerEndTag(...));
91  xml_set_character_data_handler($a_xml_parser, $this->handlerParseCharacterData(...));
92  }
93 
97  public function handlerBeginTag($a_xml_parser, $a_name, $a_attribs): void
98  {
99  switch (strtolower($a_name)) {
100  case "results":
101  break;
102  case "row":
103  switch ($this->table) {
104  case 'tst_active':
105  if (!$this->user_criteria_checked) {
106  $this->user_criteria_checked = true;
107  if (isset($a_attribs['user_criteria'])
108  && $this->db->tableColumnExists('usr_data', $a_attribs['user_criteria'])) {
109  $analyzer = new ilDBAnalyzer();
110  $info = $analyzer->getFieldInformation('usr_data');
111  $this->user_criteria_field = $a_attribs['user_criteria'];
112  $this->user_criteria_type = $info[$a_attribs['user_criteria']]['type'];
113  }
114  }
115  $usr_id = ANONYMOUS_USER_ID;
116  if ($this->user_criteria_field !== '') {
117  $result = $this->db->queryF(
118  'SELECT usr_id FROM usr_data WHERE '
119  . $this->user_criteria_field . ' = %s',
120  [$this->user_criteria_type],
121  [$a_attribs[$this->user_criteria_field]]
122  );
123  if ($result->numRows()) {
124  $row = $this->db->fetchAssoc($result);
125  $usr_id = $row['usr_id'];
126  }
127  }
128  $next_id = $this->db->nextId('tst_active');
129 
130  $this->db->insert('tst_active', [
131  'active_id' => ['integer', $next_id],
132  'user_fi' => ['integer', $usr_id],
133  'anonymous_id' => ['text', strlen($a_attribs['anonymous_id']) ? $a_attribs['anonymous_id'] : null],
134  'test_fi' => ['integer', $this->test_obj->getTestId()],
135  'lastindex' => ['integer', $a_attribs['lastindex']],
136  'tries' => ['integer', $a_attribs['tries']],
137  'submitted' => ['integer', $a_attribs['submitted']],
138  'submittimestamp' => ['timestamp', strlen($a_attribs['submittimestamp']) ? $a_attribs['submittimestamp'] : null],
139  'tstamp' => ['integer', $a_attribs['tstamp']],
140  'importname' => ['text', $a_attribs['fullname']],
141  'last_finished_pass' => ['integer', $this->fetchLastFinishedPass($a_attribs)],
142  'last_started_pass' => ['integer', $this->fetchLastStartedPass($a_attribs)],
143  'answerstatusfilter' => ['integer', $this->fetchAttribute($a_attribs, 'answer_status_filter')],
144  'objective_container' => ['integer', $this->fetchAttribute($a_attribs, 'objective_container')]
145  ]);
146  $this->active_id_mapping[$a_attribs['active_id']] = $next_id;
147  break;
148  case 'tst_test_rnd_qst':
149  $nextId = $this->db->nextId('tst_test_rnd_qst');
150  $newActiveId = $this->active_id_mapping[$a_attribs['active_fi']];
151  $newQuestionId = $this->question_id_mapping[$a_attribs['question_fi']];
152  $newSrcPoolDefId = $this->src_pool_def_id_mapping[$a_attribs['src_pool_def_fi']];
153  $this->db->insert('tst_test_rnd_qst', [
154  'test_random_question_id' => ['integer', $nextId],
155  'active_fi' => ['integer', $newActiveId],
156  'question_fi' => ['integer', $newQuestionId],
157  'sequence' => ['integer', $a_attribs['sequence']],
158  'pass' => ['integer', $a_attribs['pass']],
159  'tstamp' => ['integer', $a_attribs['tstamp']],
160  'src_pool_def_fi' => ['integer', $newSrcPoolDefId]
161  ]);
162  break;
163  case 'tst_pass_result':
164  $affectedRows = $this->db->manipulateF(
165  "INSERT INTO tst_pass_result (active_fi, pass, points, maxpoints, questioncount, answeredquestions, workingtime, tstamp) VALUES (%s,%s,%s,%s,%s,%s,%s,%s)",
166  [
167  'integer',
168  'integer',
169  'float',
170  'float',
171  'integer',
172  'integer',
173  'integer',
174  'integer'
175  ],
176  [
177  $this->active_id_mapping[$a_attribs['active_fi']],
178  strlen($a_attribs['pass']) ? $a_attribs['pass'] : 0,
179  ($a_attribs["points"]) ? $a_attribs["points"] : 0,
180  ($a_attribs["maxpoints"]) ? $a_attribs["maxpoints"] : 0,
181  $a_attribs["questioncount"],
182  $a_attribs["answeredquestions"],
183  ($a_attribs["workingtime"]) ? $a_attribs["workingtime"] : 0,
184  $a_attribs["tstamp"]
185  ]
186  );
187  break;
188  case 'tst_result_cache':
189  $affectedRows = $this->db->manipulateF(
190  "INSERT INTO tst_result_cache (active_fi, pass, max_points, reached_points, mark_short, mark_official, passed, failed, tstamp) VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s)",
191  [
192  'integer',
193  'integer',
194  'float',
195  'float',
196  'text',
197  'text',
198  'integer',
199  'integer',
200  'integer'
201  ],
202  [
203  $this->active_id_mapping[$a_attribs['active_fi']],
204  strlen($a_attribs['pass']) ? $a_attribs['pass'] : 0,
205  ($a_attribs["max_points"]) ? $a_attribs["max_points"] : 0,
206  ($a_attribs["reached_points"]) ? $a_attribs["reached_points"] : 0,
207  strlen($a_attribs["mark_short"]) ? $a_attribs["mark_short"] : " ",
208  strlen($a_attribs["mark_official"]) ? $a_attribs["mark_official"] : " ",
209  ($a_attribs["passed"]) ? 1 : 0,
210  ($a_attribs["failed"]) ? 1 : 0,
211  $a_attribs["tstamp"]
212  ]
213  );
214  break;
215  case 'tst_sequence':
216  $affectedRows = $this->db->insert("tst_sequence", [
217  "active_fi" => ["integer", $this->active_id_mapping[$a_attribs['active_fi']]],
218  "pass" => ["integer", $a_attribs['pass']],
219  "sequence" => ["clob", $a_attribs['sequence']],
220  "postponed" => ["text", (strlen($a_attribs['postponed'])) ? $a_attribs['postponed'] : null],
221  "hidden" => ["text", (strlen($a_attribs['hidden'])) ? $a_attribs['hidden'] : null],
222  "tstamp" => ["integer", $a_attribs['tstamp']]
223  ]);
224  break;
225  case 'tst_solutions':
226  $next_id = $this->db->nextId('tst_solutions');
227  $affectedRows = $this->db->insert("tst_solutions", [
228  "solution_id" => ["integer", $next_id],
229  "active_fi" => ["integer", $this->active_id_mapping[$a_attribs['active_fi']]],
230  "question_fi" => ["integer", $this->question_id_mapping[$a_attribs['question_fi']]],
231  "value1" => ["clob", (strlen($a_attribs['value1'])) ? $a_attribs['value1'] : null],
232  "value2" => ["clob", (strlen($a_attribs['value2'])) ? $a_attribs['value2'] : null],
233  "pass" => ["integer", $a_attribs['pass']],
234  "tstamp" => ["integer", $a_attribs['tstamp']]
235  ]);
236  break;
237  case 'tst_test_result':
238  $next_id = $this->db->nextId('tst_test_result');
239  $affectedRows = $this->db->manipulateF(
240  "INSERT INTO tst_test_result (test_result_id, active_fi, question_fi, points, pass, manual, tstamp) VALUES (%s, %s, %s, %s, %s, %s, %s)",
241  ['integer', 'integer','integer', 'float', 'integer', 'integer','integer'],
242  [$next_id, $this->active_id_mapping[$a_attribs['active_fi']], $this->question_id_mapping[$a_attribs['question_fi']], $a_attribs['points'], $a_attribs['pass'], (strlen($a_attribs['manual'])) ? $a_attribs['manual'] : 0, $a_attribs['tstamp']]
243  );
244  break;
245  case 'tst_times':
246  $next_id = $this->db->nextId('tst_times');
247  $affectedRows = $this->db->manipulateF(
248  "INSERT INTO tst_times (times_id, active_fi, started, finished, pass, tstamp) VALUES (%s, %s, %s, %s, %s, %s)",
249  ['integer', 'integer', 'timestamp', 'timestamp', 'integer', 'integer'],
250  [$next_id, $this->active_id_mapping[$a_attribs['active_fi']], $a_attribs['started'], $a_attribs['finished'], $a_attribs['pass'], $a_attribs['tstamp']]
251  );
252  break;
253  }
254  break;
255  default:
256  $this->table = $a_name;
257  break;
258  }
259  }
260 
264  public function handlerEndTag($a_xml_parser, $a_name): void
265  {
266  switch (strtolower($a_name)) {
267  case 'tst_active':
268  $this->log->info('active id mapping: ' . print_r($this->active_id_mapping, true));
269  break;
270  case 'tst_test_question':
271  $this->log->info('question id mapping: ' . print_r($this->question_id_mapping, true));
272  break;
273  }
274  }
275 
279  public function handlerParseCharacterData($a_xml_parser, $a_data): void
280  {
281  // do nothing
282  }
283 
284  private function fetchAttribute($attributes, $name)
285  {
286  if (isset($attributes[$name])) {
287  return $attributes[$name];
288  }
289 
290  return null;
291  }
292 
293  private function fetchLastFinishedPass($attribs): ?int
294  {
295  if (isset($attribs['last_finished_pass'])) {
296  return (int) $attribs['last_finished_pass'];
297  }
298 
299  if ($attribs['tries'] > 0) {
300  return $attribs['tries'] - 1;
301  }
302 
303  return null;
304  }
305 
306  private function fetchLastStartedPass($attribs): ?int
307  {
308  if (isset($attribs['last_started_pass'])) {
309  return (int) $attribs['last_started_pass'];
310  }
311 
312  if ($attribs['tries'] > 0) {
313  return (int) $attribs['tries'] - 1;
314  }
315 
316  return null;
317  }
318 }
handlerParseCharacterData($a_xml_parser, $a_data)
handler for character data
const ANONYMOUS_USER_ID
Definition: constants.php:27
handlerEndTag($a_xml_parser, $a_name)
handler for end of element
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
__construct(?string $a_xml_file, private ilObjTest $test_obj, private ilDBInterface $db, private TestLogger $log)
Constructor.
$log
Definition: result.php:32
handlerBeginTag($a_xml_parser, $a_name, $a_attribs)
handler for begin of element parser
__construct(Container $dic, ilPlugin $plugin)
This class gives all kind of DB information using the database manager and reverse module...
setQuestionIdMapping(array $question_id_mapping)
setSrcPoolDefIdMapping(array $src_pool_def_id_mapping)
setHandlers($a_xml_parser)
set event handler should be overwritten by inherited class private