1<?php
2/* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionHintAbstractGUI.php';
5require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionHintTracking.php';
6
7/**
8 * GUI class for management/output of hint requests during test session
9 *
10 * @author		Björn Heyser <bheyser@databay.de>
11 * @version		$Id$
12 *
13 * @package		Modules/TestQuestionPool
14 *
15 * @ilCtrl_Calls ilAssQuestionHintRequestGUI: ilAssQuestionHintsTableGUI
16 * @ilCtrl_Calls ilAssQuestionHintRequestGUI: ilConfirmationGUI, ilPropertyFormGUI, ilAssHintPageGUI
17 */
18class ilAssQuestionHintRequestGUI extends ilAssQuestionHintAbstractGUI
19{
20    /**
21     * command constants
22     */
23    const CMD_SHOW_LIST = 'showList';
24    const CMD_SHOW_HINT = 'showHint';
25    const CMD_CONFIRM_REQUEST = 'confirmRequest';
26    const CMD_PERFORM_REQUEST = 'performRequest';
27    const CMD_BACK_TO_QUESTION = 'backToQuestion';
28
29    /**
30     * @var mixed
31     */
32    protected $parentGUI = null;
33
34    /**
35     * @var string
36     */
37    protected $parentCMD = null;
38
39    /**
40     * @var mixed
41     */
42    protected $questionHintTracking = null;
43
44    /**
45     * Constructor
46     */
47    public function __construct($parentGUI, $parentCMD, assQuestionGUI $questionGUI, $questionHintTracking)
48    {
49        $this->parentGUI = $parentGUI;
50        $this->parentCMD = $parentCMD;
51        $this->questionHintTracking = $questionHintTracking;
52
53        parent::__construct($questionGUI);
54    }
55
56    /**
57     * Execute Command
58     *
59     * @access	public
60     * @global	ilCtrl	$ilCtrl
61     * @return	mixed
62     */
63    public function executeCommand()
64    {
65        global $DIC;
66        $ilCtrl = $DIC['ilCtrl'];
67        $ilTabs = $DIC['ilTabs'];
68        $lng = $DIC['lng'];
69
70        $cmd = $ilCtrl->getCmd(self::CMD_SHOW_LIST);
71        $nextClass = $ilCtrl->getNextClass($this);
72
73        switch ($nextClass) {
74            case 'ilasshintpagegui':
75
76                require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionHintPageObjectCommandForwarder.php';
77                $forwarder = new ilAssQuestionHintPageObjectCommandForwarder($this->questionOBJ, $ilCtrl, $ilTabs, $lng);
78                $forwarder->setPresentationMode(ilAssQuestionHintPageObjectCommandForwarder::PRESENTATION_MODE_REQUEST);
79                $forwarder->forward();
80                break;
81
82            default:
83
84                $cmd .= 'Cmd';
85                return $this->$cmd();
86                break;
87        }
88    }
89
90    /**
91     * shows the list of allready requested hints
92     *
93     * @access	private
94     */
95    private function showListCmd()
96    {
97        global $DIC;
98        $ilCtrl = $DIC['ilCtrl'];
99        $tpl = $DIC['tpl'];
100
101        require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionHintsTableGUI.php';
102
103        $questionHintList = $this->questionHintTracking->getRequestedHintsList();
104
105        $table = new ilAssQuestionHintsTableGUI(
106            $this->questionOBJ,
107            $questionHintList,
108            $this,
109            self::CMD_SHOW_LIST
110        );
111
112        $this->populateContent($ilCtrl->getHtml($table));
113    }
114
115    /**
116     * shows an allready requested hint
117     *
118     * @access	private
119     * @global	ilCtrl $ilCtrl
120     * @global	ilTemplate $tpl
121     * @global	ilLanguage $lng
122     */
123    private function showHintCmd()
124    {
125        global $DIC;
126        $ilCtrl = $DIC['ilCtrl'];
127        $tpl = $DIC['tpl'];
128        $lng = $DIC['lng'];
129
130        if (!isset($_GET['hintId']) || !(int) $_GET['hintId']) {
131            throw new ilTestException('no hint id given');
132        }
133
134        $isRequested = $this->questionHintTracking->isRequested((int) $_GET['hintId']);
135
136        if (!$isRequested) {
137            throw new ilTestException('hint with given id is not yet requested for given testactive and testpass');
138        }
139
140        $questionHint = ilAssQuestionHint::getInstanceById((int) $_GET['hintId']);
141
142        require_once 'Services/Utilities/classes/class.ilUtil.php';
143        require_once 'Services/Form/classes/class.ilPropertyFormGUI.php';
144        require_once 'Services/Form/classes/class.ilNonEditableValueGUI.php';
145
146        // build form
147
148        $form = new ilPropertyFormGUI();
149
150        $form->setFormAction($ilCtrl->getFormAction($this));
151
152        $form->setTableWidth('100%');
153
154        $form->setTitle(sprintf(
155            $lng->txt('tst_question_hints_form_header_edit'),
156            $questionHint->getIndex(),
157            $this->questionOBJ->getTitle()
158        ));
159
160        $form->addCommandButton(self::CMD_BACK_TO_QUESTION, $lng->txt('tst_question_hints_back_to_question'));
161
162        $numExistingRequests = $this->questionHintTracking->getNumExistingRequests();
163
164        if ($numExistingRequests > 1) {
165            $form->addCommandButton(self::CMD_SHOW_LIST, $lng->txt('button_show_requested_question_hints'));
166        }
167
168        // form input: hint text
169
170        $nonEditableHintText = new ilNonEditableValueGUI($lng->txt('tst_question_hints_form_label_hint_text'), 'hint_text', true);
171        $nonEditableHintText->setValue(ilUtil::prepareTextareaOutput($questionHint->getText(), true));
172        $form->addItem($nonEditableHintText);
173
174        // form input: hint points
175
176        $nonEditableHintPoints = new ilNonEditableValueGUI($lng->txt('tst_question_hints_form_label_hint_points'), 'hint_points');
177        $nonEditableHintPoints->setValue($questionHint->getPoints());
178        $form->addItem($nonEditableHintPoints);
179
180        $this->populateContent($ilCtrl->getHtml($form));
181    }
182
183    /**
184     * shows a confirmation screen for a hint request
185     *
186     * @access	private
187     * @global	ilCtrl $ilCtrl
188     * @global	ilTemplate $tpl
189     * @global	ilLanguage $lng
190     */
191    private function confirmRequestCmd()
192    {
193        global $DIC;
194        $ilCtrl = $DIC['ilCtrl'];
195        $tpl = $DIC['tpl'];
196        $lng = $DIC['lng'];
197
198        try {
199            $nextRequestableHint = $this->questionHintTracking->getNextRequestableHint();
200        } catch (ilTestNoNextRequestableHintExistsException $e) {
201            $ilCtrl->redirect($this, self::CMD_BACK_TO_QUESTION);
202        }
203
204        require_once 'Services/Utilities/classes/class.ilConfirmationGUI.php';
205
206        $confirmation = new ilConfirmationGUI();
207
208        $formAction = ilUtil::appendUrlParameterString(
209            $ilCtrl->getFormAction($this),
210            "hintId={$nextRequestableHint->getId()}"
211        );
212
213        $confirmation->setFormAction($formAction);
214
215        $confirmation->setConfirm($lng->txt('tst_question_hints_confirm_request'), self::CMD_PERFORM_REQUEST);
216        $confirmation->setCancel($lng->txt('tst_question_hints_cancel_request'), self::CMD_BACK_TO_QUESTION);
217
218        $confirmation->setHeaderText(sprintf(
219            $lng->txt('tst_question_hints_request_confirmation'),
220            $nextRequestableHint->getIndex(),
221            $nextRequestableHint->getPoints()
222        ));
223
224        $this->populateContent($ilCtrl->getHtml($confirmation));
225    }
226
227    /**
228     * Performs a hint request and invokes the (re-)saving the question solution.
229     * Redirects to local showHint command
230     *
231     * @access	private
232     * @global	ilCtrl $ilCtrl
233     */
234    private function performRequestCmd()
235    {
236        global $DIC;
237        $ilCtrl = $DIC['ilCtrl'];
238
239        if (!isset($_GET['hintId']) || !(int) $_GET['hintId']) {
240            throw new ilTestException('no hint id given');
241        }
242
243        try {
244            $nextRequestableHint = $this->questionHintTracking->getNextRequestableHint();
245        } catch (ilTestNoNextRequestableHintExistsException $e) {
246            $ilCtrl->redirect($this, self::CMD_BACK_TO_QUESTION);
247        }
248
249        if ($nextRequestableHint->getId() != (int) $_GET['hintId']) {
250            throw new ilTestException('given hint id does not relate to the next requestable hint');
251        }
252
253        $this->questionHintTracking->storeRequest($nextRequestableHint);
254
255        $redirectTarget = $this->getHintPresentationLinkTarget($nextRequestableHint->getId(), false);
256
257        ilUtil::redirect($redirectTarget);
258    }
259
260    /**
261     * gateway command method to jump back to test session output
262     *
263     * @access	private
264     * @global	ilCtrl $ilCtrl
265     */
266    private function backToQuestionCmd()
267    {
268        global $DIC;
269        $ilCtrl = $DIC['ilCtrl'];
270
271        $ilCtrl->redirect($this->parentGUI, $this->parentCMD);
272    }
273
274    /**
275     * populates the rendered questin hint relating output content to global template
276     * depending on possibly active kiosk mode
277     *
278     * @global ilTemplate $tpl
279     * @param string $content
280     */
281    private function populateContent($content)
282    {
283        global $DIC;
284        $tpl = $DIC['tpl'];
285
286        if (!$this->isQuestionPreview() && $this->parentGUI->object->getKioskMode()) {
287            $tpl->setBodyClass('kiosk');
288            $tpl->setAddFooter(false);
289
290            $tpl->addBlockFile(
291                'CONTENT',
292                'content',
293                'tpl.il_tst_question_hints_kiosk_page.html',
294                'Modules/TestQuestionPool'
295            );
296
297            $tpl->setVariable('KIOSK_HEAD', $this->parentGUI->getKioskHead());
298
299            $tpl->setVariable('KIOSK_CONTENT', $content);
300        } else {
301            $tpl->setContent($content);
302        }
303    }
304
305    private function isQuestionPreview()
306    {
307        if ($this->questionHintTracking instanceof ilAssQuestionPreviewHintTracking) {
308            return true;
309        }
310
311        return false;
312    }
313
314    /**
315     * returns the link target for hint request presentation
316     *
317     * @global ilCtrl $ilCtrl
318     * @param integer $hintId
319     * @param boolean $xmlStyle
320     * @return string $linkTarget
321     */
322    public function getHintPresentationLinkTarget($hintId, $xmlStyle = true)
323    {
324        global $DIC;
325        $ilCtrl = $DIC['ilCtrl'];
326
327        if ($this->questionOBJ->isAdditionalContentEditingModePageObject()) {
328            $ilCtrl->setParameterByClass('ilasshintpagegui', 'hint_id', $hintId);
329            $linkTarget = $ilCtrl->getLinkTargetByClass('ilAssHintPageGUI', '', '', false, $xmlStyle);
330        } else {
331            $ilCtrl->setParameter($this, 'hintId', $hintId);
332            $linkTarget = $ilCtrl->getLinkTarget($this, self::CMD_SHOW_HINT, '', false, $xmlStyle);
333        }
334
335        return $linkTarget;
336    }
337}
338