ILIAS  release_8 Revision v8.19
All Data Structures Namespaces Files Functions Variables Modules Pages
class.assOrderingHorizontalGUI.php
Go to the documentation of this file.
1 <?php
18 require_once './Modules/Test/classes/inc.AssessmentConstants.php';
19 
35 {
44  public function __construct($id = -1)
45  {
47  include_once "./Modules/TestQuestionPool/classes/class.assOrderingHorizontal.php";
48  $this->object = new assOrderingHorizontal();
49  $this->setErrorMessage($this->lng->txt("msg_form_save_error"));
50  if ($id >= 0) {
51  $this->object->loadFromDb($id);
52  }
53  }
54 
55  public function getCommand($cmd)
56  {
57  return $cmd;
58  }
59 
63  protected function writePostData(bool $always = false): int
64  {
65  $hasErrors = (!$always) ? $this->editQuestion(true) : false;
66  if (!$hasErrors) {
67  require_once 'Services/Form/classes/class.ilPropertyFormGUI.php';
70  $this->saveTaxonomyAssignments();
71  return 0;
72  }
73  return 1;
74  }
75 
81  public function editQuestion($checkonly = false): bool
82  {
83  $save = $this->isSaveCommand();
84  $this->getQuestionTemplate();
85 
86  include_once("./Services/Form/classes/class.ilPropertyFormGUI.php");
87  $form = new ilPropertyFormGUI();
88  $this->editForm = $form;
89 
90  $form->setFormAction($this->ctrl->getFormAction($this));
91  $form->setTitle($this->outQuestionType());
92  $form->setMultipart(false);
93  $form->setTableWidth("100%");
94  $form->setId("orderinghorizontal");
95 
96  $this->addBasicQuestionFormProperties($form);
98 
99 
100  $this->populateTaxonomyFormSection($form);
101 
102  $this->addQuestionFormCommandButtons($form);
103 
104  $errors = false;
105 
106  if ($save) {
107  $form->setValuesByPost();
108  $errors = !$form->checkInput();
109  $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
110  if ($errors) {
111  $checkonly = false;
112  }
113  }
114 
115  if (!$checkonly) {
116  $this->tpl->setVariable("QUESTION_DATA", $form->getHTML());
117  }
118  return $errors;
119  }
120 
133  public function getSolutionOutput(
134  $active_id,
135  $pass = null,
136  $graphicalOutput = false,
137  $result_output = false,
138  $show_question_only = true,
139  $show_feedback = false,
140  $show_correct_solution = false,
141  $show_manual_scoring = false,
142  $show_question_text = true
143  ): string {
144  // get the solution of the user for the active pass or from the last pass if allowed
145  $template = new ilTemplate("tpl.il_as_qpl_orderinghorizontal_output_solution.html", true, true, "Modules/TestQuestionPool");
146 
147  if (($active_id > 0) && (!$show_correct_solution)) {
148  $elements = [];
149  $solutions = $this->object->getSolutionValues($active_id, $pass);
150 
151  if (count($solutions) && strlen($solutions[0]["value1"])) {
152  $elements = explode("{::}", $solutions[0]["value1"]);
153  }
154 
155  if (!count($elements)) {
156  $elements = $this->object->getRandomOrderingElements();
157  }
158 
159  foreach ($elements as $id => $element) {
160  $template->setCurrentBlock("element");
161  $template->setVariable("ELEMENT_ID", "sol_e_" . $this->object->getId() . "_$id");
162  $template->setVariable("ELEMENT_VALUE", ilLegacyFormElementsUtil::prepareFormOutput($element));
163  $template->parseCurrentBlock();
164  }
165  } else {
166  $elements = $this->object->getOrderingElements();
167  foreach ($elements as $id => $element) {
168  $template->setCurrentBlock("element");
169  $template->setVariable("ELEMENT_ID", "sol_e_" . $this->object->getId() . "_$id");
170  $template->setVariable("ELEMENT_VALUE", ilLegacyFormElementsUtil::prepareFormOutput($element));
171  $template->parseCurrentBlock();
172  }
173  }
174 
175  if (($active_id > 0) && (!$show_correct_solution)) {
176  if ($this->object->getStep() === null) {
177  $reached_points = $this->object->getReachedPoints($active_id, $pass);
178  } else {
179  $reached_points = $this->object->calculateReachedPoints($active_id, $pass);
180  }
181  if ($graphicalOutput) {
182  $correctness_icon = $this->generateCorrectnessIconsForCorrectness(self::CORRECTNESS_NOT_OK);
183  if ($reached_points == $this->object->getMaximumPoints()) {
184  $correctness_icon = $this->generateCorrectnessIconsForCorrectness(self::CORRECTNESS_OK);
185  } elseif ($reached_points > 0) {
186  $correctness_icon = $this->generateCorrectnessIconsForCorrectness(self::CORRECTNESS_MOSTLY_OK);
187  }
188  $template->setCurrentBlock("icon_ok");
189  $template->setVariable("ICON_OK", $correctness_icon);
190  $template->parseCurrentBlock();
191  }
192  } else {
193  $reached_points = $this->object->getPoints();
194  }
195 
196  if ($result_output) {
197  $resulttext = ($reached_points == 1) ? "(%s " . $this->lng->txt("point") . ")" : "(%s " . $this->lng->txt("points") . ")";
198  $template->setVariable("RESULT_OUTPUT", sprintf($resulttext, $reached_points));
199  }
200  if ($show_question_text == true) {
201  $template->setVariable("QUESTIONTEXT", $this->object->getQuestionForHTMLOutput());
202  }
203  // $template->setVariable("SOLUTION_TEXT", ilUtil::prepareFormOutput($solutionvalue));
204  if ($this->object->getTextSize() >= 10) {
205  $template->setVariable("STYLE", " style=\"font-size: " . $this->object->getTextSize() . "%;\"");
206  }
207 
208  $questionoutput = $template->get();
209  $solutiontemplate = new ilTemplate("tpl.il_as_tst_solution_output.html", true, true, "Modules/TestQuestionPool");
210  $solutiontemplate->setVariable("SOLUTION_OUTPUT", $questionoutput);
211 
212 
213  $feedback = '';
214  if ($show_feedback) {
215  if (!$this->isTestPresentationContext()) {
216  $fb = $this->getGenericFeedbackOutput((int) $active_id, $pass);
217  $feedback .= strlen($fb) ? $fb : '';
218  }
219  }
220  if (strlen($feedback)) {
221  $cssClass = (
222  $this->hasCorrectSolution($active_id, $pass) ?
224  );
225 
226  $solutiontemplate->setVariable("ILC_FB_CSS_CLASS", $cssClass);
227  $solutiontemplate->setVariable("FEEDBACK", $this->object->prepareTextareaOutput($feedback, true));
228  }
229  $solutionoutput = $solutiontemplate->get();
230  if (!$show_question_only) {
231  // get page object output
232  $solutionoutput = $this->getILIASPage($solutionoutput);
233  }
234  return $solutionoutput;
235  }
236 
237 
238  public function getPreview($show_question_only = false, $showInlineFeedback = false): string
239  {
240  if (is_object($this->getPreviewSession()) && strlen((string) $this->getPreviewSession()->getParticipantsSolution())) {
241  $elements = (string) $this->getPreviewSession()->getParticipantsSolution();
242  $elements = $this->object->splitAndTrimOrderElementText($elements, $this->object->getAnswerSeparator());
243  } else {
244  $elements = $this->object->getRandomOrderingElements();
245  }
246 
247  $template = new ilTemplate("tpl.il_as_qpl_orderinghorizontal_preview.html", true, true, "Modules/TestQuestionPool");
248  $js = <<<JS
249 
250  $('#horizontal_{QUESTION_ID}').ilHorizontalOrderingQuestion({
251  result_value_selector : '.ilOrderingValue',
252  result_separator : '{::}'
253  });
254 
255 JS;
256  $js = str_replace('{QUESTION_ID}', $this->object->getId(), $js);
257  $this->tpl->addOnLoadCode($js);
258 
259  foreach ($elements as $id => $element) {
260  $template->setCurrentBlock("element");
261  $template->setVariable("ELEMENT_ID", "e_" . $this->object->getId() . "_$id");
262  $template->setVariable("ORDERING_VALUE", ilLegacyFormElementsUtil::prepareFormOutput($element));
263  $template->setVariable("ELEMENT_VALUE", ilLegacyFormElementsUtil::prepareFormOutput($element));
264  $template->parseCurrentBlock();
265  }
266  $template->setVariable("QUESTION_ID", $this->object->getId());
267  $template->setVariable("VALUE_ORDERRESULT", ' value="' . join('{::}', $elements) . '"');
268  if ($this->object->getTextSize() >= 10) {
269  $template->setVariable("STYLE", " style=\"font-size: " . $this->object->getTextSize() . "%;\"");
270  }
271  $template->setVariable("QUESTIONTEXT", $this->object->getQuestionForHTMLOutput());
272  $questionoutput = $template->get();
273  if (!$show_question_only) {
274  // get page object output
275  $questionoutput = $this->getILIASPage($questionoutput);
276  }
277  global $DIC; /* @var ILIAS\DI\Container $DIC */
278  if ($DIC->http()->agent()->isMobile() || $DIC->http()->agent()->isIpad()) {
279  require_once 'Services/jQuery/classes/class.iljQueryUtil.php';
282  $this->tpl->addJavaScript('./node_modules/@andxor/jquery-ui-touch-punch-fix/jquery.ui.touch-punch.js');
283  }
284  $this->tpl->addJavascript("./Modules/TestQuestionPool/templates/default/orderinghorizontal.js");
285  return $questionoutput;
286  }
287 
288  // hey: prevPassSolutions - pass will be always available from now on
289  public function getTestOutput($active_id, $pass, $is_postponed = false, $use_post_solutions = false, $show_feedback = false): string
290  // hey.
291  {
292  // generate the question output
293  $template = new ilTemplate("tpl.il_as_qpl_orderinghorizontal_output.html", true, true, "Modules/TestQuestionPool");
294  $js = <<<JS
295  $().ready(function() {
296  if (typeof $.fn.ilHorizontalOrderingQuestion != 'undefined') {
297  $('#horizontal_{QUESTION_ID}').ilHorizontalOrderingQuestion({
298  result_value_selector: '.ilOrderingValue',
299  result_separator: '{::}'
300  });
301  }
302  });
303 JS;
304  $js = str_replace('{QUESTION_ID}', $this->object->getId(), $js);
305  $this->tpl->addOnLoadCode($js);
306 
307 
308  $elements = $this->object->getRandomOrderingElements();
309 
310  if ($active_id) {
311  $solutions = $this->object->getTestOutputSolutions($active_id, $pass);
312  // hey.
313  if (is_array($solutions) && count($solutions) == 1) {
314  $elements = explode("{::}", $solutions[0]["value1"]);
315  }
316  }
317  if (!is_array($solutions) || count($solutions) == 0) {
318  ilSession::set('qst_ordering_horizontal_elements', $elements);
319  } else {
320  ilSession::clear('qst_ordering_horizontal_elements');
321  }
322  foreach ($elements as $id => $element) {
323  $template->setCurrentBlock("element");
324  $template->setVariable("ELEMENT_ID", "e_" . $this->object->getId() . "_$id");
325  $template->setVariable("ORDERING_VALUE", ilLegacyFormElementsUtil::prepareFormOutput($element));
326  $template->setVariable("ELEMENT_VALUE", ilLegacyFormElementsUtil::prepareFormOutput($element));
327  $template->parseCurrentBlock();
328  }
329  $template->setVariable("QUESTION_ID", $this->object->getId());
330  if ($this->object->getTextSize() >= 10) {
331  $template->setVariable("STYLE", " style=\"font-size: " . $this->object->getTextSize() . "%;\"");
332  }
333  $template->setVariable("VALUE_ORDERRESULT", ' value="' . join('{::}', $elements) . '"');
334  $template->setVariable("QUESTIONTEXT", $this->object->getQuestionForHTMLOutput());
335  $questionoutput = $template->get();
336  //if (!$show_question_only) {
337  // get page object output
338  $questionoutput = $this->getILIASPage($questionoutput);
339  //}
340  global $DIC; /* @var ILIAS\DI\Container $DIC */
341  if ($DIC->http()->agent()->isMobile() || $DIC->http()->agent()->isIpad()) {
342  require_once 'Services/jQuery/classes/class.iljQueryUtil.php';
345  $this->tpl->addJavaScript('./node_modules/@andxor/jquery-ui-touch-punch-fix/jquery.ui.touch-punch.js');
346  }
347  $this->tpl->addJavascript("./Modules/TestQuestionPool/templates/default/orderinghorizontal.js");
348  $questionoutput = $template->get();
349  $pageoutput = $this->outQuestionPage("", $is_postponed, $active_id, $questionoutput);
350  return $pageoutput;
351  }
352 
353  public function getPresentationJavascripts(): array
354  {
355  global $DIC; /* @var ILIAS\DI\Container $DIC */
356 
357  $files = array();
358 
359  if ($DIC->http()->agent()->isMobile() || $DIC->http()->agent()->isIpad()) {
360  $files[] = './node_modules/@andxor/jquery-ui-touch-punch-fix/jquery.ui.touch-punch.js';
361  }
362 
363  return $files;
364  }
365 
366  public function getSpecificFeedbackOutput(array $userSolution): string
367  {
368  return '';
369  }
370 
372  {
373  $this->object->setTextSize($_POST["textsize"]);
374  $this->object->setOrderText($_POST["ordertext"]);
375  $this->object->setPoints((float) str_replace(',', '.', $_POST["points"]));
376  }
377 
388  {
389  return array();
390  }
391 
393  {
394  // ordertext
395  $ordertext = new ilTextAreaInputGUI($this->lng->txt("ordertext"), "ordertext");
396  $ordertext->setValue((string) self::prepareTextareaOutput($this->object->getOrderText(), false, true));
397  $ordertext->setRequired(true);
398  $ordertext->setInfo(sprintf($this->lng->txt("ordertext_info"), $this->object->getSeparator()));
399  $ordertext->setRows(10);
400  $ordertext->setCols(80);
401  $form->addItem($ordertext);
402  // textsize
403  $textsize = new ilNumberInputGUI($this->lng->txt("textsize"), "textsize");
404  $textsize->setValue($this->object->getTextSize());
405  $textsize->setInfo($this->lng->txt("textsize_info"));
406  $textsize->setSize(6);
407  $textsize->setMinValue(10);
408  $textsize->setRequired(false);
409  $form->addItem($textsize);
410  // points
411  $points = new ilNumberInputGUI($this->lng->txt("points"), "points");
412 
413  $points->allowDecimals(true);
414  // mbecker: Fix for mantis bug 7866: Predefined values schould make sense.
415  // This implements a default value of "1" for this question type.
416  if ($this->object->getPoints() == null) {
417  $points->setValue("1");
418  } else {
419  $points->setValue($this->object->getPoints());
420  }
421  $points->setRequired(true);
422  $points->setSize(3);
423  $points->setMinValue(0.0);
424  $points->setMinvalueShouldBeGreater(true);
425  $form->addItem($points);
426  return $form;
427  }
428 
435  public function getAggregatedAnswersView(array $relevant_answers): string
436  {
437  return $this->renderAggregateView(
438  $this->aggregateAnswers($relevant_answers, $this->object->getOrderText())
439  )->get();
440  }
441 
442  public function aggregateAnswers($relevant_answers_chosen, $answer_defined_on_question): array
443  {
444  $aggregate = array();
445  foreach ($relevant_answers_chosen as $answer) {
446  $answer = str_replace($this->object->getAnswerSeparator(), '&nbsp;&nbsp;-&nbsp;&nbsp;', $answer);
447  if (in_array($answer['value1'], $aggregate)) {
448  $aggregate[$answer['value1']] = $aggregate[$answer['value1']] + 1;
449  } else {
450  $aggregate[$answer['value1']] = 1;
451  }
452  }
453 
454  return $aggregate;
455  }
456 
462  public function renderAggregateView($aggregate): ilTemplate
463  {
464  $tpl = new ilTemplate('tpl.il_as_aggregated_answers_table.html', true, true, "Modules/TestQuestionPool");
465 
466  foreach ($aggregate as $key => $line_data) {
467  $tpl->setCurrentBlock('aggregaterow');
468  $tpl->setVariable('COUNT', $line_data);
469  $tpl->setVariable('OPTION', $key);
471  }
472  return $tpl;
473  }
474 
475  public function getAnswersFrequency($relevantAnswers, $questionIndex): array
476  {
477  $answers = array();
478 
479  foreach ($relevantAnswers as $ans) {
480  $md5 = md5($ans['value1']);
481 
482  if (!isset($answers[$md5])) {
483  $answer = str_replace(
484  $this->object->getAnswerSeparator(),
485  '&nbsp;&nbsp;-&nbsp;&nbsp;',
486  $ans['value1']
487  );
488 
489  $answers[$md5] = array(
490  'answer' => $answer, 'frequency' => 0
491  );
492  }
493 
494  $answers[$md5]['frequency']++;
495  }
496 
497  return $answers;
498  }
499 
501  {
502  // points
503  $points = new ilNumberInputGUI($this->lng->txt("points"), "points");
504 
505  $points->allowDecimals(true);
506  $points->setValue($this->object->getPoints());
507  $points->setRequired(true);
508  $points->setSize(3);
509  $points->setMinValue(0.0);
510  $points->setMinvalueShouldBeGreater(true);
511  $form->addItem($points);
512  }
513 
518  {
519  $this->object->setPoints((float) str_replace(',', '.', $form->getInput('points')));
520  }
521 }
hasCorrectSolution($activeId, $passIndex)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
generateCorrectnessIconsForCorrectness(int $correctness)
getAggregatedAnswersView(array $relevant_answers)
Returns an html string containing a question specific representation of the answers so far given in t...
setCurrentBlock(string $blockname=self::DEFAULT_BLOCK)
Sets the template to the given block.
$errors
Definition: imgupload.php:65
saveCorrectionsFormProperties(ilPropertyFormGUI $form)
addBasicQuestionFormProperties(ilPropertyFormGUI $form)
parseCurrentBlock(string $blockname=self::DEFAULT_BLOCK)
Parses the given block.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
ilGlobalPageTemplate $tpl
static prepareFormOutput($a_str, bool $a_strip=false)
populateTaxonomyFormSection(ilPropertyFormGUI $form)
getInput(string $a_post_var, bool $ensureValidation=true)
Returns the input of an item, if item provides getInput method and as fallback the value of the HTTP-...
addQuestionFormCommandButtons(ilPropertyFormGUI $form)
populateQuestionSpecificFormPart(\ilPropertyFormGUI $form)
global $DIC
Definition: feed.php:28
allowDecimals(bool $a_value)
editQuestion($checkonly=false)
Creates an output of the edit form for the question.
setErrorMessage(string $errormessage)
This class represents a number property in a property form.
setValue(?string $a_value)
string $key
Consumer key/client ID value.
Definition: System.php:193
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.
static initjQueryUI(ilGlobalTemplateInterface $a_tpl=null)
inits and adds the jQuery-UI JS-File to the global template (see included_components.txt for included components)
aggregateAnswers($relevant_answers_chosen, $answer_defined_on_question)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
populateCorrectionsFormProperties(ilPropertyFormGUI $form)
writeQuestionSpecificPostData(ilPropertyFormGUI $form)
Extracts the question specific values from $_POST and applies them to the data object.
getILIASPage(string $html="")
Returns the ILIAS Page around a question.
__construct($id=-1)
assOrderingHorizontalGUI constructor
outQuestionPage($a_temp_var, $a_postponed=false, $active_id="", $html="", $inlineFeedbackEnabled=false)
static initjQuery(ilGlobalTemplateInterface $a_tpl=null)
inits and adds the jQuery JS-File to the global or a passed template
__construct(Container $dic, ilPlugin $plugin)
This class represents a text area property in a property form.
getPreview($show_question_only=false, $showInlineFeedback=false)
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
getAnswersFrequency($relevantAnswers, $questionIndex)
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...
static clear(string $a_var)
setVariable(string $variable, $value='')
Sets the given variable to the given value.
static set(string $a_var, $a_val)
Set a value.
getTestOutput($active_id, $pass, $is_postponed=false, $use_post_solutions=false, $show_feedback=false)
getGenericFeedbackOutput(int $active_id, ?int $pass)