1<?php
2/* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4
5/**
6 * @author		Björn Heyser <bheyser@databay.de>
7 * @version		$Id$
8 *
9 * @package     Modules/Test
10 *
11 * @ilCtrl_Calls ilTestSkillLevelThresholdsGUI: ilTestSkillLevelThresholdsTableGUI
12 */
13class ilTestSkillLevelThresholdsGUI
14{
15    const CMD_SHOW_SKILL_THRESHOLDS = 'showSkillThresholds';
16    const CMD_SAVE_SKILL_THRESHOLDS = 'saveSkillThresholds';
17    /**
18     * @var ilCtrl
19     */
20    private $ctrl;
21
22    /**
23     * @var ilGlobalTemplateInterface
24     */
25    private $tpl;
26
27    /**
28     * @var ilLanguage
29     */
30    private $lng;
31
32    /**
33     * @var ilDBInterface
34     */
35    private $db;
36
37    /**
38     * @var int
39     */
40    private $testId;
41
42    /**
43     * @var integer
44     */
45    private $questionContainerId;
46
47    private $questionAssignmentColumnsEnabled;
48
49    public function __construct(ilCtrl $ctrl, ilGlobalTemplateInterface $tpl, ilLanguage $lng, ilDBInterface $db, $testId)
50    {
51        $this->ctrl = $ctrl;
52        $this->tpl = $tpl;
53        $this->lng = $lng;
54        $this->db = $db;
55        $this->testId = $testId;
56        $this->questionAssignmentColumnsEnabled = false;
57    }
58
59    /**
60     * @return int
61     */
62    public function getQuestionContainerId()
63    {
64        return $this->questionContainerId;
65    }
66
67    /**
68     * @param int $questionContainerId
69     */
70    public function setQuestionContainerId($questionContainerId)
71    {
72        $this->questionContainerId = $questionContainerId;
73    }
74
75    public function executeCommand()
76    {
77        $cmd = $this->ctrl->getCmd('show') . 'Cmd';
78
79        $this->$cmd();
80    }
81
82    /**
83     * @param boolean $questionAssignmentColumnsEnabled
84     */
85    public function setQuestionAssignmentColumnsEnabled($questionAssignmentColumnsEnabled)
86    {
87        $this->questionAssignmentColumnsEnabled = $questionAssignmentColumnsEnabled;
88    }
89
90    /**
91     * @return bool
92     */
93    public function areQuestionAssignmentColumnsEnabled()
94    {
95        return $this->questionAssignmentColumnsEnabled;
96    }
97
98    /**
99     * @return int
100     */
101    public function getTestId()
102    {
103        return $this->testId;
104    }
105
106    private function saveSkillThresholdsCmd()
107    {
108        require_once 'Modules/Test/classes/class.ilTestSkillLevelThreshold.php';
109
110        if (strtolower($_SERVER['REQUEST_METHOD']) == 'post') {
111            $assignmentList = $this->buildSkillQuestionAssignmentList();
112            $assignmentList->loadFromDb();
113
114            $valid = true;
115
116            $table = $this->getPopulatedTable();
117            $elements = $table->getInputElements((array) ($_POST['rendered'] ?? []));
118            foreach ($elements as $elm) {
119                if (!$elm->checkInput()) {
120                    $valid = false;
121                }
122
123                $elm->setValueByArray($_POST);
124            }
125
126            if (!$valid) {
127                ilUtil::sendFailure($this->lng->txt('form_input_not_valid'));
128                return $this->showSkillThresholdsCmd($table);
129            }
130
131            $threshold = array();
132            foreach ($_POST as $key => $value) {
133                $matches = null;
134                if (preg_match('/^threshold_(\d+?):(\d+?)_(\d+?)$/', $key, $matches) && is_array($matches)) {
135                    $threshold[$matches[1] . ':' . $matches[2]][$matches[3]] = $value;
136                }
137            }
138
139            /** @var $skillLevelThresholds ilTestSkillLevelThreshold[] */
140            $skillLevelThresholds = array();
141
142            foreach ($assignmentList->getUniqueAssignedSkills() as $data) {
143                $skill = $data['skill'];
144                $skillKey = $data['skill_base_id'] . ':' . $data['skill_tref_id'];
145                $levels = $skill->getLevelData();
146
147                $thresholds_by_level = array();
148
149                foreach ($levels as $level) {
150                    if (isset($threshold[$skillKey]) && isset($threshold[$skillKey][$level['id']])) {
151                        $skillLevelThreshold = new ilTestSkillLevelThreshold($this->db);
152
153                        $skillLevelThreshold->setTestId($this->getTestId());
154                        $skillLevelThreshold->setSkillBaseId($data['skill_base_id']);
155                        $skillLevelThreshold->setSkillTrefId($data['skill_tref_id']);
156                        $skillLevelThreshold->setSkillLevelId($level['id']);
157
158                        $skillLevelThreshold->setThreshold($threshold[$skillKey][$level['id']]);
159                        $skillLevelThresholds[] = $skillLevelThreshold;
160                        $thresholds_by_level[] = $threshold[$skillKey][$level['id']];
161                    }
162                }
163
164                $sorted_thresholds_by_level = $thresholds_by_level = array_values($thresholds_by_level);
165                sort($sorted_thresholds_by_level);
166                if (
167                    $sorted_thresholds_by_level != $thresholds_by_level ||
168                    count($thresholds_by_level) != count(array_unique($thresholds_by_level))
169                ) {
170                    ilUtil::sendFailure($this->lng->txt('ass_competence_respect_level_ordering'));
171                    return $this->showSkillThresholdsCmd($table);
172                }
173            }
174
175            foreach ($skillLevelThresholds as $skillLevelThreshold) {
176                $skillLevelThreshold->saveToDb();
177            }
178
179            ilUtil::sendSuccess($this->lng->txt('tst_msg_skl_lvl_thresholds_saved'), true);
180        }
181
182        $this->ctrl->redirect($this, self::CMD_SHOW_SKILL_THRESHOLDS);
183    }
184
185    /**
186     * @param ilTestSkillLevelThresholdsTableGUI|null $table
187     */
188    private function showSkillThresholdsCmd(ilTestSkillLevelThresholdsTableGUI $table = null)
189    {
190        if (null === $table) {
191            $table = $this->getPopulatedTable();
192        }
193
194        $this->tpl->setContent($this->ctrl->getHTML($table));
195    }
196
197    /**
198     * @return ilTestSkillLevelThresholdsTableGUI
199     */
200    protected function getPopulatedTable()
201    {
202        $table = $this->buildTableGUI();
203
204        $skillLevelThresholdList = $this->buildSkillLevelThresholdList();
205        $skillLevelThresholdList->loadFromDb();
206        $table->setSkillLevelThresholdList($skillLevelThresholdList);
207
208        $assignmentList = $this->buildSkillQuestionAssignmentList();
209        $assignmentList->loadFromDb();
210
211        $table->setData($table->completeCompetenceTitles(
212            $assignmentList->getUniqueAssignedSkills()
213        ));
214        return $table;
215    }
216
217    private function buildTableGUI()
218    {
219        require_once 'Modules/Test/classes/tables/class.ilTestSkillLevelThresholdsTableGUI.php';
220        $table = new ilTestSkillLevelThresholdsTableGUI(
221            $this,
222            $this->getTestId(),
223            self::CMD_SHOW_SKILL_THRESHOLDS,
224            $this->ctrl,
225            $this->lng
226        );
227        $table->setQuestionAssignmentColumnsEnabled($this->areQuestionAssignmentColumnsEnabled());
228        $table->initColumns();
229
230        return $table;
231    }
232
233    private function buildSkillQuestionAssignmentList()
234    {
235        require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionSkillAssignmentList.php';
236        $assignmentList = new ilAssQuestionSkillAssignmentList($this->db);
237        $assignmentList->setParentObjId($this->getQuestionContainerId());
238
239        return $assignmentList;
240    }
241
242    private function buildSkillLevelThresholdList()
243    {
244        require_once 'Modules/Test/classes/class.ilTestSkillLevelThresholdList.php';
245        $thresholdList = new ilTestSkillLevelThresholdList($this->db);
246        $thresholdList->setTestId($this->getTestId());
247
248        return $thresholdList;
249    }
250}
251