ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
class.ilAssQuestionHintsGUI.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
4 require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionHintAbstractGUI.php';
5 require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionHintGUI.php';
6 require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionHintsOrderingClipboard.php';
7 
23 {
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 
44  private $hintOrderingClipboard = null;
45 
49  protected $editingEnabled = false;
50 
58  {
59  parent::__construct($questionGUI);
60 
61  $this->hintOrderingClipboard = new ilAssQuestionHintsOrderingClipboard($questionGUI->object);
62  }
63 
67  public function isEditingEnabled()
68  {
69  return $this->editingEnabled;
70  }
71 
75  public function setEditingEnabled(bool $editingEnabled)
76  {
77  $this->editingEnabled = $editingEnabled;
78  }
79 
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()) {
121  } else {
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 
145  private function showListCmd()
146  {
147  global $DIC;
148  $ilCtrl = $DIC['ilCtrl'];
149  $tpl = $DIC['tpl'];
150  $lng = $DIC['lng'];
151 
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 
177  } else {
179  }
180 
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 
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 
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 
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 
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 
372 
373  $this->hintOrderingClipboard->setStored($moveHintId);
374 
375  $ilCtrl->redirect($this, self::CMD_SHOW_LIST);
376  }
377 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 }
static getListByQuestionId($questionId)
instantiates a question hint list for the passed question id
static orderHintIndexes($hintIndexes)
sorts the array of indexes by index value so keys (hint ids) get into new order submitted by user ...
getHintPresentationLinkTarget($hintId, $xmlStyle=true)
returns the link target for hint request presentation
static getInstanceById($hintId)
creates a hint object instance, loads the persisted hint dataset identified by passed hint id from da...
This class represents a property form user interface.
global $DIC
Definition: saml.php:7
$_GET["client_id"]
$tpl
Definition: ilias.php:10
static prepareTextareaOutput($txt_output, $prepare_for_latex_output=false, $omitNl2BrWhenTextArea=false)
Prepares a string for a text area output where latex code may be in it If the text is HTML-free...
showListCmd()
shows a table with existing hints
showHintCmd()
shows an allready requested hint
static fetchHintIdsParameter()
fetches either an array of hint ids from POST or a single hint id from GET and returns an array of (a...
const CMD_SHOW_LIST
command constants
getQuestionHintListWithoutHintStoredInOrderingClipboard(ilAssQuestionHintList $questionHintList)
returns a new quastion hint list that contains all question hints from the passed list except for the...
Base Exception for all Exceptions relating to Modules/Test.
__construct(assQuestionGUI $questionGUI)
Constructor.
global $ilCtrl
Definition: ilias.php:18
static sendInfo($a_info="", $a_keep=false)
Send Info Message to Screen.
resetOrderingClipboardCmd()
resets the ordering clipboard
const TBL_MODE_TESTOUTPUT
the available table modes controlling the tables behaviour
cutToOrderingClipboardCmd()
cuts a hint from question hint list and stores it to ordering clipboard
if(isset($_POST['submit'])) $form
$lng
pasteFromOrderingClipboardAfterCmd()
pastes a hint from ordering clipboard after the selected one
$ilUser
Definition: imgupload.php:18
static getContentStylePath($a_style_id, $add_random=true)
get content style path
Basic GUI class for assessment questions.
confirmDeleteCmd()
shows a confirmation screen with selected hints for deletion
performDeleteCmd()
performs confirmed deletion for selected hints
static sendFailure($a_info="", $a_keep=false)
Send Failure Message to Screen.
const CMD_SHOW_FORM
command constants
static fetchHintIndexesParameter()
fetches an array of hint index values from POST
This class represents a non editable value in a property form.
pasteFromOrderingClipboardBeforeCmd()
pastes a hint from ordering clipboard before the selected one
addHint(ilAssQuestionHint $questionHint)
adds a question hint object to the current list instance
saveListOrderCmd()
saves the order based on index values passed from table&#39;s form (the table must not be paginated...
checkForSingleHintIdAndRedirectOnFailure($hintIds)
checks for a hint id in the passed array and redirects with corresponding failure message if not exac...
if(empty($password)) $table
Definition: pwgen.php:24
setEditingEnabled(bool $editingEnabled)
initHintOrderingClipboardNotification()
inits the notification telling the user, that a hint is stored to hint ordering clipboard ...
$_POST["username"]
checkForExistingHintRelatingToCurrentQuestionAndRedirectOnFailure($hintId)
checks for an existing hint relating to current question and redirects with corresponding failure mes...
Confirmation screen class.
static _isWriteable($question_id, $user_id)
Returns true if the question is writeable by a certain user.