ILIAS  trunk Revision v11.0_alpha-2638-g80c1d007f79
class.SurveyMultipleChoiceQuestionGUI.php
Go to the documentation of this file.
1 <?php
2 
26 {
27  protected function initObject(): void
28  {
29  $this->object = new SurveyMultipleChoiceQuestion();
30  }
31 
32  //
33  // EDITOR
34  //
35 
36  public function setQuestionTabs(): void
37  {
38  $this->setQuestionTabsForClass("surveymultiplechoicequestiongui");
39  }
40 
41  protected function addFieldsToEditForm(ilPropertyFormGUI $a_form): void
42  {
43  // orientation
44  $orientation = new ilRadioGroupInputGUI($this->lng->txt("orientation"), "orientation");
45  $orientation->setRequired(false);
46  $orientation->addOption(new ilRadioOption($this->lng->txt('vertical'), 0));
47  $orientation->addOption(new ilRadioOption($this->lng->txt('horizontal'), 1));
48  $a_form->addItem($orientation);
49 
50  // minimum answers
51  $minanswers = new ilCheckboxInputGUI($this->lng->txt("use_min_answers"), "use_min_answers");
52  $minanswers->setValue(1);
53  $minanswers->setOptionTitle($this->lng->txt("use_min_answers_option"));
54  $minanswers->setRequired(false);
55 
56  $nranswers = new ilNumberInputGUI($this->lng->txt("nr_min_answers"), "nr_min_answers");
57  $nranswers->setSize(5);
58  $nranswers->setDecimals(0);
59  $nranswers->setRequired(false);
60  $nranswers->setMinValue(1);
61  $minanswers->addSubItem($nranswers);
62 
63  $nrmaxanswers = new ilNumberInputGUI($this->lng->txt("nr_max_answers"), "nr_max_answers");
64  $nrmaxanswers->setSize(5);
65  $nrmaxanswers->setDecimals(0);
66  $nrmaxanswers->setRequired(false);
67  $nrmaxanswers->setMinValue(1);
68  $minanswers->addSubItem($nrmaxanswers);
69 
70  $a_form->addItem($minanswers);
71 
72  // Answers
73  $answers = new ilCategoryWizardInputGUI($this->lng->txt("answers"), "answers");
74  $answers->setRequired(false);
75  $answers->setAllowMove(true);
76  $answers->setShowWizard(false);
77  $answers->setUseOtherAnswer(true);
78  $answers->setShowNeutralCategory(true);
79  $answers->setNeutralCategoryTitle($this->lng->txt('svy_neutral_answer'));
80  $answers->setDisabledScale(false);
81  $a_form->addItem($answers);
82 
83 
84  // values
85  $orientation->setValue($this->object->getOrientation());
86  $minanswers->setChecked((bool) $this->object->use_min_answers);
87  $nranswers->setValue($this->object->nr_min_answers);
88  $nrmaxanswers->setValue($this->object->nr_max_answers);
89  if (!$this->object->getCategories()->getCategoryCount()) {
90  $this->object->getCategories()->addCategory("");
91  }
92  $answers->setValues($this->object->getCategories());
93  }
94 
95  protected function validateEditForm(ilPropertyFormGUI $a_form): bool
96  {
97  $errors = false;
98  if ($a_form->getInput("use_min_answers")) {
99  // #13927 - see importEditFormValues()
100  $cnt_answers = 0;
101  $answers = $this->request->getAnswers();
102  foreach ($answers['answer'] as $key => $value) {
103  if (strlen($value ?? "")) {
104  $cnt_answers++;
105  }
106  }
107  if ($this->request->getNeutral() !== "") {
108  $cnt_answers++;
109  }
110  /* this would be the DB-values
111  $cnt_answers = $a_form->getItemByPostVar("answers");
112  $cnt_answers = $cnt_answers->getCategoryCount();
113  */
114  $min_anwers = $a_form->getInput("nr_min_answers");
115  $max_anwers = $a_form->getInput("nr_max_answers");
116 
117  if ($min_anwers &&
118  $min_anwers > $cnt_answers) {
119  $a_form->getItemByPostVar("nr_min_answers")->setAlert($this->lng->txt('err_minvalueganswers'));
120  $errors = true;
121  }
122  if ($max_anwers > 0 &&
123  ($max_anwers > $cnt_answers || $max_anwers < $min_anwers)) {
124  $a_form->getItemByPostVar("nr_max_answers")->setAlert($this->lng->txt('err_maxvaluegeminvalue'));
125  $errors = true;
126  }
127  }
128 
129  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('form_input_not_valid'));
130  return !$errors;
131  }
132 
133  protected function importEditFormValues(ilPropertyFormGUI $a_form): void
134  {
135  $this->object->setOrientation($a_form->getInput("orientation"));
136  $this->object->use_other_answer = ($a_form->getInput('use_other_answer')) ? 1 : 0;
137  $this->object->other_answer_label = $this->object->use_other_answer ? $a_form->getInput('other_answer_label') : "";
138  $this->object->use_min_answers = (bool) $a_form->getInput('use_min_answers');
139  $this->object->nr_min_answers = ($a_form->getInput('nr_min_answers') > 0) ? $a_form->getInput('nr_min_answers') : "";
140  $this->object->nr_max_answers = ($a_form->getInput('nr_max_answers') > 0) ? $a_form->getInput('nr_max_answers') : "";
141  $this->object->label = $a_form->getInput('label');
142 
143  $this->object->categories->flushCategories();
144 
145  $answers = $this->request->getAnswers();
146  foreach ($answers['answer'] as $key => $value) {
147  if (strlen($value ?? "")) {
148  $this->object->getCategories()->addCategory($value, $answers['other'][$key] ?? 0, 0, null, $answers['scale'][$key]);
149  }
150  }
151  if ($this->request->getNeutral() !== "") {
152  $this->object->getCategories()->addCategory($this->request->getNeutral(), 0, 1, null, $this->request->getNeutralScale());
153  }
154  }
155 
156  public function getParsedAnswers(
157  ?array $a_working_data = null,
158  $a_only_user_anwers = false
159  ): array {
160  if (is_array($a_working_data)) {
161  $user_answers = $a_working_data;
162  }
163 
164  $options = array();
165  for ($i = 0; $i < $this->object->categories->getCategoryCount(); $i++) {
166  $cat = $this->object->categories->getCategory($i);
167  $value = ($cat->scale) ? ($cat->scale - 1) : $i;
168 
169  $checked = "unchecked";
170  $text = null;
171  if (is_array($a_working_data)) {
172  foreach ($user_answers as $user_answer) {
173  if ($value == $user_answer["value"]) {
174  $checked = "checked";
175  if ($user_answer["textanswer"]) {
176  $text = $user_answer["textanswer"];
177  }
178  break;
179  }
180  }
181  }
182 
183  // "other" options have to be last or horizontal will be screwed
184  $idx = $cat->other . "_" . $value;
185 
186  if (!$a_only_user_anwers || $checked === "checked") {
187  $options[$idx] = array(
188  "value" => $value
189  ,"title" => trim($cat->title)
190  ,"other" => (bool) $cat->other
191  ,"checked" => $checked
192  ,"textanswer" => $text
193  );
194  }
195 
196  ksort($options);
197  }
198 
199  return array_values($options);
200  }
201 
202  public function getPrintView(
203  int $question_title = 1,
204  bool $show_questiontext = true,
205  ?int $survey_id = null,
206  ?array $working_data = null
207  ): string {
208  $options = $this->getParsedAnswers($working_data);
209 
210  $template = new ilTemplate("tpl.il_svy_qpl_mc_printview.html", true, true, "components/ILIAS/SurveyQuestionPool");
211  switch ($this->object->getOrientation()) {
212  case 0:
213  // vertical orientation
214  foreach ($options as $option) {
215  if ($option["other"]) {
216  $template->setCurrentBlock("other_row");
217  $template->setVariable("IMAGE_CHECKBOX", ilUtil::getHtmlPath(ilUtil::getImagePath("object/checkbox_" . $option["checked"] . ".png")));
218  $template->setVariable("ALT_CHECKBOX", $this->lng->txt($option["checked"]));
219  $template->setVariable("TITLE_CHECKBOX", $this->lng->txt($option["checked"]));
220  $template->setVariable(
221  "OTHER_LABEL",
223  );
224  $template->setVariable("OTHER_ANSWER", $option["textanswer"]
225  ? ilLegacyFormElementsUtil::prepareFormOutput($option["textanswer"])
226  : "&nbsp;");
227  } else {
228  $template->setCurrentBlock("mc_row");
229  $template->setVariable("IMAGE_CHECKBOX", ilUtil::getHtmlPath(ilUtil::getImagePath("object/checkbox_" . $option["checked"] . ".png")));
230  $template->setVariable("ALT_CHECKBOX", $this->lng->txt($option["checked"]));
231  $template->setVariable("TITLE_CHECKBOX", $this->lng->txt($option["checked"]));
232  $template->setVariable("TEXT_MC", ilLegacyFormElementsUtil::prepareFormOutput($option["title"]));
233  }
234  $template->parseCurrentBlock();
235  }
236  break;
237  case 1:
238  // horizontal orientation
239  foreach ($options as $option) {
240  $template->setCurrentBlock("checkbox_col");
241  $template->setVariable("IMAGE_CHECKBOX", ilUtil::getHtmlPath(ilUtil::getImagePath("object/checkbox_" . $option["checked"] . ".png")));
242  $template->setVariable("ALT_CHECKBOX", $this->lng->txt($option["checked"]));
243  $template->setVariable("TITLE_CHECKBOX", $this->lng->txt($option["checked"]));
244  $template->parseCurrentBlock();
245  }
246  foreach ($options as $option) {
247  if ($option["other"]) {
248  $template->setCurrentBlock("other_text_col");
249  $template->setVariable(
250  "OTHER_LABEL",
252  );
253  $template->setVariable("OTHER_ANSWER", $option["textanswer"]
254  ? ilLegacyFormElementsUtil::prepareFormOutput($option["textanswer"])
255  : "&nbsp;");
256  } else {
257  $template->setCurrentBlock("text_col");
258  $template->setVariable("TEXT_MC", ilLegacyFormElementsUtil::prepareFormOutput($option["title"]));
259  }
260  $template->parseCurrentBlock();
261  }
262  break;
263  }
264 
265  if ($this->object->use_min_answers) {
266  $template->setCurrentBlock('min_max_msg');
267  if ($this->object->nr_min_answers > 0 && $this->object->nr_max_answers > 0) {
268  $template->setVariable('MIN_MAX_MSG', sprintf($this->lng->txt('msg_min_max_nr_answers'), $this->object->nr_min_answers, $this->object->nr_max_answers));
269  } elseif ($this->object->nr_min_answers > 0) {
270  $template->setVariable('MIN_MAX_MSG', sprintf($this->lng->txt('msg_min_nr_answers'), $this->object->nr_min_answers));
271  } elseif ($this->object->nr_max_answers > 0) {
272  $template->setVariable('MIN_MAX_MSG', sprintf($this->lng->txt('msg_max_nr_answers'), $this->object->nr_max_answers));
273  }
274  $template->parseCurrentBlock();
275  }
276  if ($show_questiontext) {
277  $this->outQuestionText($template);
278  }
279  if ($question_title) {
280  $template->setVariable("QUESTION_TITLE", $this->getPrintViewQuestionTitle($question_title));
281  }
282  $template->parseCurrentBlock();
283  return $template->get();
284  }
285 
286 
287  //
288  // EXECUTION
289  //
290 
294  public function getWorkingForm(
295  ?array $working_data = null,
296  int $question_title = 1,
297  bool $show_questiontext = true,
298  string $error_message = "",
299  ?int $survey_id = null,
300  bool $compress_view = false
301  ): string {
302  $template = new ilTemplate("tpl.il_svy_out_mc.html", true, true, "components/ILIAS/SurveyQuestionPool");
303  switch ($this->object->getOrientation()) {
304  case 0:
305  // vertical orientation
306  for ($i = 0; $i < $this->object->categories->getCategoryCount(); $i++) {
307  $cat = $this->object->categories->getCategory($i);
308  if ($cat->other) {
309  $template->setCurrentBlock("other_row");
310  if (strlen($cat->title ?? "")) {
311  $template->setVariable("OTHER_LABEL", $cat->title);
312  }
313  $template->setVariable("VALUE_MC", ($cat->scale) ? ($cat->scale - 1) : $i);
314  $template->setVariable("QUESTION_ID", $this->object->getId());
315  if (is_array($working_data)) {
316  foreach ($working_data as $value) {
317  if (strlen($value["value"] ?? "")) {
318  if ($value["value"] == $cat->scale - 1) {
319  $template->setVariable("OTHER_VALUE", ' value="' . ilLegacyFormElementsUtil::prepareFormOutput(
320  $value['textanswer']
321  ) . '"');
322  if (!($value['uncheck'] ?? false)) {
323  $template->setVariable("CHECKED_MC", " checked=\"checked\"");
324  }
325  }
326  }
327  }
328  }
329  } else {
330  $template->setCurrentBlock("mc_row");
331  if ($cat->neutral) {
332  $template->setVariable('ROWCLASS', ' class="neutral"');
333  }
334  $template->setVariable("TEXT_MC", ilLegacyFormElementsUtil::prepareFormOutput($cat->title));
335  $template->setVariable("VALUE_MC", ($cat->scale) ? ($cat->scale - 1) : $i);
336  $template->setVariable("QUESTION_ID", $this->object->getId());
337  if (is_array($working_data)) {
338  foreach ($working_data as $value) {
339  if (strlen($value["value"] ?? "")) {
340  if ($value["value"] == $cat->scale - 1) {
341  if (!($value['uncheck'] ?? false)) {
342  $template->setVariable("CHECKED_MC", " checked=\"checked\"");
343  }
344  }
345  }
346  }
347  }
348  }
349  $template->parseCurrentBlock();
350  $template->touchBlock('outer_row');
351  }
352  break;
353  case 1:
354  // horizontal orientation
355 
356  // #15477 - reverting the categorizing of answers
357  for ($i = 0; $i < $this->object->categories->getCategoryCount(); $i++) {
358  $cat = $this->object->categories->getCategory($i);
359 
360  // checkbox
361  $template->setCurrentBlock("checkbox_col");
362  if ($cat->neutral) {
363  $template->setVariable('COLCLASS', ' neutral');
364  }
365  $template->setVariable("VALUE_MC", ($cat->scale) ? ($cat->scale - 1) : $i);
366  $template->setVariable("QUESTION_ID", $this->object->getId());
367  if (is_array($working_data)) {
368  foreach ($working_data as $value) {
369  if (strlen($value["value"] ?? "")) {
370  if ($value["value"] == $cat->scale - 1) {
371  if (!($value['uncheck'] ?? false)) {
372  $template->setVariable("CHECKED_MC", " checked=\"checked\"");
373  }
374  }
375  }
376  }
377  }
378  $template->parseCurrentBlock();
379 
380  // answer & input
381  if ($cat->other) {
382  $template->setCurrentBlock("text_other_col");
383  $template->setVariable("VALUE_MC", ($cat->scale) ? ($cat->scale - 1) : $i);
384  $template->setVariable("QUESTION_ID", $this->object->getId());
385  if (strlen($cat->title ?? "")) {
386  $template->setVariable("OTHER_LABEL", $cat->title);
387  }
388  if (is_array($working_data)) {
389  foreach ($working_data as $value) {
390  if (strlen($value["value"] ?? "")) {
391  if ($value["value"] == $cat->scale - 1) {
392  $template->setVariable("OTHER_VALUE", ' value="' . ilLegacyFormElementsUtil::prepareFormOutput(
393  $value['textanswer']
394  ) . '"');
395  }
396  }
397  }
398  }
399  }
400  // answer
401  else {
402  $template->setCurrentBlock("text_col");
403  if ($cat->neutral) {
404  $template->setVariable('COLCLASS', ' neutral');
405  }
406  $template->setVariable("VALUE_MC", ($cat->scale) ? ($cat->scale - 1) : $i);
407  $template->setVariable("TEXT_MC", ilLegacyFormElementsUtil::prepareFormOutput($cat->title));
408  $template->setVariable("QUESTION_ID", $this->object->getId());
409  }
410  $template->parseCurrentBlock();
411  $template->touchBlock('text_outer_col');
412  }
413  break;
414  }
415 
416  $template->setCurrentBlock("question_data");
417  if ($this->object->use_min_answers) {
418  $template->setCurrentBlock('min_max_msg');
419  if ($this->object->nr_min_answers > 0 && $this->object->nr_max_answers > 0) {
420  if ($this->object->nr_min_answers == $this->object->nr_max_answers) {
421  $template->setVariable('MIN_MAX_MSG', sprintf($this->lng->txt('msg_min_max_exact_answers'), $this->object->nr_min_answers));
422  } else {
423  $template->setVariable('MIN_MAX_MSG', sprintf($this->lng->txt('msg_min_max_nr_answers'), $this->object->nr_min_answers, $this->object->nr_max_answers));
424  }
425  } elseif ($this->object->nr_min_answers > 0) {
426  $template->setVariable('MIN_MAX_MSG', sprintf($this->lng->txt('msg_min_nr_answers'), $this->object->nr_min_answers));
427  } elseif ($this->object->nr_max_answers > 0) {
428  $template->setVariable('MIN_MAX_MSG', sprintf($this->lng->txt('msg_max_nr_answers'), $this->object->nr_max_answers));
429  }
430  $template->parseCurrentBlock();
431  }
432  if (strcmp($error_message, "") !== 0) {
433  $template->setVariable("ERROR_MESSAGE", "<p class=\"warning\">$error_message</p>");
434  }
435  if ($show_questiontext) {
436  $this->outQuestionText($template);
437  }
438  $template->setVariable("QUESTION_TITLE", $this->getQuestionTitle($question_title));
439  $template->parseCurrentBlock();
440  return $template->get();
441  }
442 }
This class represents an option in a radio group.
getQuestionTitle(int $question_title_mode=1)
getItemByPostVar(string $a_post_var)
getPrintViewQuestionTitle(int $question_title=1)
getPrintView(int $question_title=1, bool $show_questiontext=true, ?int $survey_id=null, ?array $working_data=null)
static prepareFormOutput($a_str, bool $a_strip=false)
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-...
outQuestionText(ilTemplate $template)
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
This class represents a property in a property form.
setQuestionTabsForClass(string $guiclass)
This class represents a number property in a property form.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static getImagePath(string $image_name, string $module_path="", string $mode="output", bool $offline=false)
get image path (for images located in a template directory)
static getHtmlPath(string $relative_path)
get url of path
setRequired(bool $a_required)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Basic class for all survey question types The SurveyQuestionGUI class defines and encapsulates basic ...
getWorkingForm(?array $working_data=null, int $question_title=1, bool $show_questiontext=true, string $error_message="", ?int $survey_id=null, bool $compress_view=false)
Creates the question output form for the learner.
getParsedAnswers(?array $a_working_data=null, $a_only_user_anwers=false)