ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
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 file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
getPrintView(int $question_title=1, bool $show_questiontext=true, ?int $survey_id=null, ?array $working_data=null)
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)
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 ...
setQuestionTabsForClass(string $guiclass)
return true
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This class represents a checkbox property in a property form.
static prepareFormOutput($a_str, bool $a_strip=false)
This class represents a number property in a property form.
This class represents a property form user interface.
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-...
getItemByPostVar(string $a_post_var)
This class represents a property in a property form.
This class represents an option in a radio group.
special template class to simplify handling of ITX/PEAR
setCurrentBlock(string $part=ilGlobalTemplateInterface::DEFAULT_BLOCK)
static getHtmlPath(string $relative_path)
get url of path
static getImagePath(string $image_name, string $module_path="", string $mode="output", bool $offline=false)
get image path (for images located in a template directory)
if(!file_exists('../ilias.ini.php'))