1<?php
2
3/* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
4
5/**
6 * Class ilParticipantsTestResultsGUI
7 *
8 * @author    Björn Heyser <info@bjoernheyser.de>
9 * @version    $Id$
10 *
11 * @package    Modules/Test
12 *
13 * @ilCtrl_Calls ilParticipantsTestResultsGUI: ilTestEvaluationGUI
14 * @ilCtrl_Calls ilParticipantsTestResultsGUI: ilAssQuestionPageGUI
15 * @ilCtrl_Calls ilParticipantsTestResultsGUI: ilAssSpecFeedbackPageGUI
16 * @ilCtrl_Calls ilParticipantsTestResultsGUI: ilAssGenFeedbackPageGUI
17 */
18class ilParticipantsTestResultsGUI
19{
20    const CMD_SHOW_PARTICIPANTS = 'showParticipants';
21    const CMD_CONFIRM_DELETE_ALL_USER_RESULTS = 'deleteAllUserResults';
22    const CMD_PERFORM_DELETE_ALL_USER_RESULTS = 'confirmDeleteAllUserResults';
23    const CMD_CONFIRM_DELETE_SELECTED_USER_RESULTS = 'deleteSingleUserResults';
24    const CMD_PERFORM_DELETE_SELECTED_USER_RESULTS = 'confirmDeleteSelectedUserData';
25
26    /**
27     * @var ilObjTest
28     */
29    protected $testObj;
30
31    /**
32     * @var ilTestQuestionSetConfig
33     */
34    protected $questionSetConfig;
35
36    /**
37     * @var ilTestAccess
38     */
39    protected $testAccess;
40
41    /**
42     * @var ilTestObjectiveOrientedContainer
43     */
44    protected $objectiveParent;
45
46    /**
47     * @return ilObjTest
48     */
49    public function getTestObj()
50    {
51        return $this->testObj;
52    }
53
54    /**
55     * @param ilObjTest $testObj
56     */
57    public function setTestObj($testObj)
58    {
59        $this->testObj = $testObj;
60    }
61
62    /**
63     * @return ilTestQuestionSetConfig
64     */
65    public function getQuestionSetConfig()
66    {
67        return $this->questionSetConfig;
68    }
69
70    /**
71     * @param ilTestQuestionSetConfig $questionSetConfig
72     */
73    public function setQuestionSetConfig($questionSetConfig)
74    {
75        $this->questionSetConfig = $questionSetConfig;
76    }
77
78    /**
79     * @return ilTestAccess
80     */
81    public function getTestAccess()
82    {
83        return $this->testAccess;
84    }
85
86    /**
87     * @param ilTestAccess $testAccess
88     */
89    public function setTestAccess($testAccess)
90    {
91        $this->testAccess = $testAccess;
92    }
93
94    /**
95     * @return ilTestObjectiveOrientedContainer
96     */
97    public function getObjectiveParent()
98    {
99        return $this->objectiveParent;
100    }
101
102    /**
103     * @param ilTestObjectiveOrientedContainer $objectiveParent
104     */
105    public function setObjectiveParent($objectiveParent)
106    {
107        $this->objectiveParent = $objectiveParent;
108    }
109
110    /**
111     * Execute Command
112     */
113    public function executeCommand()
114    {
115        global $DIC; /* @var ILIAS\DI\Container $DIC */
116
117        switch ($DIC->ctrl()->getNextClass($this)) {
118            case "iltestevaluationgui":
119                require_once 'Modules/Test/classes/class.ilTestEvaluationGUI.php';
120                $gui = new ilTestEvaluationGUI($this->getTestObj());
121                $gui->setObjectiveOrientedContainer($this->getObjectiveParent());
122                $gui->setTestAccess($this->getTestAccess());
123                $DIC->tabs()->clearTargets();
124                $DIC->tabs()->clearSubTabs();
125                $DIC->ctrl()->forwardCommand($gui);
126                break;
127
128            case 'ilassquestionpagegui':
129                require_once 'Modules/Test/classes/class.ilAssQuestionPageCommandForwarder.php';
130                $forwarder = new ilAssQuestionPageCommandForwarder();
131                $forwarder->setTestObj($this->getTestObj());
132                $forwarder->forward();
133                break;
134
135            default:
136
137                $command = $DIC->ctrl()->getCmd(self::CMD_SHOW_PARTICIPANTS) . 'Cmd';
138                $this->{$command}();
139        }
140    }
141
142    /**
143     * @return ilParticipantsTestResultsTableGUI
144     */
145    protected function buildTableGUI()
146    {
147        global $DIC; /* @var ILIAS\DI\Container $DIC */
148        require_once 'Modules/Test/classes/tables/class.ilParticipantsTestResultsTableGUI.php';
149        $tableGUI = new ilParticipantsTestResultsTableGUI($this, self::CMD_SHOW_PARTICIPANTS);
150        $tableGUI->setTitle($DIC->language()->txt('tst_tbl_results_grades'));
151        return $tableGUI;
152    }
153
154    /**
155     * show participants command
156     */
157    protected function showParticipantsCmd()
158    {
159        global $DIC; /* @var ILIAS\DI\Container $DIC */
160
161        if ($this->getQuestionSetConfig()->areDepenciesBroken()) {
162            ilUtil::sendFailure(
163                $this->getQuestionSetConfig()->getDepenciesBrokenMessage($DIC->language())
164            );
165        } elseif ($this->getQuestionSetConfig()->areDepenciesInVulnerableState()) {
166            ilUtil::sendInfo(
167                $this->questionSetConfig->getDepenciesInVulnerableStateMessage($DIC->language())
168            );
169        }
170
171        $manageParticipantFilter = ilTestParticipantAccessFilter::getManageParticipantsUserFilter($this->getTestObj()->getRefId());
172        $accessResultsFilter = ilTestParticipantAccessFilter::getAccessResultsUserFilter($this->getTestObj()->getRefId());
173
174        $participantList = $this->getTestObj()->getActiveParticipantList();
175        $participantList = $participantList->getAccessFilteredList($manageParticipantFilter);
176        $participantList = $participantList->getAccessFilteredList($accessResultsFilter);
177
178        $scoredParticipantList = $participantList->getScoredParticipantList();
179
180        require_once 'Modules/Test/classes/tables/class.ilTestParticipantsTableGUI.php';
181        $tableGUI = $this->buildTableGUI();
182
183        if (!$this->getQuestionSetConfig()->areDepenciesBroken()) {
184            $tableGUI->setAccessResultsCommandsEnabled(
185                $this->getTestAccess()->checkParticipantsResultsAccess()
186            );
187
188            $tableGUI->setManageResultsCommandsEnabled(
189                $this->getTestAccess()->checkManageParticipantsAccess()
190            );
191
192            if ($scoredParticipantList->hasScorings()) {
193                $this->addDeleteAllTestResultsButton($DIC->toolbar());
194            }
195        }
196
197        $tableGUI->setAnonymity($this->getTestObj()->getAnonymity());
198
199        $tableGUI->initColumns();
200        $tableGUI->initCommands();
201
202        $tableGUI->setData($participantList->getScoringsTableRows());
203
204        $DIC->ui()->mainTemplate()->setContent($tableGUI->getHTML());
205    }
206
207    /**
208     * @param ilToolbarGUI $toolbar
209     */
210    protected function addDeleteAllTestResultsButton(ilToolbarGUI $toolbar)
211    {
212        global $DIC; /* @var ILIAS\DI\Container $DIC */
213
214        require_once  'Services/UIComponent/Button/classes/class.ilLinkButton.php';
215        $delete_all_results_btn = ilLinkButton::getInstance();
216        $delete_all_results_btn->setCaption('delete_all_user_data');
217        $delete_all_results_btn->setUrl($DIC->ctrl()->getLinkTarget($this, 'deleteAllUserResults'));
218        $toolbar->addButtonInstance($delete_all_results_btn);
219    }
220
221    /**
222     * Asks for a confirmation to delete all user data of the test object
223     */
224    protected function deleteAllUserResultsCmd()
225    {
226        global $DIC; /* @var ILIAS\DI\Container $DIC */
227
228        // display confirmation message
229        include_once("./Services/Utilities/classes/class.ilConfirmationGUI.php");
230        $cgui = new ilConfirmationGUI();
231        $cgui->setFormAction($DIC->ctrl()->getFormAction($this));
232        $cgui->setHeaderText($DIC->language()->txt("delete_all_user_data_confirmation"));
233        $cgui->setCancel($DIC->language()->txt("cancel"), self::CMD_SHOW_PARTICIPANTS);
234        $cgui->setConfirm($DIC->language()->txt("proceed"), self::CMD_PERFORM_DELETE_ALL_USER_RESULTS);
235
236        $DIC->ui()->mainTemplate()->setContent($cgui->getHTML());
237    }
238
239    /**
240     * Deletes all user data for the test object
241     */
242    protected function confirmDeleteAllUserResultsCmd()
243    {
244        global $DIC; /* @var ILIAS\DI\Container $DIC */
245
246        require_once 'Modules/Test/classes/class.ilTestParticipantAccessFilter.php';
247        $accessFilter = ilTestParticipantAccessFilter::getManageParticipantsUserFilter(
248            $this->getTestObj()->getRefId()
249        );
250
251        require_once 'Modules/Test/classes/class.ilTestParticipantData.php';
252        $participantData = new ilTestParticipantData($DIC->database(), $DIC->language());
253        //$participantData->setScoredParticipantsFilterEnabled(!$this->getTestObj()->isDynamicTest());
254        $participantData->setParticipantAccessFilter($accessFilter);
255        $participantData->load($this->getTestObj()->getTestId());
256
257        $this->getTestObj()->removeTestResults($participantData);
258
259        ilUtil::sendSuccess($DIC->language()->txt("tst_all_user_data_deleted"), true);
260        $DIC->ctrl()->redirect($this, self::CMD_SHOW_PARTICIPANTS);
261    }
262
263    /**
264     * Asks for a confirmation to delete selected user data of the test object
265     */
266    protected function deleteSingleUserResultsCmd()
267    {
268        global $DIC; /* @var ILIAS\DI\Container $DIC */
269
270        if (!is_array($_POST["chbUser"]) || count($_POST["chbUser"]) == 0) {
271            ilUtil::sendInfo($DIC->language()->txt("select_one_user"), true);
272            $DIC->ctrl()->redirect($this);
273        }
274
275        include_once("./Services/Utilities/classes/class.ilConfirmationGUI.php");
276        $cgui = new ilConfirmationGUI();
277        $cgui->setHeaderText($DIC->language()->txt("confirm_delete_single_user_data"));
278
279        $cgui->setFormAction($DIC->ctrl()->getFormAction($this));
280        $cgui->setCancel($DIC->language()->txt("cancel"), self::CMD_SHOW_PARTICIPANTS);
281        $cgui->setConfirm($DIC->language()->txt("confirm"), self::CMD_PERFORM_DELETE_SELECTED_USER_RESULTS);
282
283        require_once 'Modules/Test/classes/class.ilTestParticipantAccessFilter.php';
284        $accessFilter = ilTestParticipantAccessFilter::getManageParticipantsUserFilter($this->getTestObj()->getRefId());
285
286        require_once 'Modules/Test/classes/class.ilTestParticipantData.php';
287        $participantData = new ilTestParticipantData($DIC->database(), $DIC->language());
288        //$participantData->setScoredParticipantsFilterEnabled(!$this->getTestObj()->isDynamicTest());
289        $participantData->setParticipantAccessFilter($accessFilter);
290
291        $participantData->setActiveIdsFilter((array) $_POST["chbUser"]);
292
293        $participantData->load($this->getTestObj()->getTestId());
294
295        foreach ($participantData->getActiveIds() as $activeId) {
296            if ($this->testObj->getAnonymity()) {
297                $username = $DIC->language()->txt('anonymous');
298            } else {
299                $username = $participantData->getFormatedFullnameByActiveId($activeId);
300            }
301
302            $cgui->addItem(
303                "chbUser[]",
304                $activeId,
305                $username,
306                ilUtil::getImagePath("icon_usr.svg"),
307                $DIC->language()->txt("usr")
308            );
309        }
310
311        $DIC->ui()->mainTemplate()->setContent($cgui->getHTML());
312    }
313
314    /**
315     * Deletes the selected user data for the test object
316     */
317    protected function confirmDeleteSelectedUserDataCmd()
318    {
319        global $DIC; /* @var ILIAS\DI\Container $DIC */
320
321        if (isset($_POST["chbUser"]) && is_array($_POST["chbUser"]) && count($_POST["chbUser"])) {
322            require_once 'Modules/Test/classes/class.ilTestParticipantAccessFilter.php';
323            $accessFilter = ilTestParticipantAccessFilter::getManageParticipantsUserFilter($this->getTestObj()->getRefId());
324
325            require_once 'Modules/Test/classes/class.ilTestParticipantData.php';
326            $participantData = new ilTestParticipantData($DIC->database(), $DIC->language());
327            //$participantData->setScoredParticipantsFilterEnabled(!$this->getTestObj()->isDynamicTest());
328            $participantData->setParticipantAccessFilter($accessFilter);
329            $participantData->setActiveIdsFilter($_POST["chbUser"]);
330
331            $participantData->load($this->getTestObj()->getTestId());
332
333            $this->getTestObj()->removeTestResults($participantData);
334
335            ilUtil::sendSuccess($DIC->language()->txt("tst_selected_user_data_deleted"), true);
336        }
337
338        $DIC->ctrl()->redirect($this, self::CMD_SHOW_PARTICIPANTS);
339    }
340
341    /**
342     * Shows the pass overview and the answers of one ore more users for the scored pass
343     */
344    protected function showDetailedResultsCmd()
345    {
346        if (is_array($_POST) && count($_POST)) {
347            $_SESSION["show_user_results"] = $_POST["chbUser"];
348        }
349        $this->showUserResults($show_pass_details = true, $show_answers = true, $show_reached_points = true);
350    }
351
352    /**
353     * Shows the answers of one ore more users for the scored pass
354     */
355    protected function showUserAnswersCmd()
356    {
357        if (is_array($_POST) && count($_POST)) {
358            $_SESSION["show_user_results"] = $_POST["chbUser"];
359        }
360        $this->showUserResults($show_pass_details = false, $show_answers = true);
361    }
362
363    /**
364     * Shows the pass overview of the scored pass for one ore more users
365     */
366    protected function showPassOverviewCmd()
367    {
368        if (is_array($_POST) && count($_POST)) {
369            $_SESSION["show_user_results"] = $_POST["chbUser"];
370        }
371        $this->showUserResults($show_pass_details = true, $show_answers = false);
372    }
373
374    /**
375     * Shows the pass overview of the scored pass for one ore more users
376     *
377     * @access	public
378     */
379    protected function showUserResults($show_pass_details, $show_answers, $show_reached_points = false)
380    {
381        global $DIC; /* @var ILIAS\DI\Container $DIC */
382
383        $DIC->tabs()->clearTargets();
384        $DIC->tabs()->clearSubTabs();
385
386        $show_user_results = $_SESSION["show_user_results"];
387
388        if (!is_array($show_user_results) || count($show_user_results) == 0) {
389            ilUtil::sendInfo($DIC->language()->txt("select_one_user"), true);
390            $DIC->ctrl()->redirect($this, self::CMD_SHOW_PARTICIPANTS);
391        }
392
393
394        $template = $this->createUserResults($show_pass_details, $show_answers, $show_reached_points, $show_user_results);
395
396        if ($template instanceof ilTemplate) {
397            $DIC->ui()->mainTemplate()->setVariable("ADM_CONTENT", $template->get());
398            $DIC->ui()->mainTemplate()->addCss(ilUtil::getStyleSheetLocation("output", "test_print.css", "Modules/Test"), "print");
399            if ($this->getTestObj()->getShowSolutionAnswersOnly()) {
400                $DIC->ui()->mainTemplate()->addCss(ilUtil::getStyleSheetLocation("output", "test_print_hide_content.css", "Modules/Test"), "print");
401            }
402        }
403    }
404
405    /**
406     * @param $show_pass_details
407     * @param $show_answers
408     * @param $show_reached_points
409     * @param $show_user_results
410     *
411     * @return ilTemplate
412     */
413    public function createUserResults($show_pass_details, $show_answers, $show_reached_points, $show_user_results)
414    {
415        global $DIC; /* @var ILIAS\DI\Container $DIC */
416
417        // prepare generation before contents are processed (needed for mathjax)
418        if ($this->isPdfDeliveryRequest()) {
419            ilPDFGeneratorUtils::prepareGenerationRequest("Test", PDF_USER_RESULT);
420        }
421
422        $DIC->tabs()->setBackTarget(
423            $DIC->language()->txt('back'),
424            $DIC->ctrl()->getLinkTarget($this, self::CMD_SHOW_PARTICIPANTS)
425        );
426
427        if ($this->getObjectiveParent()->isObjectiveOrientedPresentationRequired()) {
428            require_once 'Services/Link/classes/class.ilLink.php';
429            $courseLink = ilLink::_getLink($this->getObjectiveParent()->getRefId());
430            $DIC->tabs()->setBack2Target($DIC->language()->txt('back_to_objective_container'), $courseLink);
431        }
432
433        $template = new ilTemplate("tpl.il_as_tst_participants_result_output.html", true, true, "Modules/Test");
434
435        require_once 'Modules/Test/classes/toolbars/class.ilTestResultsToolbarGUI.php';
436        $toolbar = new ilTestResultsToolbarGUI($DIC->ctrl(), $DIC->ui()->mainTemplate(), $DIC->language());
437
438        $DIC->ctrl()->setParameter($this, 'pdf', '1');
439        $toolbar->setPdfExportLinkTarget($DIC->ctrl()->getLinkTarget($this, $DIC->ctrl()->getCmd()));
440        $DIC->ctrl()->setParameter($this, 'pdf', '');
441
442        if ($show_answers) {
443            if (isset($_GET['show_best_solutions'])) {
444                $_SESSION['tst_results_show_best_solutions'] = true;
445            } elseif (isset($_GET['hide_best_solutions'])) {
446                $_SESSION['tst_results_show_best_solutions'] = false;
447            } elseif (!isset($_SESSION['tst_results_show_best_solutions'])) {
448                $_SESSION['tst_results_show_best_solutions'] = false;
449            }
450
451            if ($_SESSION['tst_results_show_best_solutions']) {
452                $DIC->ctrl()->setParameter($this, 'hide_best_solutions', '1');
453                $toolbar->setHideBestSolutionsLinkTarget($DIC->ctrl()->getLinkTarget($this, $DIC->ctrl()->getCmd()));
454                $DIC->ctrl()->setParameter($this, 'hide_best_solutions', '');
455            } else {
456                $DIC->ctrl()->setParameter($this, 'show_best_solutions', '1');
457                $toolbar->setShowBestSolutionsLinkTarget($DIC->ctrl()->getLinkTarget($this, $DIC->ctrl()->getCmd()));
458                $DIC->ctrl()->setParameterByClass('', 'show_best_solutions', '');
459            }
460        }
461
462        require_once 'Modules/Test/classes/class.ilTestParticipantData.php';
463        require_once 'Modules/Test/classes/class.ilTestParticipantAccessFilter.php';
464
465        $participantData = new ilTestParticipantData($DIC->database(), $DIC->language());
466
467        $participantData->setParticipantAccessFilter(
468            ilTestParticipantAccessFilter::getAccessResultsUserFilter($this->getTestObj()->getRefId())
469        );
470
471        $participantData->setActiveIdsFilter($show_user_results);
472
473        $participantData->load($this->getTestObj()->getTestId());
474        $toolbar->setParticipantSelectorOptions($participantData->getOptionArray());
475
476        $toolbar->build();
477        $template->setVariable('RESULTS_TOOLBAR', $toolbar->getHTML());
478
479        include_once "./Modules/Test/classes/class.ilTestServiceGUI.php";
480        $serviceGUI = new ilTestServiceGUI($this->getTestObj());
481        $serviceGUI->setObjectiveOrientedContainer($this->getObjectiveParent());
482        $serviceGUI->setParticipantData($participantData);
483
484        require_once 'Modules/Test/classes/class.ilTestSessionFactory.php';
485        $testSessionFactory = new ilTestSessionFactory($this->getTestObj());
486
487        $count = 0;
488        foreach ($show_user_results as $key => $active_id) {
489            if (!in_array($active_id, $participantData->getActiveIds())) {
490                continue;
491            }
492
493            $count++;
494            $results = "";
495            if ($active_id > 0) {
496                $results = $serviceGUI->getResultsOfUserOutput(
497                    $testSessionFactory->getSession($active_id),
498                    $active_id,
499                    $this->getTestObj()->_getResultPass($active_id),
500                    $this,
501                    $show_pass_details,
502                    $show_answers,
503                    false,
504                    $show_reached_points
505                );
506            }
507            if ($count < count($show_user_results)) {
508                $template->touchBlock("break");
509            }
510            $template->setCurrentBlock("user_result");
511            $template->setVariable("USER_RESULT", $results);
512            $template->parseCurrentBlock();
513        }
514
515        if ($this->isPdfDeliveryRequest()) {
516            ilTestPDFGenerator::generatePDF(
517                $template->get(),
518                ilTestPDFGenerator::PDF_OUTPUT_DOWNLOAD,
519                $this->getTestObj()->getTitleFilenameCompliant(),
520                PDF_USER_RESULT
521            );
522        } else {
523            return $template;
524        }
525    }
526
527    /**
528     * @return bool
529     */
530    protected function isPdfDeliveryRequest()
531    {
532        if (!isset($_GET['pdf'])) {
533            return false;
534        }
535
536        if (!(bool) $_GET['pdf']) {
537            return false;
538        }
539
540        return true;
541    }
542}
543