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