ILIAS  eassessment Revision 61809
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilTestResultsImportParser.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2011 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
11 include_once("./classes/class.ilSaxParser.php");
12 
14 {
15  private $tst_obj;
16  private $table;
21  private $user_criteria_checked = false;
22 
26  function __construct($a_xml_file, &$test_object)
27  {
28  parent::__construct($a_xml_file, true);
29  $this->tst_obj = &$test_object;
30  $this->table = '';
31  $this->active_id_mapping = array();
32  $this->question_id_mapping = array();
33  $this->user_criteria_checked = false;
34  }
35 
41  function setHandlers($a_xml_parser)
42  {
43  xml_set_object($a_xml_parser,$this);
44  xml_set_element_handler($a_xml_parser,'handlerBeginTag','handlerEndTag');
45  xml_set_character_data_handler($a_xml_parser,'handlerCharacterData');
46  }
47 
51  function handlerBeginTag($a_xml_parser,$a_name,$a_attribs)
52  {
53  global $ilDB;
54 
55  $this->sametag = FALSE;
56  $this->characterbuffer = "";
57  $this->depth[$a_xml_parser]++;
58  $this->path[$this->depth[$a_xml_parser]] = strtolower($a_name);
59  $this->qti_element = $a_name;
60 
61  switch (strtolower($a_name))
62  {
63  case "results":
64  break;
65  case "row":
66  switch ($this->table)
67  {
68  case 'tst_active':
69  if (!$this->user_criteria_checked)
70  {
71  $this->user_criteria_checked = true;
72  if ($ilDB->tableColumnExists('usr_data', $a_attribs['user_criteria']))
73  {
74  include_once './Services/Database/classes/class.ilDBAnalyzer.php';
75  $analyzer = new ilDBAnalyzer();
76  $info = $analyzer->getFieldInformation('usr_data');
77  $this->user_criteria_field = $a_attribs['user_criteria'];
78  $this->user_criteria_type = $info[$a_attribs['user_criteria']]['type'];
79  }
80  }
81  $usr_id = ANONYMOUS_USER_ID;
82  if (strlen($this->user_criteria_field))
83  {
84  $result = $ilDB->queryF("SELECT usr_id FROM usr_data WHERE " . $this->user_criteria_field . " = %s",
85  array($this->user_criteria_type),
86  array($a_attribs[$this->user_criteria_field])
87  );
88  if ($result->numRows())
89  {
90  $row = $ilDB->fetchAssoc($result);
91  $usr_id = $row['usr_id'];
92  }
93  }
94  $next_id = $ilDB->nextId('tst_active');
95  $affectedRows = $ilDB->manipulateF("INSERT INTO tst_active (active_id, user_fi, anonymous_id, test_fi, lastindex, tries, submitted, submittimestamp, tstamp, importname) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)",
96  array('integer', 'integer', 'text', 'integer', 'integer', 'integer', 'integer', 'timestamp', 'integer', 'text'),
97  array(
98  $next_id,
99  $usr_id,
100  strlen($a_attribs['anonymous_id']) ? $a_attribs['anonymous_id'] : NULL,
101  $this->tst_obj->getTestId(),
102  $a_attribs['lastindex'],
103  $a_attribs['tries'],
104  $a_attribs['submitted'],
105  (strlen($a_attribs['submittimestamp'])) ? $a_attribs['submittimestamp'] : NULL,
106  $a_attribs['tstamp'],
107  $a_attribs['fullname']
108  )
109  );
110  $this->active_id_mapping[$a_attribs['active_id']] = $next_id;
111  break;
112  case 'tst_test_question':
113  $questions = $this->tst_obj->getQuestions();
114  $id = $questions[$a_attribs['sequence']];
115  if ($id > 0)
116  {
117  $this->question_id_mapping[$a_attribs['question_fi']] = $id;
118  }
119  else
120  {
121  $this->question_id_mapping[$a_attribs['question_fi']] = $a_attribs['question_fi'];
122  global $ilLog;
123  $ilLog->write("Error: Could not find question for sequence " . $a_attribs['sequence'] . " of test id " . $this->tst_obj->getTestId());
124  }
125  break;
126  case 'tst_pass_result':
127  $affectedRows = $ilDB->manipulateF("INSERT INTO tst_pass_result (active_fi, pass, points, maxpoints, questioncount, answeredquestions, workingtime, tstamp) VALUES (%s,%s,%s,%s,%s,%s,%s,%s)",
128  array(
129  'integer',
130  'integer',
131  'float',
132  'float',
133  'integer',
134  'integer',
135  'integer',
136  'integer'
137  ),
138  array(
139  $this->active_id_mapping[$a_attribs['active_fi']],
140  strlen($a_attribs['pass']) ? $a_attribs['pass'] : 0,
141  ($a_attribs["points"]) ? $a_attribs["points"] : 0,
142  ($a_attribs["maxpoints"]) ? $a_attribs["maxpoints"] : 0,
143  $a_attribs["questioncount"],
144  $a_attribs["answeredquestions"],
145  ($a_attribs["workingtime"]) ? $a_attribs["workingtime"] : 0,
146  $a_attribs["tstamp"]
147  )
148  );
149  break;
150  case 'tst_result_cache':
151  $affectedRows = $ilDB->manipulateF("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)",
152  array(
153  'integer',
154  'integer',
155  'float',
156  'float',
157  'text',
158  'text',
159  'integer',
160  'integer',
161  'integer'
162  ),
163  array(
164  $this->active_id_mapping[$a_attribs['active_fi']],
165  strlen($a_attribs['pass']) ? $a_attribs['pass'] : 0,
166  ($a_attribs["max_points"]) ? $a_attribs["max_points"] : 0,
167  ($a_attribs["reached_points"]) ? $a_attribs["reached_points"] : 0,
168  strlen($a_attribs["mark_short"]) ? $a_attribs["mark_short"] : " ",
169  strlen($a_attribs["mark_official"]) ? $a_attribs["mark_official"] : " ",
170  ($a_attribs["passed"]) ? 1 : 0,
171  ($a_attribs["failed"]) ? 1 : 0,
172  $a_attribs["tstamp"]
173  )
174  );
175  break;
176  case 'tst_sequence':
177  $affectedRows = $ilDB->insert("tst_sequence", array(
178  "active_fi" => array("integer", $this->active_id_mapping[$a_attribs['active_fi']]),
179  "pass" => array("integer", $a_attribs['pass']),
180  "sequence" => array("clob", $a_attribs['sequence']),
181  "postponed" => array("text", (strlen($a_attribs['postponed'])) ? $a_attribs['postponed'] : NULL),
182  "hidden" => array("text", (strlen($a_attribs['hidden'])) ? $a_attribs['hidden'] : NULL),
183  "tstamp" => array("integer", $a_attribs['tstamp'])
184  ));
185  break;
186  case 'tst_solutions':
187  //Modified case to handle the translation from old Term-IDs provided by imported questions for given answers
188 
189  //First, check if the there is a temporal column within qpl_a_mterm
190  $oldIDExists = false;
191  $isMatchingTerm =false;
192 
193  $checkResult = $ilDB->query("SHOW COLUMNS FROM qpl_a_mterm");
194  if ($checkResult->numRows() > 0)
195  {
196  while ($dataCR = $ilDB->fetchAssoc($checkResult))
197  {
198  if($dataCR['field']=='old_id')
199  {
200  $oldIDExists=true;
201  }
202  }
203  }
204 
205  $checkQuestionID = $ilDB->queryF("SELECT * FROM qpl_questions WHERE question_id = %s ORDER BY question_id ASC",
206  array('integer'),
207  array($this->question_id_mapping[$a_attribs['question_fi']])
208  );
209  if ($checkQuestionID->numRows() > 0)
210  {
211  while ($dataCQID = $ilDB->fetchAssoc($checkQuestionID))
212  {
213  if((int)$dataCQID['question_type_fi']==4)
214  {
215  $isMatchingTerm=true;
216  }
217  }
218  }
219  //If so, write the data to the database with the new IDs provided by the temporal column
220  if($oldIDExists && $isMatchingTerm)
221  {
222 
223  $changeResult = $ilDB->queryF("SELECT * FROM qpl_a_mterm WHERE question_fi = %s ORDER BY term_id ASC",
224  array('integer'),
225  array($this->question_id_mapping[$a_attribs['question_fi']])
226  );
227  $newTerms=array();
228  if ($changeResult->numRows() > 0)
229  {
230  while ($data = $ilDB->fetchAssoc($changeResult))
231  {
232  if($data['old_id']==($a_attribs['value1']))
233  {
234  $newTerms = $data;
235  }
236  }
237 
238  $testVariable=strlen($newTerms['term_id']);
239 
240  $next_id = $ilDB->nextId('tst_solutions');
241  $affectedRows = $ilDB->insert("tst_solutions", array(
242  "solution_id" => array("integer", $next_id),
243  "active_fi" => array("integer", $this->active_id_mapping[$a_attribs['active_fi']]),
244  "question_fi" => array("integer", $this->question_id_mapping[$a_attribs['question_fi']]),
245  "value1" => array("clob", (strlen($newTerms['term_id'])) ? $newTerms['term_id'] : ((strlen($a_attribs['value1'])) ? $a_attribs['value1'] : NULL)),
246  "value2" => array("clob", (strlen($a_attribs['value2'])) ? $a_attribs['value2'] : NULL),
247  "pass" => array("integer", $a_attribs['pass']),
248  "tstamp" => array("integer", $a_attribs['tstamp'])
249  ));
250  }
251 
252  }
253  //If not, procede as before
254  else
255  {
256  $next_id = $ilDB->nextId('tst_solutions');
257  $affectedRows = $ilDB->insert("tst_solutions", array(
258  "solution_id" => array("integer", $next_id),
259  "active_fi" => array("integer", $this->active_id_mapping[$a_attribs['active_fi']]),
260  "question_fi" => array("integer", $this->question_id_mapping[$a_attribs['question_fi']]),
261  "value1" => array("clob", (strlen($a_attribs['value1'])) ? $a_attribs['value1'] : NULL),
262  "value2" => array("clob", (strlen($a_attribs['value2'])) ? $a_attribs['value2'] : NULL),
263  "pass" => array("integer", $a_attribs['pass']),
264  "tstamp" => array("integer", $a_attribs['tstamp'])
265  ));
266  }
267  break;
268  case 'tst_test_result':
269  $next_id = $ilDB->nextId('tst_test_result');
270  $affectedRows = $ilDB->manipulateF("INSERT INTO tst_test_result (test_result_id, active_fi, question_fi, points, pass, manual, tstamp) VALUES (%s, %s, %s, %s, %s, %s, %s)",
271  array('integer', 'integer','integer', 'float', 'integer', 'integer','integer'),
272  array($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'])
273  );
274  break;
275  case 'tst_times':
276  $next_id = $ilDB->nextId('tst_times');
277  $affectedRows = $ilDB->manipulateF("INSERT INTO tst_times (times_id, active_fi, started, finished, pass, tstamp) VALUES (%s, %s, %s, %s, %s, %s)",
278  array('integer', 'integer', 'timestamp', 'timestamp', 'integer', 'integer'),
279  array($next_id, $this->active_id_mapping[$a_attribs['active_fi']], $a_attribs['started'], $a_attribs['finished'], $a_attribs['pass'], $a_attribs['tstamp'])
280  );
281  break;
282  }
283  break;
284  default:
285  $this->table = $a_name;
286  break;
287  }
288  }
289 
293  function handlerEndTag($a_xml_parser,$a_name)
294  {
295  switch (strtolower($a_name))
296  {
297  case "tst_active":
298  global $ilLog;
299  $ilLog->write("active id mapping: " . print_r($this->active_id_mapping, true));
300  break;
301  case "tst_test_question":
302  global $ilLog;
303  $ilLog->write("question id mapping: " . print_r($this->question_id_mapping, true));
304  break;
305  }
306  }
307 
311  function handlerParseCharacterData($a_xml_parser,$a_data)
312  {
313  // do nothing
314  }
315 }
316 ?>