ILIAS  release_5-1 Revision 5.0.0-5477-g43f3e3fab5
class.ilTestExport.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
4 require_once './Modules/Test/classes/inc.AssessmentConstants.php';
5 require_once './Services/Utilities/classes/class.ilFormat.php';
6 
7 require_once 'Modules/TestQuestionPool/classes/class.assQuestion.php';
19 {
21  var $err; // error object
22 
24  var $db; // database object
25 
27  var $ilias; // ilias object
28 
30  var $test_obj; // test object
31 
32  var $inst_id; // installation id
33  var $mode;
34 
36  private $lng;
37 
38  private $resultsfile;
39 
41 
45  public function __construct(&$a_test_obj, $a_mode = "xml")
46  {
47  global $ilErr, $ilDB, $ilias, $lng;
48 
49  $this->test_obj =& $a_test_obj;
50 
51  $this->err =& $ilErr;
52  $this->ilias =& $ilias;
53  $this->db =& $ilDB;
54  $this->mode = $a_mode;
55  $this->lng =& $lng;
56 
57  $this->inst_id = IL_INST_ID;
58 
59  $date = time();
60  $this->export_dir = $this->test_obj->getExportDirectory();
61  switch($this->mode)
62  {
63  case "results":
64  $this->subdir = $date."__".$this->inst_id."__".
65  "tst__results_".$this->test_obj->getId();
66  break;
67  case "aggregated":
68  $this->subdir = $date."__".$this->inst_id."__".
69  "test__aggregated__results_".$this->test_obj->getId();
70  break;
71  default:
72  $this->subdir = $date."__".$this->inst_id."__".
73  "tst"."_".$this->test_obj->getId();
74  $this->filename = $this->subdir.".xml";
75  $this->resultsfile = $date."__".$this->inst_id."__".
76  "results"."_".$this->test_obj->getId().".xml";
77  $this->qti_filename = $date."__".$this->inst_id."__".
78  "qti"."_".$this->test_obj->getId().".xml";
79  break;
80  }
81  $this->filename = $this->subdir.".".$this->getExtension();
82  }
83 
88  {
90  }
91 
95  public function setResultExportingEnabledForTestExport($resultExprtingEnabledForTestExport)
96  {
97  $this->resultExportingEnabledForTestExport = $resultExprtingEnabledForTestExport;
98  }
99 
100  function getExtension () {
101  switch ($this->mode) {
102  case "results":
103  return "csv"; break;
104  default:
105  return "xml"; break;
106  }
107  }
108 
109  function getInstId()
110  {
111  return $this->inst_id;
112  }
113 
114 
121  function buildExportFile()
122  {
123  switch ($this->mode)
124  {
125  case "results":
126  return $this->buildExportResultFile();
127  break;
128  default:
129  return $this->buildExportFileXML();
130  break;
131  }
132  }
133 
138  {
139  global $ilBench;
140  global $log;
141 
142  //get Log File
143  $expDir = $this->test_obj->getExportDirectory();
144 
145  // make_directories
146  $this->test_obj->createExportDirectory();
147  include_once "./Services/Utilities/classes/class.ilUtil.php";
148  ilUtil::makeDir($this->export_dir);
149 
150  include_once './Services/Logging/classes/class.ilLog.php';
151  $expLog = new ilLog($expDir, "export.log");
152  $expLog->delete();
153  $expLog->setLogFormat("");
154  $expLog->write(date("[y-m-d H:i:s] ")."Start Export Of Results");
155 
156  $data = $this->exportToCSV($deliver = FALSE);
157  $file = fopen($this->export_dir."/".$this->filename, "w");
158  fwrite($file, $data);
159  fclose($file);
160 
161  $excelfile = $this->exportToExcel($deliver = FALSE);
162  @copy($excelfile, $this->export_dir . "/" . str_replace($this->getExtension(), "xls", $this->filename));
163  @unlink($excelfile);
164  // end
165  $expLog->write(date("[y-m-d H:i:s] ")."Finished Export of Results");
166 
167  return $this->export_dir."/".$this->filename;
168  }
169 
175  protected function aggregatedResultsToExcel($deliver = TRUE)
176  {
177  $data = $this->test_obj->getAggregatedResultsData();
178  include_once "./Services/Excel/classes/class.ilExcelWriterAdapter.php";
179  $excelfile = ilUtil::ilTempnam();
180  $adapter = new ilExcelWriterAdapter($excelfile, FALSE);
181  $testname = ilUtil::getASCIIFilename(preg_replace("/\s/", "_", $this->test_obj->getTitle() . '_aggregated')) . ".xls";
182  $workbook = $adapter->getWorkbook();
183  $workbook->setVersion(8); // Use Excel97/2000 Format
184  // Creating a worksheet
185  $format_percent =& $workbook->addFormat();
186  $format_percent->setNumFormat("0.00%");
187  $format_title =& $workbook->addFormat();
188  $format_title->setBold();
189  $format_title->setColor('black');
190  $format_title->setPattern(1);
191  $format_title->setFgColor('silver');
192  include_once "./Services/Excel/classes/class.ilExcelUtils.php";
193  $worksheet =& $workbook->addWorksheet(ilExcelUtils::_convert_text($this->lng->txt("tst_results_aggregated")));
194  $row = 0;
195  $col = 0;
196  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($this->lng->txt("result")), $format_title);
197  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($this->lng->txt("value")), $format_title);
198  $row++;
199  foreach ($data["overview"] as $key => $value)
200  {
201  $col = 0;
202  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($key));
203  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($value));
204  $row++;
205  }
206  $row++;
207  $col = 0;
208  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($this->lng->txt("question_id")), $format_title);
209  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($this->lng->txt("question_title")), $format_title);
210  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($this->lng->txt("average_reached_points")), $format_title);
211  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($this->lng->txt("points")), $format_title);
212  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($this->lng->txt("percentage")), $format_title);
213  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($this->lng->txt("number_of_answers")), $format_title);
214  $row++;
215  foreach ($data["questions"] as $key => $value)
216  {
217  $col = 0;
218  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($key));
219  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($value[0]));
220  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($value[4]));
221  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($value[5]));
222  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($value[6]), $format_percent);
223  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($value[3]));
224  $row++;
225  }
226  $workbook->close();
227  if ($deliver)
228  {
229  ilUtil::deliverFile($excelfile, $testname, "application/vnd.ms-excel", false, true);
230  exit;
231  }
232  else
233  {
234  return $excelfile;
235  }
236  }
237 
243  protected function aggregatedResultsToCSV($deliver = TRUE)
244  {
245  $data = $this->test_obj->getAggregatedResultsData();
246  $rows = array();
247  array_push($rows, array(
248  $this->lng->txt("result"),
249  $this->lng->txt("value")
250  ));
251  foreach ($data["overview"] as $key => $value)
252  {
253  array_push($rows, array(
254  $key,
255  $value
256  ));
257  }
258  array_push($rows, array(
259  $this->lng->txt("question_title"),
260  $this->lng->txt("average_reached_points"),
261  $this->lng->txt("points"),
262  $this->lng->txt("percentage"),
263  $this->lng->txt("number_of_answers")
264  ));
265  foreach ($data["questions"] as $key => $value)
266  {
267  array_push($rows, array(
268  $value[0],
269  $value[4],
270  $value[5],
271  $value[6],
272  $value[3]
273  ));
274  }
275  $csv = "";
276  $separator = ";";
277  foreach ($rows as $evalrow)
278  {
279  $csvrow =& $this->test_obj->processCSVRow($evalrow, TRUE, $separator);
280  $csv .= join($csvrow, $separator) . "\n";
281  }
282  if ($deliver)
283  {
284  ilUtil::deliverData($csv, ilUtil::getASCIIFilename($this->test_obj->getTitle() . "_aggregated.csv"));
285  exit;
286  }
287  else
288  {
289  return $csv;
290  }
291  }
292 
303  public function exportToExcel($deliver = TRUE, $filterby = "", $filtertext = "", $passedonly = FALSE)
304  {
305  if (strcmp($this->mode, "aggregated") == 0) return $this->aggregatedResultsToExcel($deliver);
306 
307  require_once './Services/Excel/classes/class.ilExcelWriterAdapter.php';
308  $excelfile = ilUtil::ilTempnam();
309  $adapter = new ilExcelWriterAdapter($excelfile, FALSE);
310  $testname = $this->test_obj->getTitle();
311  switch($this->mode)
312  {
313  case 'results':
314  $testname .= '_results';
315  break;
316  }
317  $testname = ilUtil::getASCIIFilename(preg_replace("/\s/", "_", $testname)) . ".xls";
318  $workbook = $adapter->getWorkbook();
319  $workbook->setVersion(8); // Use Excel97/2000 Format
320  // Creating a worksheet
321  $format_bold =& $workbook->addFormat();
322  $format_bold->setBold();
323  $format_percent =& $workbook->addFormat();
324  $format_percent->setNumFormat("0.00%");
325  $format_datetime =& $workbook->addFormat();
326  $format_datetime->setNumFormat("DD/MM/YYYY hh:mm:ss");
327  $format_title =& $workbook->addFormat();
328  $format_title->setBold();
329  $format_title->setColor('black');
330  $format_title->setPattern(1);
331  $format_title->setFgColor('silver');
332  require_once './Services/Excel/classes/class.ilExcelUtils.php';
333  $worksheet =& $workbook->addWorksheet(ilExcelUtils::_convert_text($this->lng->txt("tst_results")));
334  $additionalFields = $this->test_obj->getEvaluationAdditionalFields();
335  $row = 0;
336  $col = 0;
337 
338  if ($this->test_obj->getAnonymity())
339  {
340  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($this->lng->txt("counter")), $format_title);
341  }
342  else
343  {
344  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($this->lng->txt("name")), $format_title);
345  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($this->lng->txt("login")), $format_title);
346  }
347  if (count($additionalFields))
348  {
349  foreach ($additionalFields as $fieldname)
350  {
351  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($this->lng->txt($fieldname)), $format_title);
352  }
353  }
354  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($this->lng->txt("tst_stat_result_resultspoints")), $format_title);
355  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($this->lng->txt("maximum_points")), $format_title);
356  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($this->lng->txt("tst_stat_result_resultsmarks")), $format_title);
357  if ($this->test_obj->getECTSOutput())
358  {
359  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($this->lng->txt("ects_grade")), $format_title);
360  }
361  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($this->lng->txt("tst_stat_result_qworkedthrough")), $format_title);
362  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($this->lng->txt("tst_stat_result_qmax")), $format_title);
363  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($this->lng->txt("tst_stat_result_pworkedthrough")), $format_title);
364  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($this->lng->txt("tst_stat_result_timeofwork")), $format_title);
365  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($this->lng->txt("tst_stat_result_atimeofwork")), $format_title);
366  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($this->lng->txt("tst_stat_result_firstvisit")), $format_title);
367  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($this->lng->txt("tst_stat_result_lastvisit")), $format_title);
368 
369  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($this->lng->txt("tst_stat_result_mark_median")), $format_title);
370  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($this->lng->txt("tst_stat_result_rank_participant")), $format_title);
371  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($this->lng->txt("tst_stat_result_rank_median")), $format_title);
372  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($this->lng->txt("tst_stat_result_total_participants")), $format_title);
373  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($this->lng->txt("tst_stat_result_median")), $format_title);
374  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($this->lng->txt("scored_pass")), $format_title);
375 
376  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($this->lng->txt("pass")), $format_title);
377 
378  $counter = 1;
379  $data =& $this->test_obj->getCompleteEvaluationData(TRUE, $filterby, $filtertext);
380  $firstrowwritten = false;
381  foreach ($data->getParticipants() as $active_id => $userdata)
382  {
383  if ($passedonly && $data->getParticipant($active_id)->getPassed() == FALSE)
384  {
385  continue;
386  }
387 
388  $row++;
389  $col = 0;
390 
391  // each participant gets an own row for question column headers
392  if($this->test_obj->isRandomTest())
393  {
394  $row++;
395  }
396 
397  if ($this->test_obj->getAnonymity())
398  {
399  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($counter));
400  }
401  else
402  {
403  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($data->getParticipant($active_id)->getName()));
404  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($data->getParticipant($active_id)->getLogin()));
405  }
406  if (count($additionalFields))
407  {
408  $userfields = ilObjUser::_lookupFields($userdata->getUserID());
409  foreach ($additionalFields as $fieldname)
410  {
411  if (strcmp($fieldname, "gender") == 0)
412  {
413  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($this->lng->txt("gender_" . $userfields[$fieldname])));
414  }
415  else
416  {
417  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($userfields[$fieldname]));
418  }
419  }
420  }
421  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($data->getParticipant($active_id)->getReached()));
422  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($data->getParticipant($active_id)->getMaxpoints()));
423  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($data->getParticipant($active_id)->getMark()));
424  if ($this->test_obj->getECTSOutput())
425  {
426  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($data->getParticipant($active_id)->getECTSMark()));
427  }
428  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($data->getParticipant($active_id)->getQuestionsWorkedThrough()));
429  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($data->getParticipant($active_id)->getNumberOfQuestions()));
430  $worksheet->write($row, $col++, $data->getParticipant($active_id)->getQuestionsWorkedThroughInPercent() / 100.0, $format_percent);
431  $time = $data->getParticipant($active_id)->getTimeOfWork();
432  $time_seconds = $time;
433  $time_hours = floor($time_seconds/3600);
434  $time_seconds -= $time_hours * 3600;
435  $time_minutes = floor($time_seconds/60);
436  $time_seconds -= $time_minutes * 60;
437  $worksheet->write($row, $col++, ilExcelUtils::_convert_text(sprintf("%02d:%02d:%02d", $time_hours, $time_minutes, $time_seconds)));
438  $time = $data->getParticipant($active_id)->getQuestionsWorkedThrough() ? $data->getParticipant($active_id)->getTimeOfWork() / $data->getParticipant($active_id)->getQuestionsWorkedThrough() : 0;
439  $time_seconds = $time;
440  $time_hours = floor($time_seconds/3600);
441  $time_seconds -= $time_hours * 3600;
442  $time_minutes = floor($time_seconds/60);
443  $time_seconds -= $time_minutes * 60;
444  $worksheet->write($row, $col++, ilExcelUtils::_convert_text(sprintf("%02d:%02d:%02d", $time_hours, $time_minutes, $time_seconds)));
445  $fv = getdate($data->getParticipant($active_id)->getFirstVisit());
446  $firstvisit = ilUtil::excelTime(
447  $fv["year"],
448  $fv["mon"],
449  $fv["mday"],
450  $fv["hours"],
451  $fv["minutes"],
452  $fv["seconds"]
453  );
454  $worksheet->write($row, $col++, $firstvisit, $format_datetime);
455  $lv = getdate($data->getParticipant($active_id)->getLastVisit());
456  $lastvisit = ilUtil::excelTime(
457  $lv["year"],
458  $lv["mon"],
459  $lv["mday"],
460  $lv["hours"],
461  $lv["minutes"],
462  $lv["seconds"]
463  );
464  $worksheet->write($row, $col++, $lastvisit, $format_datetime);
465 
466  $median = $data->getStatistics()->getStatistics()->median();
467  $pct = $data->getParticipant($active_id)->getMaxpoints() ? $median / $data->getParticipant($active_id)->getMaxpoints() * 100.0 : 0;
468  $mark = $this->test_obj->mark_schema->getMatchingMark($pct);
469  $mark_short_name = "";
470  if (is_object($mark))
471  {
472  $mark_short_name = $mark->getShortName();
473  }
474  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($mark_short_name));
475  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($data->getStatistics()->getStatistics()->rank($data->getParticipant($active_id)->getReached())));
476  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($data->getStatistics()->getStatistics()->rank_median()));
477  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($data->getStatistics()->getStatistics()->count()));
478  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($median));
479  if ($this->test_obj->getPassScoring() == SCORE_BEST_PASS)
480  {
481  $worksheet->write($row, $col++, $data->getParticipant($active_id)->getBestPass() + 1);
482  }
483  else
484  {
485  $worksheet->write($row, $col++, $data->getParticipant($active_id)->getLastPass() + 1);
486  }
487  $startcol = $col;
488  for ($pass = 0; $pass <= $data->getParticipant($active_id)->getLastPass(); $pass++)
489  {
490  $col = $startcol;
491  $finishdate = $this->test_obj->getPassFinishDate($active_id, $pass);
492  if ($finishdate > 0)
493  {
494  if ($pass > 0)
495  {
496  $row++;
497  if ($this->test_obj->isRandomTest())
498  {
499  $row++;
500  }
501  }
502  $worksheet->write($row, $col++, ilExcelUtils::_convert_text($pass+1));
503  if (is_object($data->getParticipant($active_id)) && is_array($data->getParticipant($active_id)->getQuestions($pass)))
504  {
505  $evaluatedQuestions = $data->getParticipant($active_id)->getQuestions($pass);
506 
507  if( $this->test_obj->getShuffleQuestions() )
508  {
509  // reorder questions according to general fixed sequence,
510  // so participant rows can share single questions header
511  $questions = array();
512  foreach($this->test_obj->getQuestions() as $qId)
513  {
514  foreach($evaluatedQuestions as $evaledQst)
515  {
516  if( $evaledQst['id'] != $qId )
517  {
518  continue;
519  }
520 
521  $questions[] = $evaledQst;
522  }
523  }
524  }
525  else
526  {
527  $questions = $evaluatedQuestions;
528  }
529 
530  foreach($questions as $question)
531  {
532  $question_data = $data->getParticipant($active_id)->getPass($pass)->getAnsweredQuestionByQuestionId($question["id"]);
533  $worksheet->write($row, $col, ilExcelUtils::_convert_text($question_data["reached"]));
534  if ($this->test_obj->isRandomTest())
535  {
536  // random test requires question headers for every participant
537  // and we allready skipped a row for that reason ( --> row - 1)
538  $worksheet->write($row-1, $col, ilExcelUtils::_convert_text(preg_replace("/<.*?>/", "", $data->getQuestionTitle($question["id"]))), $format_title);
539  }
540  else
541  {
542  if ($pass == 0 && !$firstrowwritten)
543  {
544  $worksheet->write(0, $col, ilExcelUtils::_convert_text(preg_replace("/<.*?>/", "", $data->getQuestionTitle($question["id"]))), $format_title);
545  }
546  }
547  $col++;
548  }
549  $firstrowwritten = true;
550  }
551  }
552  }
553  $counter++;
554  }
555  if ($this->test_obj->getExportSettingsSingleChoiceShort() && !$this->test_obj->isRandomTest() && $this->test_obj->hasSingleChoiceQuestions())
556  {
557  // special tab for single choice tests
558  $titles =& $this->test_obj->getQuestionTitlesAndIndexes();
559  $positions = array();
560  $pos = 0;
561  $row = 0;
562  foreach ($titles as $id => $title)
563  {
564  $positions[$id] = $pos;
565  $pos++;
566  }
567  $usernames = array();
568  $participantcount = count($data->getParticipants());
569  $allusersheet = false;
570  $pages = 0;
571  $resultsheet =& $workbook->addWorksheet($this->lng->txt("eval_all_users"));
572 
573  $col = 0;
574  $resultsheet->write($row, $col++, ilExcelUtils::_convert_text($this->lng->txt('name')), $format_title);
575  $resultsheet->write($row, $col++, ilExcelUtils::_convert_text($this->lng->txt('login')), $format_title);
576  if (count($additionalFields))
577  {
578  foreach ($additionalFields as $fieldname)
579  {
580  if (strcmp($fieldname, "matriculation") == 0)
581  {
582  $resultsheet->write($row, $col++, ilExcelUtils::_convert_text($this->lng->txt('matriculation')), $format_title);
583  }
584  }
585  }
586  $resultsheet->write($row, $col++, ilExcelUtils::_convert_text($this->lng->txt('test')), $format_title);
587  foreach ($titles as $title)
588  {
589  $resultsheet->write($row, $col++, ilExcelUtils::_convert_text($title), $format_title);
590  }
591  $row++;
592 
593  foreach ($data->getParticipants() as $active_id => $userdata)
594  {
595  $username = (!is_null($userdata) && ilExcelUtils::_convert_text($userdata->getName())) ? ilExcelUtils::_convert_text($userdata->getName()) : "ID $active_id";
596  if (array_key_exists($username, $usernames))
597  {
598  $usernames[$username]++;
599  $username .= " ($i)";
600  }
601  else
602  {
603  $usernames[$username] = 1;
604  }
605  $col = 0;
606  $resultsheet->write($row, $col++, $username);
607  $resultsheet->write($row, $col++, $userdata->getLogin());
608  if (count($additionalFields))
609  {
610  $userfields = ilObjUser::_lookupFields($userdata->getUserID());
611  foreach ($additionalFields as $fieldname)
612  {
613  if (strcmp($fieldname, "matriculation") == 0)
614  {
615  if (strlen($userfields[$fieldname]))
616  {
617  $resultsheet->write($row, $col++, ilExcelUtils::_convert_text($userfields[$fieldname]));
618  }
619  else
620  {
621  $col++;
622  }
623  }
624  }
625  }
626  $resultsheet->write($row, $col++, ilExcelUtils::_convert_text($this->test_obj->getTitle()));
627  $pass = $userdata->getScoredPass();
628  if (is_object($userdata) && is_array($userdata->getQuestions($pass)))
629  {
630  foreach ($userdata->getQuestions($pass) as $question)
631  {
632  $objQuestion = assQuestion::_instantiateQuestion($question["id"]);
633  if(is_object($objQuestion) && strcmp($objQuestion->getQuestionType(), 'assSingleChoice') == 0)
634  {
635  $solution = $objQuestion->getSolutionValues($active_id, $pass);
636  $pos = $positions[$question["id"]];
637  $selectedanswer = "x";
638  foreach ($objQuestion->getAnswers() as $id => $answer)
639  {
640  if (strlen($solution[0]["value1"]) && $id == $solution[0]["value1"])
641  {
642  $selectedanswer = $answer->getAnswertext();
643  }
644  }
645  $resultsheet->write($row, $col+$pos, ilExcelUtils::_convert_text($selectedanswer));
646  }
647  }
648  }
649  $row++;
650  }
651  if ($this->test_obj->isSingleChoiceTestWithoutShuffle())
652  {
653  // special tab for single choice tests without shuffle option
654  $pos = 0;
655  $row = 0;
656  $usernames = array();
657  $allusersheet = false;
658  $pages = 0;
659  $resultsheet =& $workbook->addWorksheet($this->lng->txt("eval_all_users") . " (2)");
660 
661  $col = 0;
662  $resultsheet->write($row, $col++, ilExcelUtils::_convert_text($this->lng->txt('name')), $format_title);
663  $resultsheet->write($row, $col++, ilExcelUtils::_convert_text($this->lng->txt('login')), $format_title);
664  if (count($additionalFields))
665  {
666  foreach ($additionalFields as $fieldname)
667  {
668  if (strcmp($fieldname, "matriculation") == 0)
669  {
670  $resultsheet->write($row, $col++, ilExcelUtils::_convert_text($this->lng->txt('matriculation')), $format_title);
671  }
672  }
673  }
674  $resultsheet->write($row, $col++, ilExcelUtils::_convert_text($this->lng->txt('test')), $format_title);
675  foreach ($titles as $title)
676  {
677  $resultsheet->write($row, $col++, ilExcelUtils::_convert_text($title), $format_title);
678  }
679  $row++;
680 
681  foreach ($data->getParticipants() as $active_id => $userdata)
682  {
683  $username = (!is_null($userdata) && ilExcelUtils::_convert_text($userdata->getName())) ? ilExcelUtils::_convert_text($userdata->getName()) : "ID $active_id";
684  if (array_key_exists($username, $usernames))
685  {
686  $usernames[$username]++;
687  $username .= " ($i)";
688  }
689  else
690  {
691  $usernames[$username] = 1;
692  }
693  $col = 0;
694  $resultsheet->write($row, $col++, $username);
695  $resultsheet->write($row, $col++, $userdata->getLogin());
696  if (count($additionalFields))
697  {
698  $userfields = ilObjUser::_lookupFields($userdata->getUserID());
699  foreach ($additionalFields as $fieldname)
700  {
701  if (strcmp($fieldname, "matriculation") == 0)
702  {
703  if (strlen($userfields[$fieldname]))
704  {
705  $resultsheet->write($row, $col++, ilExcelUtils::_convert_text($userfields[$fieldname]));
706  }
707  else
708  {
709  $col++;
710  }
711  }
712  }
713  }
714  $resultsheet->write($row, $col++, ilExcelUtils::_convert_text($this->test_obj->getTitle()));
715  $pass = $userdata->getScoredPass();
716  if (is_object($userdata) && is_array($userdata->getQuestions($pass)))
717  {
718  foreach ($userdata->getQuestions($pass) as $question)
719  {
720  $objQuestion =& $this->test_obj->_instanciateQuestion($question["aid"]);
721  if (is_object($objQuestion) && strcmp($objQuestion->getQuestionType(), 'assSingleChoice') == 0)
722  {
723  $solution = $objQuestion->getSolutionValues($active_id, $pass);
724  $pos = $positions[$question["aid"]];
725  $selectedanswer = chr(65+$solution[0]["value1"]);
726  $resultsheet->write($row, $col+$pos, ilExcelUtils::_convert_text($selectedanswer));
727  }
728  }
729  }
730  $row++;
731  }
732  }
733  }
734  else
735  {
736  // test participant result export
737  $usernames = array();
738  $participantcount = count($data->getParticipants());
739  $allusersheet = false;
740  $pages = 0;
741  $i = 0;
742  foreach ($data->getParticipants() as $active_id => $userdata)
743  {
744  $i++;
745 
746  $username = (!is_null($userdata) && ilExcelUtils::_convert_text($userdata->getName())) ? ilExcelUtils::_convert_text($userdata->getName()) : "ID $active_id";
747  if (array_key_exists($username, $usernames))
748  {
749  $usernames[$username]++;
750  $username .= " ($i)";
751  }
752  else
753  {
754  $usernames[$username] = 1;
755  }
756  if ($participantcount > 250) {
757  if (!$allusersheet || ($pages-1) < floor($row / 64000)) {
758  $resultsheet =& $workbook->addWorksheet($this->lng->txt("eval_all_users") . (($pages > 0) ? " (".($pages+1).")" : ""));
759  $allusersheet = true;
760  $row = 0;
761  $pages++;
762  }
763  } else {
764  $resultsheet =& $workbook->addWorksheet(utf8_decode($username));
765  }
766  if (method_exists($resultsheet, "writeString"))
767  {
768  $pass = $userdata->getScoredPass();
769  $row = ($allusersheet) ? $row : 0;
770  $resultsheet->writeString($row, 0, ilExcelUtils::_convert_text(sprintf($this->lng->txt("tst_result_user_name_pass"), $pass+1, $userdata->getName())), $format_bold);
771  $row += 2;
772  if (is_object($userdata) && is_array($userdata->getQuestions($pass)))
773  {
774  foreach ($userdata->getQuestions($pass) as $question)
775  {
776  require_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
777  $question = assQuestion::_instanciateQuestion($question["id"]);
778  if (is_object($question))
779  {
780  $row = $question->setExportDetailsXLS($resultsheet, $row, $active_id, $pass, $format_title, $format_bold);
781  }
782  }
783  }
784  }
785  }
786  }
787  $workbook->close();
788  if ($deliver)
789  {
790  ilUtil::deliverFile($excelfile, $testname, "application/vnd.ms-excel", false, true);
791  exit;
792  }
793  else
794  {
795  return $excelfile;
796  }
797  }
798 
808  function exportToCSV($deliver = TRUE, $filterby = "", $filtertext = "", $passedonly = FALSE)
809  {
810  global $ilLog;
811 
812  if (strcmp($this->mode, "aggregated") == 0) return $this->aggregatedResultsToCSV($deliver);
813 
814  $rows = array();
815  $datarow = array();
816  $col = 1;
817  if ($this->test_obj->getAnonymity())
818  {
819  array_push($datarow, $this->lng->txt("counter"));
820  $col++;
821  }
822  else
823  {
824  array_push($datarow, $this->lng->txt("name"));
825  $col++;
826  array_push($datarow, $this->lng->txt("login"));
827  $col++;
828  }
829  $additionalFields = $this->test_obj->getEvaluationAdditionalFields();
830  if (count($additionalFields))
831  {
832  foreach ($additionalFields as $fieldname)
833  {
834  array_push($datarow, $this->lng->txt($fieldname));
835  $col++;
836  }
837  }
838  array_push($datarow, $this->lng->txt("tst_stat_result_resultspoints"));
839  $col++;
840  array_push($datarow, $this->lng->txt("maximum_points"));
841  $col++;
842  array_push($datarow, $this->lng->txt("tst_stat_result_resultsmarks"));
843  $col++;
844  if ($this->test_obj->getECTSOutput())
845  {
846  array_push($datarow, $this->lng->txt("ects_grade"));
847  $col++;
848  }
849  array_push($datarow, $this->lng->txt("tst_stat_result_qworkedthrough"));
850  $col++;
851  array_push($datarow, $this->lng->txt("tst_stat_result_qmax"));
852  $col++;
853  array_push($datarow, $this->lng->txt("tst_stat_result_pworkedthrough"));
854  $col++;
855  array_push($datarow, $this->lng->txt("tst_stat_result_timeofwork"));
856  $col++;
857  array_push($datarow, $this->lng->txt("tst_stat_result_atimeofwork"));
858  $col++;
859  array_push($datarow, $this->lng->txt("tst_stat_result_firstvisit"));
860  $col++;
861  array_push($datarow, $this->lng->txt("tst_stat_result_lastvisit"));
862  $col++;
863 
864  array_push($datarow, $this->lng->txt("tst_stat_result_mark_median"));
865  $col++;
866  array_push($datarow, $this->lng->txt("tst_stat_result_rank_participant"));
867  $col++;
868  array_push($datarow, $this->lng->txt("tst_stat_result_rank_median"));
869  $col++;
870  array_push($datarow, $this->lng->txt("tst_stat_result_total_participants"));
871  $col++;
872  array_push($datarow, $this->lng->txt("tst_stat_result_median"));
873  $col++;
874  array_push($datarow, $this->lng->txt("scored_pass"));
875  $col++;
876 
877  array_push($datarow, $this->lng->txt("pass"));
878  $col++;
879 
880  $data =& $this->test_obj->getCompleteEvaluationData(TRUE, $filterby, $filtertext);
881  $headerrow = $datarow;
882  $counter = 1;
883  foreach ($data->getParticipants() as $active_id => $userdata)
884  {
885  $datarow = $headerrow;
886  $remove = FALSE;
887  if ($passedonly)
888  {
889  if ($data->getParticipant($active_id)->getPassed() == FALSE)
890  {
891  $remove = TRUE;
892  }
893  }
894  if (!$remove)
895  {
896  $datarow2 = array();
897  if ($this->test_obj->getAnonymity())
898  {
899  array_push($datarow2, $counter);
900  }
901  else
902  {
903  array_push($datarow2, $data->getParticipant($active_id)->getName());
904  array_push($datarow2, $data->getParticipant($active_id)->getLogin());
905  }
906  if (count($additionalFields))
907  {
908  $userfields = ilObjUser::_lookupFields($userdata->getUserID());
909  foreach ($additionalFields as $fieldname)
910  {
911  if (strcmp($fieldname, "gender") == 0)
912  {
913  array_push($datarow2, $this->lng->txt("gender_" . $userfields[$fieldname]));
914  }
915  else
916  {
917  array_push($datarow2, $userfields[$fieldname]);
918  }
919  }
920  }
921  array_push($datarow2, $data->getParticipant($active_id)->getReached());
922  array_push($datarow2, $data->getParticipant($active_id)->getMaxpoints());
923  array_push($datarow2, $data->getParticipant($active_id)->getMark());
924  if ($this->test_obj->getECTSOutput())
925  {
926  array_push($datarow2, $data->getParticipant($active_id)->getECTSMark());
927  }
928  array_push($datarow2, $data->getParticipant($active_id)->getQuestionsWorkedThrough());
929  array_push($datarow2, $data->getParticipant($active_id)->getNumberOfQuestions());
930  array_push($datarow2, $data->getParticipant($active_id)->getQuestionsWorkedThroughInPercent() / 100.0);
931  $time = $data->getParticipant($active_id)->getTimeOfWork();
932  $time_seconds = $time;
933  $time_hours = floor($time_seconds/3600);
934  $time_seconds -= $time_hours * 3600;
935  $time_minutes = floor($time_seconds/60);
936  $time_seconds -= $time_minutes * 60;
937  array_push($datarow2, sprintf("%02d:%02d:%02d", $time_hours, $time_minutes, $time_seconds));
938  $time = $data->getParticipant($active_id)->getQuestionsWorkedThrough() ? $data->getParticipant($active_id)->getTimeOfWork() / $data->getParticipant($active_id)->getQuestionsWorkedThrough() : 0;
939  $time_seconds = $time;
940  $time_hours = floor($time_seconds/3600);
941  $time_seconds -= $time_hours * 3600;
942  $time_minutes = floor($time_seconds/60);
943  $time_seconds -= $time_minutes * 60;
944  array_push($datarow2, sprintf("%02d:%02d:%02d", $time_hours, $time_minutes, $time_seconds));
945 
946  $fv = $data->getParticipant($active_id)->getFirstVisit();
947  $lv = $data->getParticipant($active_id)->getLastVisit();
948  foreach(array($fv, $lv) as $ts)
949  {
950  if($ts)
951  {
952  $visit = ilFormat::formatDate(date('Y-m-d H:i:s', $ts), "datetime", false, false);
953  array_push($datarow2, $visit);
954  }
955  else
956  {
957  array_push($datarow2, "");
958  }
959  }
960 
961  $median = $data->getStatistics()->getStatistics()->median();
962  $pct = $data->getParticipant($active_id)->getMaxpoints() ? $median / $data->getParticipant($active_id)->getMaxpoints() * 100.0 : 0;
963  $mark = $this->test_obj->mark_schema->getMatchingMark($pct);
964  $mark_short_name = "";
965  if (is_object($mark))
966  {
967  $mark_short_name = $mark->getShortName();
968  }
969  array_push($datarow2, $mark_short_name);
970  array_push($datarow2, $data->getStatistics()->getStatistics()->rank($data->getParticipant($active_id)->getReached()));
971  array_push($datarow2, $data->getStatistics()->getStatistics()->rank_median());
972  array_push($datarow2, $data->getStatistics()->getStatistics()->count());
973  array_push($datarow2, $median);
974  if ($this->test_obj->getPassScoring() == SCORE_BEST_PASS)
975  {
976  array_push($datarow2, $data->getParticipant($active_id)->getBestPass() + 1);
977  }
978  else
979  {
980  array_push($datarow2, $data->getParticipant($active_id)->getLastPass() + 1);
981  }
982  for ($pass = 0; $pass <= $data->getParticipant($active_id)->getLastPass(); $pass++)
983  {
984  $finishdate = $this->test_obj->getPassFinishDate($active_id, $pass);
985  if ($finishdate > 0)
986  {
987  if ($pass > 0)
988  {
989  for ($i = 1; $i < $col-1; $i++)
990  {
991  array_push($datarow2, "");
992  array_push($datarow, "");
993  }
994  array_push($datarow, "");
995  }
996  array_push($datarow2, $pass+1);
997  if (is_object($data->getParticipant($active_id)) && is_array($data->getParticipant($active_id)->getQuestions($pass)))
998  {
999  foreach ($data->getParticipant($active_id)->getQuestions($pass) as $question)
1000  {
1001  $question_data = $data->getParticipant($active_id)->getPass($pass)->getAnsweredQuestionByQuestionId($question["id"]);
1002  array_push($datarow2, $question_data["reached"]);
1003  array_push($datarow, preg_replace("/<.*?>/", "", $data->getQuestionTitle($question["id"])));
1004  }
1005  }
1006  if ($this->test_obj->isRandomTest() || $this->test_obj->getShuffleQuestions() || ($counter == 1 && $pass == 0))
1007  {
1008  array_push($rows, $datarow);
1009  }
1010  $datarow = array();
1011  array_push($rows, $datarow2);
1012  $datarow2 = array();
1013  }
1014  }
1015  $counter++;
1016  }
1017  }
1018  $csv = "";
1019  $separator = ";";
1020  foreach ($rows as $evalrow)
1021  {
1022  $csvrow =& $this->test_obj->processCSVRow($evalrow, TRUE, $separator);
1023  $csv .= join($csvrow, $separator) . "\n";
1024  }
1025  if ($deliver)
1026  {
1027  ilUtil::deliverData($csv, ilUtil::getASCIIFilename($this->test_obj->getTitle() . "_results.csv"));
1028  exit;
1029  }
1030  else
1031  {
1032  return $csv;
1033  }
1034  }
1035 
1040  {
1041  global $ilBench;
1042 
1043  $ilBench->start("TestExport", "buildExportFile");
1044 
1045  include_once("./Services/Xml/classes/class.ilXmlWriter.php");
1046  $this->xml = new ilXmlWriter;
1047 
1048  // set dtd definition
1049  $this->xml->xmlSetDtdDef("<!DOCTYPE Test SYSTEM \"http://www.ilias.uni-koeln.de/download/dtd/ilias_co.dtd\">");
1050 
1051  // set generated comment
1052  $this->xml->xmlSetGenCmt("Export of ILIAS Test ".
1053  $this->test_obj->getId()." of installation ".$this->inst.".");
1054 
1055  // set xml header
1056  $this->xml->xmlHeader();
1057 
1058  // create directories
1059  $this->test_obj->createExportDirectory();
1060  include_once "./Services/Utilities/classes/class.ilUtil.php";
1061  ilUtil::makeDir($this->export_dir."/".$this->subdir);
1062  ilUtil::makeDir($this->export_dir."/".$this->subdir."/objects");
1063 
1064  // get Log File
1065  $expDir = $this->test_obj->getExportDirectory();
1066  include_once "./Services/Logging/classes/class.ilLog.php";
1067  $expLog = new ilLog($expDir, "export.log");
1068  $expLog->delete();
1069  $expLog->setLogFormat("");
1070  $expLog->write(date("[y-m-d H:i:s] ")."Start Export");
1071 
1072  // write qti file
1073  $qti_file = fopen($this->export_dir."/".$this->subdir."/".$this->qti_filename, "w");
1074  fwrite($qti_file, $this->test_obj->toXML());
1075  fclose($qti_file);
1076 
1077  // get xml content
1078  $ilBench->start("TestExport", "buildExportFile_getXML");
1079  $this->test_obj->exportPagesXML($this->xml, $this->inst_id,
1080  $this->export_dir."/".$this->subdir, $expLog);
1081  $ilBench->stop("TestExport", "buildExportFile_getXML");
1082 
1083  // dump xml document to screen (only for debugging reasons)
1084  /*
1085  echo "<PRE>";
1086  echo htmlentities($this->xml->xmlDumpMem($format));
1087  echo "</PRE>";
1088  */
1089 
1090  // dump xml document to file
1091  $ilBench->start("TestExport", "buildExportFile_dumpToFile");
1092  $this->xml->xmlDumpFile($this->export_dir."/".$this->subdir."/".$this->filename
1093  , false);
1094  $ilBench->stop("TestExport", "buildExportFile_dumpToFile");
1095 
1096  if ($this->isResultExportingEnabledForTestExport() && @file_exists("./Modules/Test/classes/class.ilTestResultsToXML.php"))
1097  {
1098  // dump results xml document to file
1099  include_once "./Modules/Test/classes/class.ilTestResultsToXML.php";
1100  $resultwriter = new ilTestResultsToXML($this->test_obj->getTestId(), $this->test_obj->getAnonymity());
1101  $ilBench->start("TestExport", "buildExportFile_results");
1102  $resultwriter->xmlDumpFile($this->export_dir."/".$this->subdir."/".$this->resultsfile, false);
1103  $ilBench->stop("TestExport", "buildExportFile_results");
1104  }
1105 
1106  // add media objects which were added with tiny mce
1107  $ilBench->start("QuestionpoolExport", "buildExportFile_saveAdditionalMobs");
1108  $this->exportXHTMLMediaObjects($this->export_dir."/".$this->subdir);
1109  $ilBench->stop("QuestionpoolExport", "buildExportFile_saveAdditionalMobs");
1110 
1111  // zip the file
1112  $ilBench->start("TestExport", "buildExportFile_zipFile");
1113  ilUtil::zip($this->export_dir."/".$this->subdir,
1114  $this->export_dir."/".$this->subdir.".zip");
1115  $ilBench->stop("TestExport", "buildExportFile_zipFile");
1116 
1117  // destroy writer object
1118  $this->xml->_XmlWriter;
1119 
1120  $expLog->write(date("[y-m-d H:i:s] ")."Finished Export");
1121  $ilBench->stop("TestExport", "buildExportFile");
1122 
1123  return $this->export_dir."/".$this->subdir.".zip";
1124  }
1125 
1126  function exportXHTMLMediaObjects($a_export_dir)
1127  {
1128  include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
1129 
1130  $mobs = ilObjMediaObject::_getMobsOfObject("tst:html", $this->test_obj->getId());
1131  foreach ($mobs as $mob)
1132  {
1133  if (ilObjMediaObject::_exists($mob))
1134  {
1135  $mob_obj =& new ilObjMediaObject($mob);
1136  $mob_obj->exportFiles($a_export_dir);
1137  unset($mob_obj);
1138  }
1139  }
1140  foreach ($this->test_obj->questions as $question_id)
1141  {
1142  $mobs = ilObjMediaObject::_getMobsOfObject("qpl:html", $question_id);
1143  foreach ($mobs as $mob)
1144  {
1145  if (ilObjMediaObject::_exists($mob))
1146  {
1147  $mob_obj =& new ilObjMediaObject($mob);
1148  $mob_obj->exportFiles($a_export_dir);
1149  unset($mob_obj);
1150  }
1151  }
1152  }
1153  }
1154 
1155 }
1156 
1157 ?>
static deliverData($a_data, $a_filename, $mime="application/octet-stream", $charset="")
deliver data for download via browser.
print $file
static _instanciateQuestion($question_id)
Creates an instance of a question with a given question id.
exit
Definition: login.php:54
$separator
exportToExcel($deliver=TRUE, $filterby="", $filtertext="", $passedonly=FALSE)
Exports the evaluation data to the Microsoft Excel file format.
aggregatedResultsToExcel($deliver=TRUE)
Exports the aggregated results to the Microsoft Excel file format.
xmlSetDtdDef($dtdDef)
Sets dtd definition.
_lookupFields($a_user_id)
lookup fields (deprecated; use more specific methods instead)
_convert_text($a_text, $a_target="has been removed")
XML writer class.
buildExportFileXML()
build xml export file
Export class for tests.
Test results to XML class.
logging
Definition: class.ilLog.php:18
isResultExportingEnabledForTestExport()
aggregatedResultsToCSV($deliver=TRUE)
Exports the aggregated results to CSV.
exportToCSV($deliver=TRUE, $filterby="", $filtertext="", $passedonly=FALSE)
Exports the evaluation data to the CSV file format.
static getASCIIFilename($a_filename)
convert utf8 to ascii filename
__construct(&$a_test_obj, $a_mode="xml")
Constructor.
Class ilExcelWriterAdapter.
buildExportFile()
build export file (complete zip file)
$data
$mobs
static _exists($a_id)
checks wether a lm content object with specified id exists or not
exportXHTMLMediaObjects($a_export_dir)
redirection script todo: (a better solution should control the processing via a xml file) ...
Class ilObjMediaObject.
static deliverFile($a_file, $a_filename, $a_mime='', $isInline=false, $removeAfterDelivery=false, $a_exit_after=true)
deliver file for download via browser.
static zip($a_dir, $a_file, $compress_content=false)
zips given directory/file into given zip.file
static _instantiateQuestion($question_id)
$filename
Definition: buildRTE.php:89
_getMobsOfObject($a_type, $a_id, $a_usage_hist_nr=0, $a_lang="-")
get mobs of object
static makeDir($a_dir)
creates a new directory and inherits all filesystem permissions of the parent directory You may pass ...
setResultExportingEnabledForTestExport($resultExprtingEnabledForTestExport)
static ilTempnam($a_temp_path=null)
Create a temporary file in an ILIAS writable directory.
formatDate($a_date, $a_mode="datetime", $a_omit_seconds=false, $a_relative=TRUE)
format a date according to the user language shortcut for Format::fmtDateTime public ...
global $ilBench
Definition: ilias.php:18
global $ilDB
buildExportResultFile()
build xml export file
static excelTime($year="", $month="", $day="", $hour="", $minute="", $second="")
Calculates a Microsoft Excel date/time value.
const SCORE_BEST_PASS
xmlDumpFile($file, $format=TRUE)