ILIAS  release_7 Revision v7.30-3-g800a261c036
class.assOrderingHorizontalGUI.php
Go to the documentation of this file.
1<?php
2/* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4require_once './Modules/TestQuestionPool/classes/class.assQuestionGUI.php';
5require_once './Modules/TestQuestionPool/interfaces/interface.ilGuiQuestionScoringAdjustable.php';
6require_once './Modules/Test/classes/inc.AssessmentConstants.php';
7
23{
32 public function __construct($id = -1)
33 {
35 include_once "./Modules/TestQuestionPool/classes/class.assOrderingHorizontal.php";
36 $this->object = new assOrderingHorizontal();
37 $this->setErrorMessage($this->lng->txt("msg_form_save_error"));
38 if ($id >= 0) {
39 $this->object->loadFromDb($id);
40 }
41 }
42
43 public function getCommand($cmd)
44 {
45 return $cmd;
46 }
47
51 protected function writePostData($always = false)
52 {
53 $hasErrors = (!$always) ? $this->editQuestion(true) : false;
54 if (!$hasErrors) {
55 require_once 'Services/Form/classes/class.ilPropertyFormGUI.php';
59 return 0;
60 }
61 return 1;
62 }
63
69 public function editQuestion($checkonly = false)
70 {
71 $save = $this->isSaveCommand();
72 $this->getQuestionTemplate();
73
74 include_once("./Services/Form/classes/class.ilPropertyFormGUI.php");
75 $form = new ilPropertyFormGUI();
76 $this->editForm = $form;
77
78 $form->setFormAction($this->ctrl->getFormAction($this));
79 $form->setTitle($this->outQuestionType());
80 $form->setMultipart(false);
81 $form->setTableWidth("100%");
82 $form->setId("orderinghorizontal");
83
86
87
88 $this->populateTaxonomyFormSection($form);
89
91
92 $errors = false;
93
94 if ($save) {
95 $form->setValuesByPost();
96 $errors = !$form->checkInput();
97 $form->setValuesByPost(); // again, because checkInput now performs the whole stripSlashes handling and we need this if we don't want to have duplication of backslashes
98 if ($errors) {
99 $checkonly = false;
100 }
101 }
102
103 if (!$checkonly) {
104 $this->tpl->setVariable("QUESTION_DATA", $form->getHTML());
105 }
106 return $errors;
107 }
108
115 {
116 return true;
117 }
118
132 public function getSolutionOutput(
133 $active_id,
134 $pass = null,
135 $graphicalOutput = false,
136 $result_output = false,
137 $show_question_only = true,
138 $show_feedback = false,
139 $show_correct_solution = false,
140 $show_manual_scoring = false,
141 $show_question_text = true
142 ) {
143 // get the solution of the user for the active pass or from the last pass if allowed
144 $template = new ilTemplate("tpl.il_as_qpl_orderinghorizontal_output_solution.html", true, true, "Modules/TestQuestionPool");
145
146 if (($active_id > 0) && (!$show_correct_solution)) {
147 $elements = [];
148 $solutions = $this->object->getSolutionValues($active_id, $pass, !$this->getUseIntermediateSolution());
149 if (strlen($solutions[0]["value1"])) {
150 $elements = explode("{::}", $solutions[0]["value1"]);
151 }
152
153 if (!count($elements)) {
154 $elements = $this->object->getRandomOrderingElements();
155 }
156
157 foreach ($elements as $id => $element) {
158 $template->setCurrentBlock("element");
159 $template->setVariable("ELEMENT_ID", "sol_e_" . $this->object->getId() . "_$id");
160 $template->setVariable("ELEMENT_VALUE", ilUtil::prepareFormOutput($element));
161 $template->parseCurrentBlock();
162 }
163 } else {
164 $elements = $this->object->getOrderingElements();
165 foreach ($elements as $id => $element) {
166 $template->setCurrentBlock("element");
167 $template->setVariable("ELEMENT_ID", "sol_e_" . $this->object->getId() . "_$id");
168 $template->setVariable("ELEMENT_VALUE", ilUtil::prepareFormOutput($element));
169 $template->parseCurrentBlock();
170 }
171 }
172
173 if (($active_id > 0) && (!$show_correct_solution)) {
174 if ($this->object->getStep() === null) {
175 $reached_points = $this->object->getReachedPoints($active_id, $pass);
176 } else {
177 $reached_points = $this->object->calculateReachedPoints($active_id, $pass);
178 }
179 if ($graphicalOutput) {
180 // output of ok/not ok icons for user entered solutions
181 if ($reached_points == $this->object->getMaximumPoints()) {
182 $template->setCurrentBlock("icon_ok");
183 $template->setVariable("ICON_OK", ilUtil::getImagePath("icon_ok.svg"));
184 $template->setVariable("TEXT_OK", $this->lng->txt("answer_is_right"));
185 $template->parseCurrentBlock();
186 } else {
187 $template->setCurrentBlock("icon_ok");
188 if ($reached_points > 0) {
189 $template->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_mostly_ok.svg"));
190 $template->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_not_correct_but_positive"));
191 } else {
192 $template->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_not_ok.svg"));
193 $template->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_wrong"));
194 }
195 $template->parseCurrentBlock();
196 }
197 }
198 } else {
199 $reached_points = $this->object->getPoints();
200 }
201
202 if ($result_output) {
203 $resulttext = ($reached_points == 1) ? "(%s " . $this->lng->txt("point") . ")" : "(%s " . $this->lng->txt("points") . ")";
204 $template->setVariable("RESULT_OUTPUT", sprintf($resulttext, $reached_points));
205 }
206 if ($show_question_text == true) {
207 $template->setVariable("QUESTIONTEXT", $this->object->getQuestionForHTMLOutput());
208 }
209 // $template->setVariable("SOLUTION_TEXT", ilUtil::prepareFormOutput($solutionvalue));
210 if ($this->object->textsize >= 10) {
211 $template->setVariable("STYLE", " style=\"font-size: " . $this->object->textsize . "%;\"");
212 }
213
214 $questionoutput = $template->get();
215 $solutiontemplate = new ilTemplate("tpl.il_as_tst_solution_output.html", true, true, "Modules/TestQuestionPool");
216 $solutiontemplate->setVariable("SOLUTION_OUTPUT", $questionoutput);
217
218
219 $feedback = '';
220 if ($show_feedback) {
221 if (!$this->isTestPresentationContext()) {
222 $fb = $this->getGenericFeedbackOutput($active_id, $pass);
223 $feedback .= strlen($fb) ? $fb : '';
224 }
225
226 $fb = $this->getSpecificFeedbackOutput(array());
227 $feedback .= strlen($fb) ? $fb : '';
228 }
229 if (strlen($feedback)) {
230 $cssClass = (
231 $this->hasCorrectSolution($active_id, $pass) ?
233 );
234
235 $solutiontemplate->setVariable("ILC_FB_CSS_CLASS", $cssClass);
236 $solutiontemplate->setVariable("FEEDBACK", $this->object->prepareTextareaOutput($feedback, true));
237 }
238 $solutionoutput = $solutiontemplate->get();
239 if (!$show_question_only) {
240 // get page object output
241 $solutionoutput = $this->getILIASPage($solutionoutput);
242 }
243 return $solutionoutput;
244 }
245
246 public function getPreview($show_question_only = false, $showInlineFeedback = false)
247 {
248 if (is_object($this->getPreviewSession()) && strlen((string) $this->getPreviewSession()->getParticipantsSolution())) {
249 $elements = (string) $this->getPreviewSession()->getParticipantsSolution();
250 $elements = $this->object->splitAndTrimOrderElementText($elements, $this->object->getAnswerSeparator());
251 } else {
252 $elements = $this->object->getRandomOrderingElements();
253 }
254
255 $template = new ilTemplate("tpl.il_as_qpl_orderinghorizontal_preview.html", true, true, "Modules/TestQuestionPool");
256 foreach ($elements as $id => $element) {
257 $template->setCurrentBlock("element");
258 $template->setVariable("ELEMENT_ID", "e_" . $this->object->getId() . "_$id");
259 $template->setVariable("ORDERING_VALUE", ilUtil::prepareFormOutput($element));
260 $template->setVariable("ELEMENT_VALUE", ilUtil::prepareFormOutput($element));
261 $template->parseCurrentBlock();
262 }
263 $template->setVariable("QUESTION_ID", $this->object->getId());
264 $template->setVariable("VALUE_ORDERRESULT", ' value="' . join('{::}', $elements) . '"');
265 if ($this->object->textsize >= 10) {
266 $template->setVariable("STYLE", " style=\"font-size: " . $this->object->textsize . "%;\"");
267 }
268 $template->setVariable("QUESTIONTEXT", $this->object->getQuestionForHTMLOutput());
269 $questionoutput = $template->get();
270 if (!$show_question_only) {
271 // get page object output
272 $questionoutput = $this->getILIASPage($questionoutput);
273 }
274 global $DIC; /* @var ILIAS\DI\Container $DIC */
275 if ($DIC['ilBrowser']->isMobile() || $DIC['ilBrowser']->isIpad()) {
276 require_once 'Services/jQuery/classes/class.iljQueryUtil.php';
279 $this->tpl->addJavaScript('./node_modules/@andxor/jquery-ui-touch-punch-fix/jquery.ui.touch-punch.js');
280 }
281 $this->tpl->addJavascript("./Modules/TestQuestionPool/templates/default/orderinghorizontal.js");
282 return $questionoutput;
283 }
284
285 // hey: prevPassSolutions - pass will be always available from now on
286 public function getTestOutput($active_id, $pass, $is_postponed = false, $use_post_solutions = false, $show_feedback = false)
287 // hey.
288 {
289 // generate the question output
290 $template = new ilTemplate("tpl.il_as_qpl_orderinghorizontal_output.html", true, true, "Modules/TestQuestionPool");
291 $elements = $this->object->getRandomOrderingElements();
292
293 if ($active_id) {
294 // hey: prevPassSolutions - obsolete due to central check
295 #$solutions = NULL;
296 #include_once "./Modules/Test/classes/class.ilObjTest.php";
297 #if (!ilObjTest::_getUsePreviousAnswers($active_id, true))
298 #{
299 # if (is_null($pass)) $pass = ilObjTest::_getPass($active_id);
300 #}
301 $solutions = $this->object->getTestOutputSolutions($active_id, $pass);
302 // hey.
303 if (is_array($solutions) && count($solutions) == 1) {
304 $elements = explode("{::}", $solutions[0]["value1"]);
305 }
306 }
307 if (!is_array($solutions) || count($solutions) == 0) {
308 $_SESSION['qst_ordering_horizontal_elements'] = $elements;
309 } else {
310 unset($_SESSION['qst_ordering_horizontal_elements']);
311 }
312 foreach ($elements as $id => $element) {
313 $template->setCurrentBlock("element");
314 $template->setVariable("ELEMENT_ID", "e_" . $this->object->getId() . "_$id");
315 $template->setVariable("ORDERING_VALUE", ilUtil::prepareFormOutput($element));
316 $template->setVariable("ELEMENT_VALUE", ilUtil::prepareFormOutput($element));
317 $template->parseCurrentBlock();
318 }
319 $template->setVariable("QUESTION_ID", $this->object->getId());
320 if ($this->object->textsize >= 10) {
321 $template->setVariable("STYLE", " style=\"font-size: " . $this->object->textsize . "%;\"");
322 }
323 $template->setVariable("VALUE_ORDERRESULT", ' value="' . join('{::}', $elements) . '"');
324 $template->setVariable("QUESTIONTEXT", $this->object->getQuestionForHTMLOutput());
325 $questionoutput = $template->get();
326 if (!$show_question_only) {
327 // get page object output
328 $questionoutput = $this->getILIASPage($questionoutput);
329 }
330 global $DIC; /* @var ILIAS\DI\Container $DIC */
331 if ($DIC['ilBrowser']->isMobile() || $DIC['ilBrowser']->isIpad()) {
332 require_once 'Services/jQuery/classes/class.iljQueryUtil.php';
335 $this->tpl->addJavaScript('./node_modules/@andxor/jquery-ui-touch-punch-fix/jquery.ui.touch-punch.js');
336 }
337 $this->tpl->addJavascript("./Modules/TestQuestionPool/templates/default/orderinghorizontal.js");
338 $questionoutput = $template->get();
339 $pageoutput = $this->outQuestionPage("", $is_postponed, $active_id, $questionoutput);
340 return $pageoutput;
341 }
342
348 public function saveFeedback()
349 {
350 include_once "./Services/AdvancedEditing/classes/class.ilObjAdvancedEditing.php";
351 $errors = $this->feedback(true);
352 $this->object->saveFeedbackGeneric(0, $_POST["feedback_incomplete"]);
353 $this->object->saveFeedbackGeneric(1, $_POST["feedback_complete"]);
354 $this->object->cleanupMediaObjectUsage();
355 parent::saveFeedback();
356 }
357
359 {
360 global $DIC; /* @var ILIAS\DI\Container $DIC */
361
362 $files = array();
363
364 if ($DIC['ilBrowser']->isMobile() || $DIC['ilBrowser']->isIpad()) {
365 $files[] = './node_modules/@andxor/jquery-ui-touch-punch-fix/jquery.ui.touch-punch.js';
366 }
367
368 return $files;
369 }
370
371 public function getSpecificFeedbackOutput($userSolution)
372 {
373 if (strpos($this->object->getOrderText(), '::')) {
374 $answers = explode('::', $this->object->getOrderText());
375 } else {
376 $answers = explode(' ', $this->object->getOrderText());
377 }
378
379 if (!$this->object->feedbackOBJ->specificAnswerFeedbackExists()) {
380 return '';
381 }
382
383 $output = '<table class="test_specific_feedback"><tbody>';
384
385 foreach ($answers as $idx => $answer) {
386 $feedback = $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation(
387 $this->object->getId(),
388 0,
389 $idx
390 );
391
392 $output .= "<tr><td>{$answer}</td><td>{$feedback}</td></tr>";
393 }
394
395 $output .= '</tbody></table>';
396
397 return $this->object->prepareTextareaOutput($output, true);
398 }
399
401 {
402 $this->object->setTextSize($_POST["textsize"]);
403 $this->object->setOrderText($_POST["ordertext"]);
404 $this->object->setPoints($_POST["points"]);
405 }
406
417 {
418 return array();
419 }
420
422 {
423 // ordertext
424 $ordertext = new ilTextAreaInputGUI($this->lng->txt("ordertext"), "ordertext");
425 $ordertext->setValue($this->object->prepareTextareaOutput($this->object->getOrderText()));
426 $ordertext->setRequired(true);
427 $ordertext->setInfo(sprintf($this->lng->txt("ordertext_info"), $this->object->separator));
428 $ordertext->setRows(10);
429 $ordertext->setCols(80);
430 $form->addItem($ordertext);
431 // textsize
432 $textsize = new ilNumberInputGUI($this->lng->txt("textsize"), "textsize");
433 $textsize->setValue($this->object->getTextSize());
434 $textsize->setInfo($this->lng->txt("textsize_info"));
435 $textsize->setSize(6);
436 $textsize->setMinValue(10);
437 $textsize->setRequired(false);
438 $form->addItem($textsize);
439 // points
440 $points = new ilNumberInputGUI($this->lng->txt("points"), "points");
441
442 $points->allowDecimals(true);
443 // mbecker: Fix for mantis bug 7866: Predefined values schould make sense.
444 // This implements a default value of "1" for this question type.
445 if ($this->object->getPoints() == null) {
446 $points->setValue("1");
447 } else {
448 $points->setValue($this->object->getPoints());
449 }
450 $points->setRequired(true);
451 $points->setSize(3);
452 $points->setMinValue(0.0);
453 $points->setMinvalueShouldBeGreater(true);
454 $form->addItem($points);
455 }
456
465 public function getAggregatedAnswersView($relevant_answers)
466 {
467 return $this->renderAggregateView(
468 $this->aggregateAnswers($relevant_answers, $this->object->getOrderText())
469 )->get();
470 }
471
472 public function aggregateAnswers($relevant_answers_chosen, $answer_defined_on_question)
473 {
474 $aggregate = array();
475 foreach ($relevant_answers_chosen as $answer) {
476 $answer = str_replace($this->object->getAnswerSeparator(), '&nbsp;&nbsp;-&nbsp;&nbsp;', $answer);
477 if (in_array($answer['value1'], $aggregate)) {
478 $aggregate[$answer['value1']] = $aggregate[$answer['value1']] + 1;
479 } else {
480 $aggregate[$answer['value1']] = 1;
481 }
482 }
483
484 return $aggregate;
485 }
486
492 public function renderAggregateView($aggregate)
493 {
494 $tpl = new ilTemplate('tpl.il_as_aggregated_answers_table.html', true, true, "Modules/TestQuestionPool");
495
496 foreach ($aggregate as $key => $line_data) {
497 $tpl->setCurrentBlock('aggregaterow');
498 $tpl->setVariable('COUNT', $line_data);
499 $tpl->setVariable('OPTION', $key);
500 $tpl->parseCurrentBlock();
501 }
502 return $tpl;
503 }
504
505 public function getAnswersFrequency($relevantAnswers, $questionIndex)
506 {
507 $answers = array();
508
509 foreach ($relevantAnswers as $ans) {
510 $md5 = md5($ans['value1']);
511
512 if (!isset($answers[$md5])) {
513 $answer = str_replace(
514 $this->object->getAnswerSeparator(),
515 '&nbsp;&nbsp;-&nbsp;&nbsp;',
516 $ans['value1']
517 );
518
519 $answers[$md5] = array(
520 'answer' => $answer, 'frequency' => 0
521 );
522 }
523
524 $answers[$md5]['frequency']++;
525 }
526
527 return $answers;
528 }
529
531 {
532 // points
533 $points = new ilNumberInputGUI($this->lng->txt("points"), "points");
534
535 $points->allowDecimals(true);
536 $points->setValue($this->object->getPoints());
537 $points->setRequired(true);
538 $points->setSize(3);
539 $points->setMinValue(0.0);
540 $points->setMinvalueShouldBeGreater(true);
541 $form->addItem($points);
542 }
543
548 {
549 $this->object->setPoints((float) $form->getInput('points'));
550 }
551}
$_POST["username"]
$_SESSION["AccountId"]
An exception for terminatinating execution or to throw for unit testing.
The assOrderingHorizontalGUI class encapsulates the GUI representation for horizontal ordering questi...
aggregateAnswers($relevant_answers_chosen, $answer_defined_on_question)
populateCorrectionsFormProperties(ilPropertyFormGUI $form)
getSolutionOutput( $active_id, $pass=null, $graphicalOutput=false, $result_output=false, $show_question_only=true, $show_feedback=false, $show_correct_solution=false, $show_manual_scoring=false, $show_question_text=true)
Get the question solution output.
getPreview($show_question_only=false, $showInlineFeedback=false)
saveCorrectionsFormProperties(ilPropertyFormGUI $form)
writePostData($always=false)
{Evaluates a posted edit form and writes the form data in the question object.integer A positive valu...
getAggregatedAnswersView($relevant_answers)
Returns an html string containing a question specific representation of the answers so far given in t...
getTestOutput($active_id, $pass, $is_postponed=false, $use_post_solutions=false, $show_feedback=false)
editQuestion($checkonly=false)
Creates an output of the edit form for the question.
writeQuestionSpecificPostData(ilPropertyFormGUI $form)
Extracts the question specific values from $_POST and applies them to the data object.
populateQuestionSpecificFormPart(\ilPropertyFormGUI $form)
getAnswersFrequency($relevantAnswers, $questionIndex)
saveFeedback()
Saves the feedback for a single choice question.
__construct($id=-1)
assOrderingHorizontalGUI constructor
getSpecificFeedbackOutput($userSolution)
Returns the answer specific feedback for the question.
supportsIntermediateSolutionOutput()
Question type specific support of intermediate solution output The function getSolutionOutput respect...
getAfterParticipationSuppressionQuestionPostVars()
Returns a list of postvars which will be suppressed in the form output when used in scoring adjustmen...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Basic GUI class for assessment questions.
populateTaxonomyFormSection(ilPropertyFormGUI $form)
setErrorMessage($errormessage)
addQuestionFormCommandButtons($form)
Add the command buttons of a question properties form.
getILIASPage($html="")
Returns the ILIAS Page around a question.
getQuestionTemplate()
get question template
outQuestionPage($a_temp_var, $a_postponed=false, $active_id="", $html="", $inlineFeedbackEnabled=false)
output question page
getUseIntermediateSolution()
Get if intermediate solution should be used for solution output.
hasCorrectSolution($activeId, $passIndex)
addBasicQuestionFormProperties($form)
Add basic question form properties: assessment: title, author, description, question,...
getGenericFeedbackOutput($active_id, $pass)
Returns the answer specific feedback for the question.
This class represents a number property in a property form.
This class represents a property form user interface.
addItem($a_item)
Add Item (Property, SectionHeader).
getInput($a_post_var, $ensureValidation=true)
Returns the value of a HTTP-POST variable, identified by the passed id.
special template class to simplify handling of ITX/PEAR
This class represents a text area property in a property form.
static getImagePath($img, $module_path="", $mode="output", $offline=false)
get image path (for images located in a template directory)
static prepareFormOutput($a_str, $a_strip=false)
prepares string output for html forms @access public
static initjQuery(ilGlobalTemplateInterface $a_tpl=null)
inits and adds the jQuery JS-File to the global or a passed template
static initjQueryUI($a_tpl=null)
inits and adds the jQuery-UI JS-File to the global template (see included_components....
global $DIC
Definition: goto.php:24
$errors
Definition: imgupload.php:49
Interface ilGuiQuestionScoringAdjustable.
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc