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.ilAssQuestionHintGUI.php';
6require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionHintsOrderingClipboard.php';
7
8/**
9 * @ilCtrl_Calls ilAssQuestionHintsGUI: ilAssQuestionHintGUI
10 *
11 * GUI class for hints management of assessment questions
12 *
13 * @author		Björn Heyser <bheyser@databay.de>
14 * @version		$Id$
15 *
16 * @package		Modules/TestQuestionPool
17 *
18 * @ilCtrl_Calls ilAssQuestionHintsGUI: ilAssQuestionHintsTableGUI
19 * @ilCtrl_Calls ilAssQuestionHintsGUI: ilAssHintPageGUI
20 * @ilCtrl_Calls ilAssQuestionHintsGUI: ilToolbarGUI, ilConfirmationGUI
21 */
22class ilAssQuestionHintsGUI extends ilAssQuestionHintAbstractGUI
23{
24    /**
25     * command constants
26     */
27    const CMD_SHOW_LIST = 'showList';
28    const CMD_SHOW_HINT = 'showHint';
29    const CMD_CONFIRM_DELETE = 'confirmDelete';
30    const CMD_PERFORM_DELETE = 'performDelete';
31    const CMD_SAVE_LIST_ORDER = 'saveListOrder';
32    const CMD_CUT_TO_ORDERING_CLIPBOARD = 'cutToOrderingClipboard';
33    const CMD_PASTE_FROM_ORDERING_CLIPBOARD_BEFORE = 'pasteFromOrderingClipboardBefore';
34    const CMD_PASTE_FROM_ORDERING_CLIPBOARD_AFTER = 'pasteFromOrderingClipboardAfter';
35    const CMD_RESET_ORDERING_CLIPBOARD = 'resetOrderingClipboard';
36    const CMD_CONFIRM_SYNC = 'confirmSync';
37
38    /**
39     * object that handles the current ordering clipboard state
40     *
41     * @access	private
42     * @var		ilAssQuestionHintOrderingClipboard
43     */
44    private $hintOrderingClipboard = null;
45
46    /**
47     * @var bool
48     */
49    protected $editingEnabled = false;
50
51    /**
52     * Constructor
53     *
54     * @access	public
55     * @param	assQuestionGUI	$questionGUI
56     */
57    public function __construct(assQuestionGUI $questionGUI)
58    {
59        parent::__construct($questionGUI);
60
61        $this->hintOrderingClipboard = new ilAssQuestionHintsOrderingClipboard($questionGUI->object);
62    }
63
64    /**
65     * @return bool
66     */
67    public function isEditingEnabled()
68    {
69        return $this->editingEnabled;
70    }
71
72    /**
73     * @param bool $editingEnabled
74     */
75    public function setEditingEnabled(bool $editingEnabled)
76    {
77        $this->editingEnabled = $editingEnabled;
78    }
79
80    /**
81     * Execute Command
82     *
83     * @access	public
84     * @global	ilCtrl	$ilCtrl
85     * @return	mixed
86     */
87    public function executeCommand()
88    {
89        global $DIC;
90        $ilCtrl = $DIC['ilCtrl'];
91        $ilTabs = $DIC['ilTabs'];
92        $lng = $DIC['lng'];
93        global $DIC; /* @var \ILIAS\DI\Container $DIC */
94        $ilHelp = $DIC['ilHelp']; /* @var ilHelpGUI $ilHelp */
95        $ilHelp->setScreenIdComponent('qpl');
96
97        require_once "./Services/Style/Content/classes/class.ilObjStyleSheet.php";
98        $DIC->ui()->mainTemplate()->setCurrentBlock("ContentStyle");
99        $DIC->ui()->mainTemplate()->setVariable("LOCATION_CONTENT_STYLESHEET", ilObjStyleSheet::getContentStylePath(0));
100        $DIC->ui()->mainTemplate()->parseCurrentBlock();
101
102        $cmd = $ilCtrl->getCmd(self::CMD_SHOW_LIST);
103        $nextClass = $ilCtrl->getNextClass($this);
104
105        switch ($nextClass) {
106            case 'ilassquestionhintgui':
107
108                if (!$this->isEditingEnabled()) {
109                    return;
110                }
111
112                require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionHintGUI.php';
113                $gui = new ilAssQuestionHintGUI($this->questionGUI);
114                $ilCtrl->forwardCommand($gui);
115                break;
116
117            case 'ilasshintpagegui':
118
119                if ($this->isEditingEnabled()) {
120                    $presentationMode = ilAssQuestionHintPageObjectCommandForwarder::PRESENTATION_MODE_AUTHOR;
121                } else {
122                    $presentationMode = ilAssQuestionHintPageObjectCommandForwarder::PRESENTATION_MODE_PREVIEW;
123                }
124
125                require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionHintPageObjectCommandForwarder.php';
126                $forwarder = new ilAssQuestionHintPageObjectCommandForwarder($this->questionOBJ, $ilCtrl, $ilTabs, $lng);
127                $forwarder->setPresentationMode($presentationMode);
128                $forwarder->forward();
129                break;
130
131            default:
132
133                $cmd .= 'Cmd';
134                $this->$cmd();
135                break;
136        }
137    }
138
139    /**
140     * shows a table with existing hints
141     *
142     * @access	private
143     * @global	ilTemplate	$tpl
144     */
145    private function showListCmd()
146    {
147        global $DIC;
148        $ilCtrl = $DIC['ilCtrl'];
149        $tpl = $DIC['tpl'];
150        $lng = $DIC['lng'];
151
152        $this->initHintOrderingClipboardNotification();
153
154        require_once 'Services/UIComponent/Toolbar/classes/class.ilToolbarGUI.php';
155        require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionHintsTableGUI.php';
156
157        $toolbar = new ilToolbarGUI();
158
159        $questionHintList = ilAssQuestionHintList::getListByQuestionId($this->questionOBJ->getId());
160
161        if ($this->isEditingEnabled()) {
162            if ($this->hintOrderingClipboard->hasStored()) {
163                $questionHintList = $this->getQuestionHintListWithoutHintStoredInOrderingClipboard($questionHintList);
164
165                $toolbar->addButton(
166                    $lng->txt('tst_questions_hints_toolbar_cmd_reset_ordering_clipboard'),
167                    $ilCtrl->getLinkTarget($this, self::CMD_RESET_ORDERING_CLIPBOARD)
168                );
169            } else {
170                $toolbar->addButton(
171                    $lng->txt('tst_questions_hints_toolbar_cmd_add_hint'),
172                    $ilCtrl->getLinkTargetByClass('ilAssQuestionHintGUI', ilAssQuestionHintGUI::CMD_SHOW_FORM)
173                );
174            }
175
176            $tableMode = ilAssQuestionHintsTableGUI::TBL_MODE_ADMINISTRATION;
177        } else {
178            $tableMode = ilAssQuestionHintsTableGUI::TBL_MODE_TESTOUTPUT;
179        }
180
181        $table = new ilAssQuestionHintsTableGUI(
182            $this->questionOBJ,
183            $questionHintList,
184            $this,
185            self::CMD_SHOW_LIST,
186            $tableMode,
187            $this->hintOrderingClipboard
188        );
189
190        $tpl->setContent($ilCtrl->getHtml($toolbar) . $ilCtrl->getHtml($table));
191    }
192
193    /**
194     * shows a confirmation screen with selected hints for deletion
195     *
196     * @access	private
197     * @global	ilCtrl		$ilCtrl
198     * @global	ilTemplate	$tpl
199     * @global	ilLanguage	$lng
200     */
201    private function confirmDeleteCmd()
202    {
203        global $DIC;
204        $ilCtrl = $DIC['ilCtrl'];
205        $tpl = $DIC['tpl'];
206        $lng = $DIC['lng'];
207
208        $hintIds = self::fetchHintIdsParameter();
209
210        if (!count($hintIds)) {
211            ilUtil::sendFailure($lng->txt('tst_question_hints_delete_hints_missing_selection_msg'), true);
212            $ilCtrl->redirect($this);
213        }
214
215        require_once 'Services/Utilities/classes/class.ilConfirmationGUI.php';
216        $confirmation = new ilConfirmationGUI();
217
218        $confirmation->setHeaderText($lng->txt('tst_question_hints_delete_hints_confirm_header'));
219        $confirmation->setFormAction($ilCtrl->getFormAction($this));
220        $confirmation->setConfirm($lng->txt('tst_question_hints_delete_hints_confirm_cmd'), self::CMD_PERFORM_DELETE);
221        $confirmation->setCancel($lng->txt('cancel'), self::CMD_SHOW_LIST);
222
223        $questionHintList = ilAssQuestionHintList::getListByQuestionId($this->questionOBJ->getId());
224
225        foreach ($questionHintList as $questionHint) {
226            /* @var $questionHint ilAssQuestionHint */
227
228            if (in_array($questionHint->getId(), $hintIds)) {
229                $confirmation->addItem('hint_ids[]', $questionHint->getId(), sprintf(
230                    $lng->txt('tst_question_hints_delete_hints_confirm_item'),
231                    $questionHint->getIndex(),
232                    $questionHint->getText()
233                ));
234            }
235        }
236
237        $tpl->setContent($ilCtrl->getHtml($confirmation));
238    }
239
240    /**
241     * performs confirmed deletion for selected hints
242     *
243     * @access	private
244     * @global	ilCtrl		$ilCtrl
245     * @global	ilLanguage	$lng
246     */
247    private function performDeleteCmd()
248    {
249        if (!$this->isEditingEnabled()) {
250            return;
251        }
252
253        global $DIC;
254        $ilCtrl = $DIC['ilCtrl'];
255        $tpl = $DIC['tpl'];
256        $lng = $DIC['lng'];
257
258        $hintIds = self::fetchHintIdsParameter();
259
260        if (!count($hintIds)) {
261            ilUtil::sendFailure($lng->txt('tst_question_hints_delete_hints_missing_selection_msg'), true);
262            $ilCtrl->redirect($this);
263        }
264
265        $questionCompleteHintList = ilAssQuestionHintList::getListByQuestionId($this->questionOBJ->getId());
266
267        $questionRemainingHintList = new ilAssQuestionHintList();
268
269        foreach ($questionCompleteHintList as $listKey => $questionHint) {
270            /* @var $questionHint ilAssQuestionHint */
271
272            if (in_array($questionHint->getId(), $hintIds)) {
273                $questionHint->delete();
274            } else {
275                $questionRemainingHintList->addHint($questionHint);
276            }
277        }
278
279        $questionRemainingHintList->reIndex();
280
281        ilUtil::sendSuccess($lng->txt('tst_question_hints_delete_success_msg'), true);
282
283        $originalexists = $this->questionOBJ->_questionExistsInPool($this->questionOBJ->original_id);
284        include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
285        global $DIC;
286        $ilUser = $DIC['ilUser'];
287        if ($_GET["calling_test"] && $originalexists && assQuestion::_isWriteable($this->questionOBJ->original_id, $ilUser->getId())) {
288            $ilCtrl->redirectByClass('ilAssQuestionHintsGUI', ilAssQuestionHintsGUI::CMD_CONFIRM_SYNC);
289        }
290
291        $ilCtrl->redirect($this);
292    }
293
294    /**
295     * saves the order based on index values passed from table's form
296     * (the table must not be paginated, because ALL hints index values are required)
297     *
298     * @access	private
299     * @global	ilCtrl		$ilCtrl
300     * @global	ilLanguage	$lng
301     */
302    private function saveListOrderCmd()
303    {
304        if (!$this->isEditingEnabled()) {
305            return;
306        }
307
308        global $DIC;
309        $ilCtrl = $DIC['ilCtrl'];
310        $lng = $DIC['lng'];
311
312        $hintIndexes = self::orderHintIndexes(
313            self::fetchHintIndexesParameter()
314        );
315
316        if (!count($hintIndexes)) {
317            ilUtil::sendFailure($lng->txt('tst_question_hints_save_order_unkown_failure_msg'), true);
318            $ilCtrl->redirect($this);
319        }
320
321        $curQuestionHintList = ilAssQuestionHintList::getListByQuestionId($this->questionOBJ->getId());
322
323        $newQuestionHintList = new ilAssQuestionHintList();
324
325        foreach ($hintIndexes as $hintId => $hintIndex) {
326            if (!$curQuestionHintList->hintExists($hintId)) {
327                ilUtil::sendFailure($lng->txt('tst_question_hints_save_order_unkown_failure_msg'), true);
328                $ilCtrl->redirect($this);
329            }
330
331            $questionHint = $curQuestionHintList->getHint($hintId);
332
333            $newQuestionHintList->addHint($questionHint);
334        }
335
336        $newQuestionHintList->reIndex();
337
338        ilUtil::sendSuccess($lng->txt('tst_question_hints_save_order_success_msg'), true);
339
340        $originalexists = $this->questionOBJ->_questionExistsInPool($this->questionOBJ->original_id);
341        include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
342        global $DIC;
343        $ilUser = $DIC['ilUser'];
344        if ($_GET["calling_test"] && $originalexists && assQuestion::_isWriteable($this->questionOBJ->original_id, $ilUser->getId())) {
345            $ilCtrl->redirectByClass('ilAssQuestionHintsGUI', ilAssQuestionHintsGUI::CMD_CONFIRM_SYNC);
346        }
347
348        $ilCtrl->redirect($this);
349    }
350
351    /**
352     * cuts a hint from question hint list and stores it to ordering clipboard
353     *
354     * @access	private
355     * @global	ilCtrl	$ilCtrl
356     */
357    private function cutToOrderingClipboardCmd()
358    {
359        if (!$this->isEditingEnabled()) {
360            return;
361        }
362
363        global $DIC;
364        $ilCtrl = $DIC['ilCtrl'];
365
366        $moveHintIds = self::fetchHintIdsParameter();
367        $this->checkForSingleHintIdAndRedirectOnFailure($moveHintIds);
368
369        $moveHintId = current($moveHintIds);
370
371        $this->checkForExistingHintRelatingToCurrentQuestionAndRedirectOnFailure($moveHintId);
372
373        $this->hintOrderingClipboard->setStored($moveHintId);
374
375        $ilCtrl->redirect($this, self::CMD_SHOW_LIST);
376    }
377
378    /**
379     * pastes a hint from ordering clipboard before the selected one
380     *
381     * @access	private
382     * @global	ilCtrl		$ilCtrl
383     * @global	ilLanguage	$lng
384     */
385    private function pasteFromOrderingClipboardBeforeCmd()
386    {
387        if (!$this->isEditingEnabled()) {
388            return;
389        }
390
391        global $DIC;
392        $ilCtrl = $DIC['ilCtrl'];
393        $lng = $DIC['lng'];
394
395        $targetHintIds = self::fetchHintIdsParameter();
396        $this->checkForSingleHintIdAndRedirectOnFailure($targetHintIds);
397
398        $targetHintId = current($targetHintIds);
399
400        $this->checkForExistingHintRelatingToCurrentQuestionAndRedirectOnFailure($targetHintId);
401
402        $curQuestionHintList = ilAssQuestionHintList::getListByQuestionId($this->questionOBJ->getId());
403        $newQuestionHintList = new ilAssQuestionHintList($this->questionOBJ->getId());
404
405        foreach ($curQuestionHintList as $questionHint) {
406            /* @var $questionHint ilAssQuestionHint */
407
408            if ($questionHint->getId() == $this->hintOrderingClipboard->getStored()) {
409                continue;
410            }
411
412            if ($questionHint->getId() == $targetHintId) {
413                $targetQuestionHint = $questionHint;
414
415                $pasteQuestionHint = ilAssQuestionHint::getInstanceById($this->hintOrderingClipboard->getStored());
416
417                $newQuestionHintList->addHint($pasteQuestionHint);
418            }
419
420            $newQuestionHintList->addHint($questionHint);
421        }
422
423        $successMsg = sprintf(
424            $lng->txt('tst_question_hints_paste_before_success_msg'),
425            $pasteQuestionHint->getIndex(),
426            $targetQuestionHint->getIndex()
427        );
428
429        $newQuestionHintList->reIndex();
430
431        $this->hintOrderingClipboard->resetStored();
432
433        ilUtil::sendSuccess($successMsg, true);
434
435        $ilCtrl->redirect($this, self::CMD_SHOW_LIST);
436    }
437
438    /**
439     * pastes a hint from ordering clipboard after the selected one
440     *
441     * @access	private
442     * @global	ilCtrl		$ilCtrl
443     * @global	ilLanguage	$lng
444     */
445    private function pasteFromOrderingClipboardAfterCmd()
446    {
447        if (!$this->isEditingEnabled()) {
448            return;
449        }
450
451        global $DIC;
452        $ilCtrl = $DIC['ilCtrl'];
453        $lng = $DIC['lng'];
454
455        $targetHintIds = self::fetchHintIdsParameter();
456        $this->checkForSingleHintIdAndRedirectOnFailure($targetHintIds);
457
458        $targetHintId = current($targetHintIds);
459
460        $this->checkForExistingHintRelatingToCurrentQuestionAndRedirectOnFailure($targetHintId);
461
462        $curQuestionHintList = ilAssQuestionHintList::getListByQuestionId($this->questionOBJ->getId());
463        $newQuestionHintList = new ilAssQuestionHintList($this->questionOBJ->getId());
464
465        foreach ($curQuestionHintList as $questionHint) {
466            /* @var $questionHint ilAssQuestionHint */
467
468            if ($questionHint->getId() == $this->hintOrderingClipboard->getStored()) {
469                continue;
470            }
471
472            $newQuestionHintList->addHint($questionHint);
473
474            if ($questionHint->getId() == $targetHintId) {
475                $targetQuestionHint = $questionHint;
476
477                $pasteQuestionHint = ilAssQuestionHint::getInstanceById($this->hintOrderingClipboard->getStored());
478
479                $newQuestionHintList->addHint($pasteQuestionHint);
480            }
481        }
482
483        $successMsg = sprintf(
484            $lng->txt('tst_question_hints_paste_after_success_msg'),
485            $pasteQuestionHint->getIndex(),
486            $targetQuestionHint->getIndex()
487        );
488
489        $newQuestionHintList->reIndex();
490
491        $this->hintOrderingClipboard->resetStored();
492
493        ilUtil::sendSuccess($successMsg, true);
494
495        $ilCtrl->redirect($this, self::CMD_SHOW_LIST);
496    }
497
498    /**
499     * resets the ordering clipboard
500     *
501     * @access	private
502     * @global	ilCtrl		$ilCtrl
503     * @global	ilLanguage	$lng
504     */
505    private function resetOrderingClipboardCmd()
506    {
507        global $DIC;
508        $ilCtrl = $DIC['ilCtrl'];
509        $lng = $DIC['lng'];
510
511        $this->hintOrderingClipboard->resetStored();
512
513        ilUtil::sendInfo($lng->txt('tst_question_hints_ordering_clipboard_resetted'), true);
514        $ilCtrl->redirect($this, self::CMD_SHOW_LIST);
515    }
516
517    /**
518     * inits the notification telling the user,
519     * that a hint is stored to hint ordering clipboard
520     *
521     * @access	private
522     * @global	ilLanguage	$lng
523     */
524    private function initHintOrderingClipboardNotification()
525    {
526        global $DIC;
527        $lng = $DIC['lng'];
528
529        if (!$this->hintOrderingClipboard->hasStored()) {
530            return;
531        }
532
533        $questionHint = ilAssQuestionHint::getInstanceById($this->hintOrderingClipboard->getStored());
534
535        ilUtil::sendInfo(sprintf(
536            $lng->txt('tst_question_hints_item_stored_in_ordering_clipboard'),
537            $questionHint->getIndex()
538        ));
539    }
540
541    /**
542     * checks for an existing hint relating to current question and redirects
543     * with corresponding failure message on failure
544     *
545     * @access	private
546     * @param	integer	$hintId
547     */
548    private function checkForExistingHintRelatingToCurrentQuestionAndRedirectOnFailure($hintId)
549    {
550        $questionHintList = ilAssQuestionHintList::getListByQuestionId($this->questionOBJ->getId());
551
552        if (!$questionHintList->hintExists($hintId)) {
553            ilUtil::sendFailure($lng->txt('tst_question_hints_invalid_hint_id'), true);
554            $ilCtrl->redirect($this, self::CMD_SHOW_LIST);
555        }
556    }
557
558    /**
559     * returns a new quastion hint list that contains all question hints
560     * from the passed list except for the hint that is stored to ordering clipboard
561     *
562     * @access	private
563     * @param	ilAssQuestionHintList	$questionHintList
564     * @return	ilAssQuestionHintList	$filteredQuestionHintList
565     */
566    private function getQuestionHintListWithoutHintStoredInOrderingClipboard(ilAssQuestionHintList $questionHintList)
567    {
568        $filteredQuestionHintList = new ilAssQuestionHintList();
569
570        foreach ($questionHintList as $questionHint) {
571            /* @var $questionHint ilAssQuestionHint */
572
573            if ($questionHint->getId() != $this->hintOrderingClipboard->getStored()) {
574                $filteredQuestionHintList->addHint($questionHint);
575            }
576        }
577
578        return $filteredQuestionHintList;
579    }
580
581    /**
582     * checks for a hint id in the passed array and redirects
583     * with corresponding failure message if not exactly one id is given
584     *
585     * @access	private
586     * @global	ilCtrl		$ilCtrl
587     * @global	ilLanguage	$lng
588     * @param	array		$hintIds
589     */
590    private function checkForSingleHintIdAndRedirectOnFailure($hintIds)
591    {
592        global $DIC;
593        $ilCtrl = $DIC['ilCtrl'];
594        $lng = $DIC['lng'];
595
596        if (!count($hintIds)) {
597            ilUtil::sendFailure($lng->txt('tst_question_hints_cut_hints_missing_selection_msg'), true);
598            $ilCtrl->redirect($this, self::CMD_SHOW_LIST);
599        } elseif (count($hintIds) > 1) {
600            ilUtil::sendFailure($lng->txt('tst_question_hints_cut_hints_single_selection_msg'), true);
601            $ilCtrl->redirect($this, self::CMD_SHOW_LIST);
602        }
603    }
604
605    /**
606     * fetches either an array of hint ids from POST or a single hint id from GET
607     * and returns an array of (a single) hint id(s) casted to integer in both cases
608     *
609     * @access	private
610     * @static
611     * @return	array	$hintIds
612     */
613    private static function fetchHintIdsParameter()
614    {
615        $hintIds = array();
616
617        if (isset($_POST['hint_ids']) && is_array($_POST['hint_ids'])) {
618            foreach ($_POST['hint_ids'] as $hintId) {
619                if ((int) $hintId) {
620                    $hintIds[] = (int) $hintId;
621                }
622            }
623        } elseif (isset($_GET['hint_id']) && (int) $_GET['hint_id']) {
624            $hintIds[] = (int) $_GET['hint_id'];
625        }
626
627        return $hintIds;
628    }
629
630    /**
631     * fetches an array of hint index values from POST
632     *
633     * @access	private
634     * @static
635     * @return	array	$hintIndexes
636     */
637    private static function fetchHintIndexesParameter()
638    {
639        $hintIndexes = array();
640
641        if (isset($_POST['hint_indexes']) && is_array($_POST['hint_indexes'])) {
642            foreach ($_POST['hint_indexes'] as $hintId => $hintIndex) {
643                if ((int) $hintId) {
644                    $hintIndexes[(int) $hintId] = $hintIndex;
645                }
646            }
647        }
648
649        return $hintIndexes;
650    }
651
652    /**
653     * sorts the array of indexes by index value so keys (hint ids)
654     * get into new order submitted by user
655     *
656     * @access	private
657     * @static
658     * @return	array	$hintIndexes
659     */
660    private static function orderHintIndexes($hintIndexes)
661    {
662        asort($hintIndexes);
663
664        return $hintIndexes;
665    }
666
667    public function confirmSyncCmd()
668    {
669        $this->questionGUI->originalSyncForm('showHints');
670    }
671
672    /**
673     * returns the link target for hint request presentation
674     *
675     * @param integer $hintId
676     * @param boolean $xmlStyle
677     * @return string $linkTarget
678     */
679    public function getHintPresentationLinkTarget($hintId, $xmlStyle = true)
680    {
681        global $DIC;
682        $ilCtrl = $DIC['ilCtrl'];
683
684        if ($this->questionOBJ->isAdditionalContentEditingModePageObject()) {
685            $ilCtrl->setParameterByClass('ilasshintpagegui', 'hint_id', $hintId);
686            $linkTarget = $ilCtrl->getLinkTargetByClass('ilAssHintPageGUI', '', '', false, $xmlStyle);
687        } else {
688            $ilCtrl->setParameter($this, 'hintId', $hintId);
689            $linkTarget = $ilCtrl->getLinkTarget($this, self::CMD_SHOW_HINT, '', false, $xmlStyle);
690        }
691
692        return $linkTarget;
693    }
694
695    /**
696     * shows an allready requested hint
697     *
698     * @access	private
699     * @global	ilCtrl $ilCtrl
700     * @global	ilTemplate $tpl
701     * @global	ilLanguage $lng
702     */
703    private function showHintCmd()
704    {
705        global $DIC;
706        $ilCtrl = $DIC['ilCtrl'];
707        $tpl = $DIC['tpl'];
708        $lng = $DIC['lng'];
709
710        if (!isset($_GET['hintId']) || !(int) $_GET['hintId']) {
711            throw new ilTestException('no hint id given');
712        }
713
714        $DIC->tabs()->clearTargets();
715        $DIC->tabs()->clearSubTabs();
716
717        $DIC->tabs()->setBackTarget(
718            $DIC->language()->txt('tst_question_hints_back_to_hint_list'),
719            $DIC->ctrl()->getLinkTarget($this, self::CMD_SHOW_LIST)
720        );
721
722        $questionHint = ilAssQuestionHint::getInstanceById((int) $_GET['hintId']);
723
724        // build form
725
726        $form = new ilPropertyFormGUI();
727
728        $form->setFormAction($ilCtrl->getFormAction($this));
729
730        $form->setTableWidth('100%');
731
732        $form->setTitle(sprintf(
733            $lng->txt('tst_question_hints_form_header_edit'),
734            $questionHint->getIndex(),
735            $this->questionOBJ->getTitle()
736        ));
737
738        // form input: hint text
739
740        $nonEditableHintText = new ilNonEditableValueGUI($lng->txt('tst_question_hints_form_label_hint_text'), 'hint_text', true);
741        $nonEditableHintText->setValue(ilUtil::prepareTextareaOutput($questionHint->getText(), true));
742        $form->addItem($nonEditableHintText);
743
744        // form input: hint points
745
746        $nonEditableHintPoints = new ilNonEditableValueGUI($lng->txt('tst_question_hints_form_label_hint_points'), 'hint_points');
747        $nonEditableHintPoints->setValue($questionHint->getPoints());
748        $form->addItem($nonEditableHintPoints);
749
750        $tpl->setContent($form->getHTML());
751    }
752}
753