ILIAS  release_5-1 Revision 5.0.0-5477-g43f3e3fab5f
class.ilTestServiceGUI.php
Go to the documentation of this file.
1<?php
2/* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4include_once "./Modules/Test/classes/inc.AssessmentConstants.php";
5include_once 'Modules/Test/classes/class.ilTestService.php';
6
22{
26 public $object = null;
27
31 public $service = null;
32
36 protected $db;
37
38 var $lng;
39 var $tpl;
40
44 var $ctrl;
45
49 protected $tabs;
50
54 protected $objCache;
55
56 var $ilias;
57 var $tree;
59
65 protected $testSessionFactory = null;
66
72 protected $testSequenceFactory = null;
73
78
83
85
90 {
92 }
93
98 {
99 $this->contextResultPresentation = $contextResultPresentation;
100 }
101
108 function ilTestServiceGUI(ilObjTest $a_object)
109 {
110 global $lng, $tpl, $ilCtrl, $ilias, $tree, $ilDB, $ilPluginAdmin, $ilTabs, $ilObjDataCache;
111
112 $this->db = $ilDB;
113 $this->lng =& $lng;
114 $this->tpl =& $tpl;
115 $this->ctrl =& $ilCtrl;
116 $this->tabs = $ilTabs;
117 $this->objCache = $ilObjDataCache;
118 $this->ilias =& $ilias;
119 $this->object =& $a_object;
120 $this->tree =& $tree;
121 $this->ref_id = $a_object->ref_id;
122
123 $this->service = new ilTestService($a_object);
124
125 require_once 'Modules/Test/classes/class.ilTestSessionFactory.php';
126 $this->testSessionFactory = new ilTestSessionFactory($this->object);
127
128 require_once 'Modules/Test/classes/class.ilTestSequenceFactory.php';
129 $this->testSequenceFactory = new ilTestSequenceFactory($ilDB, $lng, $ilPluginAdmin, $this->object);
130
131 $this->objectiveOrientedContainer = null;
132 }
133
138 {
139 $this->participantData = $participantData;
140 }
141
145 public function getParticipantData()
146 {
148 }
149
155 public function getPassOverviewTableData(ilTestSession $testSession, $passes, $withResults)
156 {
157 $data = array();
158
159 if($this->getObjectiveOrientedContainer()->isObjectiveOrientedPresentationRequired())
160 {
161 $considerHiddenQuestions = false;
162
163 require_once 'Modules/Course/classes/Objectives/class.ilLOTestQuestionAdapter.php';
164 $objectivesAdapter = ilLOTestQuestionAdapter::getInstance($testSession);
165 }
166 else
167 {
168 $considerHiddenQuestions = true;
169 }
170
171 $scoredPass = $this->object->_getResultPass($testSession->getActiveId());
172
173 foreach($passes as $pass)
174 {
175 $row = array();
176
177 $considerOptionalQuestions = true;
178
179 if($this->getObjectiveOrientedContainer()->isObjectiveOrientedPresentationRequired())
180 {
181 $testSequence = $this->testSequenceFactory->getSequenceByActiveIdAndPass($testSession->getActiveId(), $pass);
182
183 $testSequence->loadFromDb();
184 $testSequence->loadQuestions();
185
186 if($this->object->isRandomTest() && !$testSequence->isAnsweringOptionalQuestionsConfirmed())
187 {
188 $considerOptionalQuestions = false;
189 }
190
191 $testSequence->setConsiderHiddenQuestionsEnabled($considerHiddenQuestions);
192 $testSequence->setConsiderOptionalQuestionsEnabled($considerOptionalQuestions);
193
194 $objectivesList = $this->buildQuestionRelatedObjectivesList($objectivesAdapter, $testSequence);
195 $objectivesList->loadObjectivesTitles();
196
197 $row['objectives'] = $objectivesList->getUniqueObjectivesStringForQuestions($testSequence->getUserSequenceQuestions());
198 }
199
200 if($withResults)
201 {
202 $result_array = $this->object->getTestResult($testSession->getActiveId(), $pass, false, $considerHiddenQuestions, $considerOptionalQuestions);
203 if(!$result_array['pass']['total_max_points'])
204 {
205 $percentage = 0;
206 } else
207 {
208 $percentage = ($result_array['pass']['total_reached_points'] / $result_array['pass']['total_max_points']) * 100;
209 }
210 $total_max = $result_array['pass']['total_max_points'];
211 $total_reached = $result_array['pass']['total_reached_points'];
212 $total_requested_hints = $result_array['pass']['total_requested_hints'];
213 }
214
215 if($withResults)
216 {
217 $row['scored'] = ($pass == $scoredPass);
218 }
219
220 $row['pass'] = $pass;
221 $row['date'] = $this->object->getPassFinishDate($testSession->getActiveId(), $pass);
222 if($withResults)
223 {
224 $row['num_workedthrough_questions'] = $result_array['pass']['num_workedthrough'];
225 $row['num_questions_total'] = $result_array['pass']['num_questions_total'];
226
227 if($this->object->isOfferingQuestionHintsEnabled())
228 {
229 $row['hints'] = $total_requested_hints;
230 }
231
232 $row['reached_points'] = $total_reached;
233 $row['max_points'] = $total_max;
234 $row['percentage'] = $percentage;
235 }
236
237 $data[] = $row;
238 }
239
240 return $data;
241 }
242
247 {
248 $this->objectiveOrientedContainer = $objectiveOrientedContainer;
249 }
250
255 {
257 }
258
262 function &executeCommand()
263 {
264 $cmd = $this->ctrl->getCmd();
265 $next_class = $this->ctrl->getNextClass($this);
266
267 $cmd = $this->getCommand($cmd);
268 switch($next_class)
269 {
270 default:
271 $ret =& $this->$cmd();
272 break;
273 }
274 return $ret;
275 }
276
282 function getCommand($cmd)
283 {
284 return $cmd;
285 }
286
287 protected function handleTabs($activeTabId)
288 {
289 if( $this->getObjectiveOrientedContainer()->isObjectiveOrientedPresentationRequired() )
290 {
291 require_once 'Services/Link/classes/class.ilLink.php';
292 $courseLink = ilLink::_getLink($this->getObjectiveOrientedContainer()->getRefId());
293 $this->tabs->setBack2Target($this->lng->txt('back_to_objective_container'), $courseLink);
294
295 $this->tabs->addTab(
296 'results_pass_oriented', $this->lng->txt('tst_tab_results_pass_oriented'),
297 $this->ctrl->getLinkTargetByClass('ilTestEvaluationGUI', 'outUserResultsOverview')
298 );
299
300 $this->tabs->addTab(
301 'results_objective_oriented', $this->lng->txt('tst_tab_results_objective_oriented'),
302 $this->ctrl->getLinkTargetByClass('ilTestEvalObjectiveOrientedGUI', 'showVirtualPass')
303 );
304
305 $this->tabs->setTabActive($activeTabId);
306 }
307 }
308
312 protected function isPdfDeliveryRequest()
313 {
314 if( !isset($_GET['pdf']) )
315 {
316 return false;
317 }
318
319 if( !(bool)$_GET['pdf'] )
320 {
321 return false;
322 }
323
324 return true;
325 }
326
330 public function buildPassOverviewTableGUI($targetGUI, $targetCmd = '')
331 {
332 require_once 'Modules/Test/classes/tables/class.ilTestPassOverviewTableGUI.php';
333
334 $table = new ilTestPassOverviewTableGUI($targetGUI, $targetCmd);
335
336 $table->setPdfPresentationEnabled(
337 isset($_GET['pdf']) && $_GET['pdf'] == 1
338 );
339
340 $table->setObjectiveOrientedPresentationEnabled(
341 $this->getObjectiveOrientedContainer()->isObjectiveOrientedPresentationRequired()
342 );
343
344 return $table;
345 }
346
357 function getPassListOfAnswers(&$result_array, $active_id, $pass, $show_solutions = FALSE, $only_answered_questions = FALSE, $show_question_only = FALSE, $show_reached_points = FALSE, $anchorNav = false, ilTestQuestionRelatedObjectivesList $objectivesList = null, ilTestResultHeaderLabelBuilder $testResultHeaderLabelBuilder = null)
358 {
359 $maintemplate = new ilTemplate("tpl.il_as_tst_list_of_answers.html", TRUE, TRUE, "Modules/Test");
360
361 $counter = 1;
362 // output of questions with solutions
363 foreach ($result_array as $question_data)
364 {
365 if (($question_data["workedthrough"] == 1) || ($only_answered_questions == FALSE))
366 {
367 $template = new ilTemplate("tpl.il_as_qpl_question_printview.html", TRUE, TRUE, "Modules/TestQuestionPool");
368 $question = $question_data["qid"];
369 if (is_numeric($question))
370 {
371 $maintemplate->setCurrentBlock("printview_question");
372 $question_gui = $this->object->createQuestionGUI("", $question);
373 if (is_object($question_gui))
374 {
375 if( $this->isPdfDeliveryRequest() )
376 {
377 $question_gui->setOutputMode(assQuestionGUI::OUTPUT_MODE_PDF);
378 }
379
380 if($anchorNav)
381 {
382 $template->setCurrentBlock('block_id');
383 $template->setVariable('BLOCK_ID', "detailed_answer_block_act_{$active_id}_qst_{$question}");
384 $template->parseCurrentBlock();
385
386 $template->setCurrentBlock('back_anchor');
387 $template->setVariable('HREF_BACK_ANCHOR', "#pass_details_tbl_row_act_{$active_id}_qst_{$question}");
388 $template->setVariable('TXT_BACK_ANCHOR', $this->lng->txt('tst_back_to_question_list'));
389 $template->parseCurrentBlock();
390 }
391
392 if ($show_reached_points)
393 {
394 $template->setCurrentBlock("result_points");
395 $template->setVariable("RESULT_POINTS", $this->lng->txt("tst_reached_points") . ": " . $question_gui->object->getReachedPoints($active_id, $pass) . " " . $this->lng->txt("of") . " " . $question_gui->object->getMaximumPoints());
396 $template->parseCurrentBlock();
397 }
398 $template->setVariable("COUNTER_QUESTION", $counter.". ");
399 $template->setVariable("TXT_QUESTION_ID", $this->lng->txt('question_id_short'));
400 $template->setVariable("QUESTION_ID", $question_gui->object->getId());
401 $template->setVariable("QUESTION_TITLE", $this->object->getQuestionTitle($question_gui->object->getTitle()));
402
403 if( $objectivesList !== null )
404 {
405 $objectives = $this->lng->txt('tst_res_lo_objectives_header').': ';
406 $objectives .= $objectivesList->getQuestionRelatedObjectiveTitles($question_gui->object->getId());
407 $template->setVariable("OBJECTIVES", $objectives);
408 }
409
410 $show_question_only = ($this->object->getShowSolutionAnswersOnly()) ? TRUE : FALSE;
411
412 $showFeedback = $this->isContextResultPresentation() && $this->object->getShowSolutionFeedback();
413 $show_solutions = $this->isContextResultPresentation() && $show_solutions;
414
415 if($show_solutions)
416 {
417 $compare_template = new ilTemplate('tpl.il_as_tst_answers_compare.html', TRUE, TRUE, 'Modules/Test');
418 $compare_template->setVariable("HEADER_PARTICIPANT", $this->lng->txt('tst_header_participant'));
419 $compare_template->setVariable("HEADER_SOLUTION", $this->lng->txt('tst_header_solution'));
420 $result_output = $question_gui->getSolutionOutput($active_id, $pass, $show_solutions, FALSE, $show_question_only, $showFeedback);
421 $best_output = $question_gui->getSolutionOutput($active_id, $pass, FALSE, FALSE, $show_question_only, FALSE, TRUE);
422
423 $compare_template->setVariable('PARTICIPANT', $result_output);
424 $compare_template->setVariable('SOLUTION', $best_output);
425 $template->setVariable('SOLUTION_OUTPUT', $compare_template->get());
426 }
427 else
428 {
429 $result_output = $question_gui->getSolutionOutput($active_id, $pass, $show_solutions, FALSE, $show_question_only, $showFeedback);
430 $template->setVariable('SOLUTION_OUTPUT', $result_output);
431 }
432
433 $maintemplate->setCurrentBlock("printview_question");
434 $maintemplate->setVariable("QUESTION_PRINTVIEW", $template->get());
435 $maintemplate->parseCurrentBlock();
436 $counter ++;
437 }
438 }
439 }
440 }
441
442 if($pass !== null)
443 {
444 $headerText = $testResultHeaderLabelBuilder->getListOfAnswersHeaderLabel($pass + 1);
445 }
446 else
447 {
448 $headerText = $testResultHeaderLabelBuilder->getVirtualListOfAnswersHeaderLabel();
449 }
450
451 $maintemplate->setVariable("RESULTS_OVERVIEW", $headerText);
452 return $maintemplate->get();
453 }
454
467 function getPassListOfAnswersWithScoring(&$result_array, $active_id, $pass, $show_solutions = FALSE)
468 {
469 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
470
471 $maintemplate = new ilTemplate("tpl.il_as_tst_list_of_answers.html", TRUE, TRUE, "Modules/Test");
472
473 include_once "./Modules/Test/classes/class.ilObjAssessmentFolder.php";
475
476 $counter = 1;
477 // output of questions with solutions
478 foreach ($result_array as $question_data)
479 {
480 $question = $question_data["qid"];
481 if (is_numeric($question))
482 {
483 $question_gui = $this->object->createQuestionGUI("", $question);
484 if (in_array($question_gui->object->getQuestionTypeID(), $scoring))
485 {
486 $template = new ilTemplate("tpl.il_as_qpl_question_printview.html", TRUE, TRUE, "Modules/TestQuestionPool");
487 $scoretemplate = new ilTemplate("tpl.il_as_tst_manual_scoring_points.html", TRUE, TRUE, "Modules/Test");
488 #mbecker: No such block. $this->tpl->setCurrentBlock("printview_question");
489 $template->setVariable("COUNTER_QUESTION", $counter.". ");
490 $template->setVariable("QUESTION_TITLE", $this->object->getQuestionTitle($question_gui->object->getTitle()));
491 $points = $question_gui->object->getMaximumPoints();
492 if ($points == 1)
493 {
494 $template->setVariable("QUESTION_POINTS", $points . " " . $this->lng->txt("point"));
495 }
496 else
497 {
498 $template->setVariable("QUESTION_POINTS", $points . " " . $this->lng->txt("points"));
499 }
500
501 $show_question_only = ($this->object->getShowSolutionAnswersOnly()) ? TRUE : FALSE;
502 $result_output = $question_gui->getSolutionOutput($active_id, $pass, $show_solutions, FALSE, $show_question_only, $this->object->getShowSolutionFeedback(), FALSE, TRUE);
503
504 $solout = $question_gui->object->getSuggestedSolutionOutput();
505 if (strlen($solout))
506 {
507 $scoretemplate->setCurrentBlock("suggested_solution");
508 $scoretemplate->setVariable("TEXT_SUGGESTED_SOLUTION", $this->lng->txt("solution_hint"));
509 $scoretemplate->setVariable("VALUE_SUGGESTED_SOLUTION", $solout);
510 $scoretemplate->parseCurrentBlock();
511 }
512
513 $scoretemplate->setCurrentBlock("feedback");
514 $scoretemplate->setVariable("FEEDBACK_NAME_INPUT", $question);
515 $feedback = $this->object->getManualFeedback($active_id, $question, $pass);
516 $scoretemplate->setVariable("VALUE_FEEDBACK", ilUtil::prepareFormOutput($this->object->prepareTextareaOutput($feedback, TRUE)));
517 $scoretemplate->setVariable("TEXT_MANUAL_FEEDBACK", $this->lng->txt("set_manual_feedback"));
518 $scoretemplate->parseCurrentBlock();
519
520 $scoretemplate->setVariable("NAME_INPUT", $question);
521 $this->ctrl->setParameter($this, "active_id", $active_id);
522 $this->ctrl->setParameter($this, "pass", $pass);
523 $scoretemplate->setVariable("FORMACTION", $this->ctrl->getFormAction($this, "manscoring"));
524 $scoretemplate->setVariable("LABEL_INPUT", $this->lng->txt("tst_change_points_for_question"));
525 $scoretemplate->setVariable("VALUE_INPUT", " value=\"" . assQuestion::_getReachedPoints($active_id, $question_data["qid"], $pass) . "\"");
526 $scoretemplate->setVariable("VALUE_SAVE", $this->lng->txt("save"));
527
528 $template->setVariable("SOLUTION_OUTPUT", $result_output);
529 $maintemplate->setCurrentBlock("printview_question");
530 $maintemplate->setVariable("QUESTION_PRINTVIEW", $template->get());
531 $maintemplate->setVariable("QUESTION_SCORING", $scoretemplate->get());
532 $maintemplate->parseCurrentBlock();
533 }
534 $counter ++;
535 }
536 }
537 if ($counter == 1)
538 {
539 // no scorable questions found
540 $maintemplate->setVariable("NO_QUESTIONS_FOUND", $this->lng->txt("manscoring_questions_not_found"));
541 }
542 $maintemplate->setVariable("RESULTS_OVERVIEW", sprintf($this->lng->txt("manscoring_results_pass"), $pass+1));
543
544 include_once "./Services/YUI/classes/class.ilYuiUtil.php";
546
547 return $maintemplate->get();
548 }
549
550 protected function getPassDetailsOverviewTableGUI($result_array, $active_id, $pass, $targetGUI, $targetCMD, $questionDetailsCMD, $questionAnchorNav, ilTestQuestionRelatedObjectivesList $objectivesList = null)
551 {
552 $this->ctrl->setParameter($targetGUI, 'active_id', $active_id);
553 $this->ctrl->setParameter($targetGUI, 'pass', $pass);
554
555 $tableGUI = $this->buildPassDetailsOverviewTableGUI($targetGUI, $targetCMD);
556
557 $tableGUI->setAnswerListAnchorEnabled($questionAnchorNav);
558 $tableGUI->setSingleAnswerScreenCmd($questionDetailsCMD);
559 $tableGUI->setShowHintCount($this->object->isOfferingQuestionHintsEnabled());
560
561 if( $objectivesList !== null )
562 {
563 $tableGUI->setQuestionRelatedObjectivesList($objectivesList);
564 $tableGUI->setObjectiveOrientedPresentationEnabled(true);
565 }
566
567 $tableGUI->setActiveId($active_id);
568 $tableGUI->setShowSuggestedSolution(false);
569
570 $usersQuestionSolutions = array();
571
572 foreach($result_array as $key => $val)
573 {
574 if($key === 'test' || $key === 'pass')
575 {
576 continue;
577 }
578
579 if( $this->object->getShowSolutionSuggested() && strlen($val['solution']) )
580 {
581 $tableGUI->setShowSuggestedSolution(true);
582 }
583
584 if( isset($val['pass']) )
585 {
586 $tableGUI->setPassColumnEnabled(true);
587 }
588
589 $usersQuestionSolutions[$key] = $val;
590 }
591
592 $tableGUI->initColumns()->initFilter();
593
594 $tableGUI->setFilterCommand($targetCMD.'SetTableFilter');
595 $tableGUI->setResetCommand($targetCMD.'ResetTableFilter');
596
597 $tableGUI->setData($usersQuestionSolutions);
598
599 return $tableGUI;
600 }
601
609 {
610 if ($this->object->getShowSolutionSignature() && !$this->object->getAnonymity())
611 {
612 $template = new ilTemplate("tpl.il_as_tst_results_userdata_signature.html", TRUE, TRUE, "Modules/Test");
613 $template->setVariable("TXT_DATE", $this->lng->txt("date"));
616 $template->setVariable("VALUE_DATE", ilDatePresentation::formatDate(new ilDate(time(), IL_CAL_UNIX)));
618 $template->setVariable("TXT_SIGNATURE", $this->lng->txt("tst_signature"));
619 $template->setVariable("IMG_SPACER", ilUtil::getImagePath("spacer.png"));
620 return $template->get();
621 }
622 else
623 {
624 return "";
625 }
626 }
627
637 function getAdditionalUsrDataHtmlAndPopulateWindowTitle($testSession, $active_id, $overwrite_anonymity = FALSE)
638 {
639 if(!is_object($testSession)) throw new TestException();
640 $template = new ilTemplate("tpl.il_as_tst_results_userdata.html", TRUE, TRUE, "Modules/Test");
641 include_once './Services/User/classes/class.ilObjUser.php';
642 $user_id = $this->object->_getUserIdFromActiveId($active_id);
643 if (strlen(ilObjUser::_lookupLogin($user_id)) > 0)
644 {
645 $user = new ilObjUser($user_id);
646 }
647 else
648 {
649 $user = new ilObjUser();
650 $user->setLastname($this->lng->txt("deleted_user"));
651 }
652 $t = $testSession->getSubmittedTimestamp();
653 if (!$t)
654 {
655 $t = $this->object->_getLastAccess($testSession->getActiveId());
656 }
657
658 if( $this->getObjectiveOrientedContainer()->isObjectiveOrientedPresentationRequired() )
659 {
660 $uname = $this->object->userLookupFullName($user_id, $overwrite_anonymity);
661 $template->setCurrentBlock("name");
662 $template->setVariable('TXT_USR_NAME', $this->lng->txt("name"));
663 $template->setVariable('VALUE_USR_NAME', $uname);
664 $template->parseCurrentBlock();
665 }
666
667 $title_matric = "";
668 if (strlen($user->getMatriculation()) && (($this->object->getAnonymity() == FALSE) || ($overwrite_anonymity)))
669 {
670 $template->setCurrentBlock("matriculation");
671 $template->setVariable("TXT_USR_MATRIC", $this->lng->txt("matriculation"));
672 $template->setVariable("VALUE_USR_MATRIC", $user->getMatriculation());
673 $template->parseCurrentBlock();
674 $title_matric = " - " . $this->lng->txt("matriculation") . ": " . $user->getMatriculation();
675 }
676
677 $invited_user = array_pop($this->object->getInvitedUsers($user_id));
678 if (strlen($invited_user["clientip"]))
679 {
680 $template->setCurrentBlock("client_ip");
681 $template->setVariable("TXT_CLIENT_IP", $this->lng->txt("client_ip"));
682 $template->setVariable("VALUE_CLIENT_IP", $invited_user["clientip"]);
683 $template->parseCurrentBlock();
684 $title_client = " - " . $this->lng->txt("clientip") . ": " . $invited_user["clientip"];
685 }
686
687 $template->setVariable("TXT_TEST_TITLE", $this->lng->txt("title"));
688 $template->setVariable("VALUE_TEST_TITLE", $this->object->getTitle());
689
690 // change the pagetitle (tab title or title in title bar of window)
691 $pagetitle = $this->object->getTitle() . $title_matric . $title_client;
692 $this->tpl->setHeaderPageTitle($pagetitle);
693
694 return $template->get();
695 }
696
706 function getCorrectSolutionOutput($question_id, $active_id, $pass, ilTestQuestionRelatedObjectivesList $objectivesList = null)
707 {
708 global $ilUser;
709
710 $test_id = $this->object->getTestId();
711 $question_gui = $this->object->createQuestionGUI("", $question_id);
712
713 if( $this->isPdfDeliveryRequest() )
714 {
715 $question_gui->setOutputMode(assQuestionGUI::OUTPUT_MODE_PDF);
716 }
717
718 $template = new ilTemplate("tpl.il_as_tst_correct_solution_output.html", TRUE, TRUE, "Modules/Test");
719 $show_question_only = ($this->object->getShowSolutionAnswersOnly()) ? TRUE : FALSE;
720 $result_output = $question_gui->getSolutionOutput($active_id, $pass, TRUE, FALSE, $show_question_only, $this->object->getShowSolutionFeedback(), FALSE, FALSE, TRUE);
721 $best_output = $question_gui->getSolutionOutput($active_id, $pass, FALSE, FALSE, $show_question_only, FALSE, TRUE, FALSE, FALSE);
722 if( $this->object->getShowSolutionFeedback() && $_GET['cmd'] != 'outCorrectSolution' )
723 {
724 $specificAnswerFeedback = $question_gui->getSpecificFeedbackOutput($active_id, $pass);
725 if( strlen($specificAnswerFeedback) )
726 {
727 $template->setCurrentBlock("outline_specific_feedback");
728 $template->setVariable("OUTLINE_SPECIFIC_FEEDBACK", $specificAnswerFeedback);
729 $template->parseCurrentBlock();
730 }
731 }
732 if ($this->object->isBestSolutionPrintedWithResult() && strlen($best_output))
733 {
734 $template->setCurrentBlock("best_solution");
735 $template->setVariable("TEXT_BEST_SOLUTION", $this->lng->txt("tst_best_solution_is"));
736 $template->setVariable("BEST_OUTPUT", $best_output);
737 $template->parseCurrentBlock();
738 }
739 $template->setVariable("TEXT_YOUR_SOLUTION", $this->lng->txt("tst_your_answer_was"));
740 $maxpoints = $question_gui->object->getMaximumPoints();
741 if ($maxpoints == 1)
742 {
743 $template->setVariable("QUESTION_TITLE", $this->object->getQuestionTitle($question_gui->object->getTitle()) . " (" . $maxpoints . " " . $this->lng->txt("point") . ")");
744 }
745 else
746 {
747 $template->setVariable("QUESTION_TITLE", $this->object->getQuestionTitle($question_gui->object->getTitle()) . " (" . $maxpoints . " " . $this->lng->txt("points") . ")");
748 }
749 if( $objectivesList !== null )
750 {
751 $objectives = $this->lng->txt('tst_res_lo_objectives_header').': ';
752 $objectives .= $objectivesList->getQuestionRelatedObjectiveTitles($question_gui->object->getId());
753 $template->setVariable('OBJECTIVES', $objectives);
754 }
755 $template->setVariable("SOLUTION_OUTPUT", $result_output);
756 $template->setVariable("RECEIVED_POINTS", sprintf($this->lng->txt("you_received_a_of_b_points"), $question_gui->object->getReachedPoints($active_id, $pass), $maxpoints));
757 $template->setVariable("FORMACTION", $this->ctrl->getFormAction($this));
758 $template->setVariable("BACKLINK_TEXT", "&lt;&lt; " . $this->lng->txt("back"));
759 return $template->get();
760 }
761
774 function getResultsOfUserOutput($testSession, $active_id, $pass, $targetGUI, $show_pass_details = TRUE, $show_answers = TRUE, $show_question_only = FALSE, $show_reached_points = FALSE)
775 {
776 global $ilObjDataCache;
777
778 include_once("./Services/UICore/classes/class.ilTemplate.php");
779 $template = new ilTemplate("tpl.il_as_tst_results_participant.html", TRUE, TRUE, "Modules/Test");
780
781 if( $this->participantData instanceof ilTestParticipantData )
782 {
783 $user_id = $this->participantData->getUserIdByActiveId($active_id);
784 $uname = $this->participantData->getConcatedFullnameByActiveId($active_id, false);
785 }
786 else
787 {
788 $user_id = $this->object->_getUserIdFromActiveId($active_id);
789 $uname = $this->object->userLookupFullName($user_id, TRUE);
790 }
791
792 if (((array_key_exists("pass", $_GET)) && (strlen($_GET["pass"]) > 0)) || (!is_null($pass)))
793 {
794 if (is_null($pass)) $pass = $_GET["pass"];
795 }
796
797 if (!is_null($pass))
798 {
799 require_once 'Modules/Test/classes/class.ilTestResultHeaderLabelBuilder.php';
800 $testResultHeaderLabelBuilder = new ilTestResultHeaderLabelBuilder($this->lng, $ilObjDataCache);
801
802 $objectivesList = null;
803
804 if( $this->getObjectiveOrientedContainer()->isObjectiveOrientedPresentationRequired() )
805 {
806 $testSequence = $this->testSequenceFactory->getSequenceByActiveIdAndPass($active_id, $pass);
807 $testSequence->loadFromDb();
808 $testSequence->loadQuestions();
809
810 require_once 'Modules/Course/classes/Objectives/class.ilLOTestQuestionAdapter.php';
811 $objectivesAdapter = ilLOTestQuestionAdapter::getInstance($testSession);
812
813 $objectivesList = $this->buildQuestionRelatedObjectivesList($objectivesAdapter, $testSequence);
814 $objectivesList->loadObjectivesTitles();
815
816 $testResultHeaderLabelBuilder->setObjectiveOrientedContainerId($testSession->getObjectiveOrientedContainerId());
817 $testResultHeaderLabelBuilder->setUserId($testSession->getUserId());
818 $testResultHeaderLabelBuilder->setTestObjId($this->object->getId());
819 $testResultHeaderLabelBuilder->setTestRefId($this->object->getRefId());
820 $testResultHeaderLabelBuilder->initObjectiveOrientedMode();
821 }
822
823 $result_array = $this->object->getTestResult(
824 $active_id, $pass, false, !$this->getObjectiveOrientedContainer()->isObjectiveOrientedPresentationRequired()
825 );
826
827 $user_id = $this->object->_getUserIdFromActiveId($active_id);
828 $showAllAnswers = TRUE;
829 if ($this->object->isExecutable($testSession, $user_id))
830 {
831 $showAllAnswers = FALSE;
832 }
833 if ($show_answers)
834 {
835 $list_of_answers = $this->getPassListOfAnswers(
836 $result_array, $active_id, $pass, $_SESSION['tst_results_show_best_solutions'],
837 $showAllAnswers, $show_question_only, $show_reached_points, $show_pass_details,
838 $objectivesList, $testResultHeaderLabelBuilder
839 );
840 $template->setVariable("LIST_OF_ANSWERS", $list_of_answers);
841 }
842
843 if ($show_pass_details)
844 {
845 $overviewTableGUI = $this->getPassDetailsOverviewTableGUI($result_array, $active_id, $pass, $targetGUI, "getResultsOfUserOutput", '', $show_answers, $objectivesList);
846 $overviewTableGUI->setTitle($testResultHeaderLabelBuilder->getPassDetailsHeaderLabel($pass + 1));
847 $template->setVariable("PASS_DETAILS", $overviewTableGUI->getHTML());
848 }
849
850 $signature = $this->getResultsSignature();
851 $template->setVariable("SIGNATURE", $signature);
852
853 if ($this->object->isShowExamIdInTestResultsEnabled())
854 {
855 $template->setCurrentBlock('exam_id_footer');
856 $template->setVariable('EXAM_ID_VAL', $this->object->lookupExamId(
857 $testSession->getActiveId(), $pass
858 ));
859 $template->setVariable('EXAM_ID_TXT', $this->lng->txt('exam_id'));
860 $template->parseCurrentBlock();
861 }
862 }
863
864 $template->setCurrentBlock('participant_back_anchor');
865 $template->setVariable("HREF_PARTICIPANT_BACK_ANCHOR", "#tst_results_toolbar");
866 $template->setVariable("TXT_PARTICIPANT_BACK_ANCHOR", $this->lng->txt('tst_back_to_top'));
867 $template->parseCurrentBlock();
868
869 $template->setCurrentBlock('participant_block_id');
870 $template->setVariable("PARTICIPANT_BLOCK_ID", "participant_active_{$active_id}");
871 $template->parseCurrentBlock();
872
873 if( $this->isGradingMessageRequired() )
874 {
875 $gradingMessageBuilder = $this->getGradingMessageBuilder($active_id);
876 $gradingMessageBuilder->buildList();
877
878 $template->setCurrentBlock('grading_message');
879 $template->setVariable('GRADING_MESSAGE', $gradingMessageBuilder->getList());
880 $template->parseCurrentBlock();
881 }
882
883
884 $user_data = $this->getAdditionalUsrDataHtmlAndPopulateWindowTitle($testSession, $active_id, TRUE);
885 $template->setVariable("TEXT_HEADING", sprintf($this->lng->txt("tst_result_user_name"), $uname));
886 $template->setVariable("USER_DATA", $user_data);
887
888 $this->populatePassFinishDate($template, $this->object->getPassFinishDate($active_id, $pass));
889
890 return $template->get();
891 }
892
900 function getResultsHeadUserAndPass($active_id, $pass)
901 {
902 $template = new ilTemplate("tpl.il_as_tst_results_head_user_pass.html", TRUE, TRUE, "Modules/Test");
903 include_once './Services/User/classes/class.ilObjUser.php';
904 $user_id = $this->object->_getUserIdFromActiveId($active_id);
905 if (strlen(ilObjUser::_lookupLogin($user_id)) > 0)
906 {
907 $user = new ilObjUser($user_id);
908 }
909 else
910 {
911 $user = new ilObjUser();
912 $user->setLastname($this->lng->txt("deleted_user"));
913 }
914 $title_matric = "";
915 if (strlen($user->getMatriculation()) && (($this->object->getAnonymity() == FALSE)))
916 {
917 $template->setCurrentBlock("user_matric");
918 $template->setVariable("TXT_USR_MATRIC", $this->lng->txt("matriculation"));
919 $template->parseCurrentBlock();
920 $template->setCurrentBlock("user_matric_value");
921 $template->setVariable("VALUE_USR_MATRIC", $user->getMatriculation());
922 $template->parseCurrentBlock();
923 $template->touchBlock("user_matric_separator");
924 $title_matric = " - " . $this->lng->txt("matriculation") . ": " . $user->getMatriculation();
925 }
926
927 $invited_user = array_pop($this->object->getInvitedUsers($user_id));
928 if (strlen($invited_user["clientip"]))
929 {
930 $template->setCurrentBlock("user_clientip");
931 $template->setVariable("TXT_CLIENT_IP", $this->lng->txt("client_ip"));
932 $template->parseCurrentBlock();
933 $template->setCurrentBlock("user_clientip_value");
934 $template->setVariable("VALUE_CLIENT_IP", $invited_user["clientip"]);
935 $template->parseCurrentBlock();
936 $template->touchBlock("user_clientip_separator");
937 $title_client = " - " . $this->lng->txt("clientip") . ": " . $invited_user["clientip"];
938 }
939
940 $template->setVariable("TXT_USR_NAME", $this->lng->txt("name"));
941 $uname = $this->object->userLookupFullName($user_id, FALSE);
942 $template->setVariable("VALUE_USR_NAME", $uname);
943 $template->setVariable("TXT_PASS", $this->lng->txt("scored_pass"));
944 $template->setVariable("VALUE_PASS", $pass);
945 return $template->get();
946 }
947
955 public function getQuestionResultForTestUsers($question_id, $test_id)
956 {
957 // REQUIRED, since we call this object regardless of the loop
958 $question_gui = $this->object->createQuestionGUI("", $question_id);
959
960 $foundusers = $this->object->getParticipantsForTestAndQuestion($test_id, $question_id);
961 $output = '';
962 foreach($foundusers as $active_id => $passes)
963 {
964 $resultpass = $this->object->_getResultPass($active_id);
965 for($i = 0; $i < count($passes); $i++)
966 {
967 if(($resultpass !== null) && ($resultpass == $passes[$i]["pass"]))
968 {
969 if($output)
970 {
971 $output .= "<br /><br /><br />";
972 }
973
974 // check if re-instantiation is really neccessary
975 $question_gui = $this->object->createQuestionGUI("", $passes[$i]["qid"]);
976 $output .= $this->getResultsHeadUserAndPass($active_id, $resultpass + 1);
977 $question_gui->setOutputMode(assQuestionGUI::OUTPUT_MODE_PDF);
978 $output .= $question_gui->getSolutionOutput(
979 $active_id,
980 $resultpass,
981 $graphicalOutput = FALSE,
982 $result_output = FALSE,
983 $show_question_only = FALSE,
984 $show_feedback = FALSE
985 );
986 }
987 }
988 }
989
990 require_once './Modules/Test/classes/class.ilTestPDFGenerator.php';
991 ilTestPDFGenerator::generatePDF($output, ilTestPDFGenerator::PDF_OUTPUT_DOWNLOAD, $question_gui->object->getTitle());
992 }
993
997 protected function buildPassDetailsOverviewTableGUI($targetGUI, $targetCMD)
998 {
999 require_once 'Modules/Test/classes/tables/class.ilTestPassDetailsOverviewTableGUI.php';
1000 $tableGUI = new ilTestPassDetailsOverviewTableGUI($this->ctrl, $targetGUI, $targetCMD);
1001 $tableGUI->setIsPdfGenerationRequest($this->isPdfDeliveryRequest());
1002 return $tableGUI;
1003 }
1004
1005 protected function isGradingMessageRequired()
1006 {
1007 if( $this->getObjectiveOrientedContainer()->isObjectiveOrientedPresentationRequired() )
1008 {
1009 return false;
1010 }
1011
1012 if( $this->object->isShowGradingStatusEnabled() )
1013 {
1014 return true;
1015 }
1016
1017 if( $this->object->isShowGradingMarkEnabled() )
1018 {
1019 return true;
1020 }
1021
1022 if( $this->object->areObligationsEnabled() )
1023 {
1024 return true;
1025 }
1026
1027 return false;
1028 }
1029
1034 protected function getGradingMessageBuilder($activeId)
1035 {
1036 require_once 'Modules/Test/classes/class.ilTestGradingMessageBuilder.php';
1037 $gradingMessageBuilder = new ilTestGradingMessageBuilder($this->lng, $this->object);
1038
1039 $gradingMessageBuilder->setActiveId($activeId);
1040
1041 return $gradingMessageBuilder;
1042 }
1043
1044 protected function buildQuestionRelatedObjectivesList(ilLOTestQuestionAdapter $objectivesAdapter, ilTestQuestionSequence $testSequence)
1045 {
1046 require_once 'Modules/Test/classes/class.ilTestQuestionRelatedObjectivesList.php';
1047 $questionRelatedObjectivesList = new ilTestQuestionRelatedObjectivesList();
1048
1049 $objectivesAdapter->buildQuestionRelatedObjectiveList($testSequence, $questionRelatedObjectivesList);
1050
1051 return $questionRelatedObjectivesList;
1052 }
1053
1054 protected function getFilteredTestResult($active_id, $pass, $considerHiddenQuestions, $considerOptionalQuestions)
1055 {
1056 global $ilDB, $ilPluginAdmin;
1057
1058 $table_gui = $this->buildPassDetailsOverviewTableGUI($this, 'outUserPassDetails');
1059 $table_gui->initFilter();
1060
1061 require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionList.php';
1062 $questionList = new ilAssQuestionList($ilDB, $this->lng, $ilPluginAdmin);
1063
1064 $questionList->setParentObjIdsFilter(array($this->object->getId()));
1065 $questionList->setQuestionInstanceTypeFilter(ilAssQuestionList::QUESTION_INSTANCE_TYPE_DUPLICATES);
1066
1067 foreach ($table_gui->getFilterItems() as $item)
1068 {
1069 if( substr($item->getPostVar(), 0, strlen('tax_')) == 'tax_' )
1070 {
1071 $v = $item->getValue();
1072
1073 if( is_array($v) && count($v) && !(int)$v[0] )
1074 {
1075 continue;
1076 }
1077
1078 $taxId = substr($item->getPostVar(), strlen('tax_'));
1079 $questionList->addTaxonomyFilter($taxId, $item->getValue(), $this->object->getId(), 'tst');
1080 }
1081 elseif( $item->getValue() !== false )
1082 {
1083 $questionList->addFieldFilter($item->getPostVar(), $item->getValue());
1084 }
1085 }
1086
1087 $questionList->load();
1088
1089 $filteredTestResult = array();
1090
1091 $resultData = $this->object->getTestResult($active_id, $pass, false, $considerHiddenQuestions, $considerOptionalQuestions);
1092
1093 foreach($resultData as $resultItemKey => $resultItemValue)
1094 {
1095 if($resultItemKey === 'test' || $resultItemKey === 'pass')
1096 {
1097 continue;
1098 }
1099
1100 if( !$questionList->isInList($resultItemValue['qid']) )
1101 {
1102 continue;
1103 }
1104
1105 $filteredTestResult[] = $resultItemValue;
1106 }
1107
1108 return $filteredTestResult;
1109 }
1110
1114 protected function populateContent($content)
1115 {
1116 if($this->isPdfDeliveryRequest())
1117 {
1118 require_once 'class.ilTestPDFGenerator.php';
1119
1121 $content, ilTestPDFGenerator::PDF_OUTPUT_DOWNLOAD, $this->object->getTitle()
1122 );
1123 }
1124 else
1125 {
1126 $this->tpl->setContent($content);
1127 }
1128 }
1129
1134 {
1135 require_once 'Modules/Test/classes/toolbars/class.ilTestResultsToolbarGUI.php';
1136 $toolbar = new ilTestResultsToolbarGUI($this->ctrl, $this->tpl, $this->lng);
1137
1138 $toolbar->setSkillResultButtonEnabled($this->object->isSkillServiceToBeConsidered());
1139
1140 return $toolbar;
1141 }
1142
1143 protected function outCorrectSolutionCmd()
1144 {
1145 $this->outCorrectSolution(); // cannot be named xxxCmd, because it's also called from context without Cmd in names
1146 }
1147
1153 protected function outCorrectSolution()
1154 {
1155 if( !$this->object->getShowSolutionDetails() )
1156 {
1157 ilUtil::sendInfo($this->lng->txt("no_permission"), true);
1158 $this->ctrl->redirectByClass("ilobjtestgui", "infoScreen");
1159 }
1160
1161 $testSession = $this->testSessionFactory->getSession();
1162 $activeId = $testSession->getActiveId();
1163
1164 if( !($activeId > 0) )
1165 {
1166 $this->ctrl->redirectByClass("ilobjtestgui", "infoScreen");
1167 }
1168
1169 $this->ctrl->saveParameter($this, "pass");
1170 $pass = (int)$_GET['pass'];
1171
1172 $questionId = (int)$_GET['evaluation'];
1173
1174 if( $this->getObjectiveOrientedContainer()->isObjectiveOrientedPresentationRequired() )
1175 {
1176 $testSequence = $this->testSequenceFactory->getSequenceByActiveIdAndPass($activeId, $pass);
1177 $testSequence->loadFromDb();
1178 $testSequence->loadQuestions();
1179
1180 require_once 'Modules/Course/classes/Objectives/class.ilLOTestQuestionAdapter.php';
1181 $objectivesAdapter = ilLOTestQuestionAdapter::getInstance($testSession);
1182 $objectivesList = $this->buildQuestionRelatedObjectivesList($objectivesAdapter, $testSequence);
1183 $objectivesList->loadObjectivesTitles();
1184 }
1185 else
1186 {
1187 $objectivesList = null;
1188 }
1189
1190 global $ilTabs;
1191
1192 if($this instanceof ilTestEvalObjectiveOrientedGUI)
1193 {
1194 $ilTabs->setBackTarget(
1195 $this->lng->txt("tst_back_to_virtual_pass"), $this->ctrl->getLinkTarget($this, 'showVirtualPass')
1196 );
1197 }
1198 else
1199 {
1200 $ilTabs->setBackTarget(
1201 $this->lng->txt("tst_back_to_pass_details"), $this->ctrl->getLinkTarget($this, 'outUserPassDetails')
1202 );
1203 }
1204
1205 include_once("./Services/Style/classes/class.ilObjStyleSheet.php");
1206 $this->tpl->setCurrentBlock("ContentStyle");
1207 $this->tpl->setVariable("LOCATION_CONTENT_STYLESHEET", ilObjStyleSheet::getContentStylePath(0));
1208 $this->tpl->parseCurrentBlock();
1209
1210 $this->tpl->setCurrentBlock("SyntaxStyle");
1211 $this->tpl->setVariable("LOCATION_SYNTAX_STYLESHEET", ilObjStyleSheet::getSyntaxStylePath());
1212 $this->tpl->parseCurrentBlock();
1213
1214 $this->tpl->addCss(ilUtil::getStyleSheetLocation("output", "test_print.css", "Modules/Test"), "print");
1215 if ($this->object->getShowSolutionAnswersOnly())
1216 {
1217 $this->tpl->addCss(ilUtil::getStyleSheetLocation("output", "test_print_hide_content.css", "Modules/Test"), "print");
1218 }
1219
1220 $solution = $this->getCorrectSolutionOutput($questionId, $activeId, $pass, $objectivesList);
1221
1222 $this->tpl->setContent($solution);
1223 }
1224
1229 public function populatePassFinishDate($tpl, $passFinishDate)
1230 {
1233 $passFinishDate = ilDatePresentation::formatDate(new ilDateTime($passFinishDate, IL_CAL_UNIX));
1235 $tpl->setVariable("PASS_FINISH_DATE_LABEL", $this->lng->txt('tst_pass_finished_on'));
1236 $tpl->setVariable("PASS_FINISH_DATE_VALUE", $passFinishDate);
1237 }
1238}
1239
1240// internal sort function to sort the result array
1241function sortResults($a, $b)
1242{
1243 $sort = ($_GET["sort"]) ? ($_GET["sort"]) : "nr";
1244 $sortorder = ($_GET["sortorder"]) ? ($_GET["sortorder"]) : "asc";
1245 if (strcmp($sortorder, "asc"))
1246 {
1247 $smaller = 1;
1248 $greater = -1;
1249 }
1250 else
1251 {
1252 $smaller = -1;
1253 $greater = 1;
1254 }
1255 if ($a[$sort] == $b[$sort]) return 0;
1256 return ($a[$sort] < $b[$sort]) ? $smaller : $greater;
1257}
$_GET["client_id"]
$_SESSION["AccountId"]
const IL_CAL_UNIX
sortResults($a, $b)
_getReachedPoints($active_id, $question_id, $pass=NULL)
Returns the points, a learner has reached answering the question.
static setUseRelativeDates($a_status)
set use relative dates
static formatDate(ilDateTime $date)
Format a date @access public.
static useRelativeDates()
check if relative dates are used
@classDescription Date and time handling
Class for single dates.
buildQuestionRelatedObjectiveList(ilTestQuestionSequence $a_test_sequence, ilTestQuestionRelatedObjectivesList $a_objectives_list)
static getInstance(ilTestSession $a_test_session)
_getManualScoring()
Retrieve the manual scoring settings.
getContentStylePath($a_style_id)
get content style path
getSyntaxStylePath()
get syntax style path
static _lookupLogin($a_user_id)
lookup login
special template class to simplify handling of ITX/PEAR
static generatePDF($pdf_output, $output_mode, $filename=null)
Class ilTestPassOverviewTableGUI.
Service GUI class for tests.
getPassDetailsOverviewTableGUI($result_array, $active_id, $pass, $targetGUI, $targetCMD, $questionDetailsCMD, $questionAnchorNav, ilTestQuestionRelatedObjectivesList $objectivesList=null)
getFilteredTestResult($active_id, $pass, $considerHiddenQuestions, $considerOptionalQuestions)
outCorrectSolution()
Creates an output of the solution of an answer compared to the correct solution.
getCorrectSolutionOutput($question_id, $active_id, $pass, ilTestQuestionRelatedObjectivesList $objectivesList=null)
Returns an output of the solution to an answer compared to the correct solution.
getPassListOfAnswersWithScoring(&$result_array, $active_id, $pass, $show_solutions=FALSE)
Returns the list of answers of a users test pass and offers a scoring option.
ilTestServiceGUI(ilObjTest $a_object)
The constructor takes the test object reference as parameter.
buildPassOverviewTableGUI($targetGUI, $targetCmd='')
setObjectiveOrientedContainer(ilTestObjectiveOrientedContainer $objectiveOrientedContainer)
getResultsOfUserOutput($testSession, $active_id, $pass, $targetGUI, $show_pass_details=TRUE, $show_answers=TRUE, $show_question_only=FALSE, $show_reached_points=FALSE)
Output of the pass overview for a test called by a test participant.
populatePassFinishDate($tpl, $passFinishDate)
getResultsSignature()
Returns HTML code for a signature field.
getCommand($cmd)
Retrieves the ilCtrl command.
getQuestionResultForTestUsers($question_id, $test_id)
Creates a HTML representation for the results of a given question in a test.
getPassListOfAnswers(&$result_array, $active_id, $pass, $show_solutions=FALSE, $only_answered_questions=FALSE, $show_question_only=FALSE, $show_reached_points=FALSE, $anchorNav=false, ilTestQuestionRelatedObjectivesList $objectivesList=null, ilTestResultHeaderLabelBuilder $testResultHeaderLabelBuilder=null)
Returns the list of answers of a users test pass.
getAdditionalUsrDataHtmlAndPopulateWindowTitle($testSession, $active_id, $overwrite_anonymity=FALSE)
Returns the user data for a test results output.
setContextResultPresentation($contextResultPresentation)
buildQuestionRelatedObjectivesList(ilLOTestQuestionAdapter $objectivesAdapter, ilTestQuestionSequence $testSequence)
getPassOverviewTableData(ilTestSession $testSession, $passes, $withResults)
& executeCommand()
execute command
getResultsHeadUserAndPass($active_id, $pass)
Returns the user and pass data for a test results output.
setParticipantData($participantData)
buildPassDetailsOverviewTableGUI($targetGUI, $targetCMD)
Service class for tests.
Test session handler.
static getStyleSheetLocation($mode="output", $a_css_name="", $a_css_location="")
get full style sheet file name (path inclusive) of current user
static sendInfo($a_info="", $a_keep=false)
Send Info Message to Screen.
static getImagePath($img, $module_path="", $mode="output", $offline=false)
get image path (for images located in a template directory)
static prepareFormOutput($a_str, $a_strip=false)
prepares string output for html forms @access public
static initDomEvent()
Init YUI DomEvent.
$data
global $ilCtrl
Definition: ilias.php:18
redirection script todo: (a better solution should control the processing via a xml file)
$cmd
Definition: sahs_server.php:35
global $ilDB
global $ilUser
Definition: imgupload.php:15