ILIAS  release_6 Revision v6.24-5-g0c8bfefb3b8
class.SurveyMultipleChoiceQuestion.php
Go to the documentation of this file.
1<?php
2
3/* Copyright (c) 1998-2019 ILIAS open source, Extended GPL, see docs/LICENSE */
4
14{
18 protected $db;
19
26
36 public function __construct($title = "", $description = "", $author = "", $questiontext = "", $owner = -1, $orientation = 0)
37 {
38 global $DIC;
39
40 $this->db = $DIC->database();
41 $this->lng = $DIC->language();
43
44 $this->orientation = $orientation;
45 $this->categories = new SurveyCategories();
46 }
47
55 public function getQuestionDataArray($id)
56 {
58
59 $result = $ilDB->queryF(
60 "SELECT svy_question.*, " . $this->getAdditionalTableName() . ".* FROM svy_question, " . $this->getAdditionalTableName() . " WHERE svy_question.question_id = %s AND svy_question.question_id = " . $this->getAdditionalTableName() . ".question_fi",
61 array('integer'),
62 array($id)
63 );
64 if ($result->numRows() == 1) {
65 return $ilDB->fetchAssoc($result);
66 } else {
67 return array();
68 }
69 }
70
77 public function loadFromDb($id)
78 {
80
81 $result = $ilDB->queryF(
82 "SELECT svy_question.*, " . $this->getAdditionalTableName() . ".* FROM svy_question LEFT JOIN " . $this->getAdditionalTableName() . " ON " . $this->getAdditionalTableName() . ".question_fi = svy_question.question_id WHERE svy_question.question_id = %s",
83 array('integer'),
84 array($id)
85 );
86 if ($result->numRows() == 1) {
87 $data = $ilDB->fetchAssoc($result);
88 $this->setId($data["question_id"]);
89 $this->setTitle($data["title"]);
90 $this->label = $data['label'];
91 $this->setDescription($data["description"]);
92 $this->setObjId($data["obj_fi"]);
93 $this->setAuthor($data["author"]);
94 $this->setOwner($data["owner_fi"]);
96 $this->setObligatory($data["obligatory"]);
97 $this->setComplete($data["complete"]);
98 $this->setOriginalId($data["original_id"]);
99 $this->setOrientation($data["orientation"]);
100 $this->use_min_answers = ($data['use_min_answers']) ? true : false;
101 $this->nr_min_answers = $data['nr_min_answers'];
102 $this->nr_max_answers = $data['nr_max_answers'];
103
104 $this->categories->flushCategories();
105 $result = $ilDB->queryF(
106 "SELECT svy_variable.*, svy_category.title, svy_category.neutral FROM svy_variable, svy_category WHERE svy_variable.question_fi = %s AND svy_variable.category_fi = svy_category.category_id ORDER BY sequence ASC",
107 array('integer'),
108 array($id)
109 );
110 if ($result->numRows() > 0) {
111 while ($data = $ilDB->fetchAssoc($result)) {
112 $this->categories->addCategory($data["title"], $data["other"], $data["neutral"], null, ($data['scale']) ? $data['scale'] : ($data['sequence'] + 1));
113 }
114 }
115 }
116 parent::loadFromDb($id);
117 }
118
125 public function isComplete()
126 {
127 if (
128 strlen($this->getTitle()) &&
129 strlen($this->getAuthor()) &&
130 strlen($this->getQuestiontext()) &&
131 $this->categories->getCategoryCount()
132 ) {
133 return 1;
134 } else {
135 return 0;
136 }
137 }
138
144 public function saveToDb($original_id = "")
145 {
147
148 $affectedRows = parent::saveToDb($original_id);
149 if ($affectedRows == 1) {
150 $affectedRows = $ilDB->manipulateF(
151 "DELETE FROM " . $this->getAdditionalTableName() . " WHERE question_fi = %s",
152 array('integer'),
153 array($this->getId())
154 );
155 $affectedRows = $ilDB->manipulateF(
156 "INSERT INTO " . $this->getAdditionalTableName() . " (question_fi, orientation, use_min_answers, nr_min_answers, nr_max_answers) VALUES (%s, %s, %s, %s, %s)",
157 array('integer', 'text', 'integer', 'integer', 'integer'),
158 array(
159 $this->getId(),
160 $this->getOrientation(),
161 ($this->use_min_answers) ? 1 : 0,
162 ($this->nr_min_answers > 0) ? $this->nr_min_answers : null,
163 ($this->nr_max_answers > 0) ? $this->nr_max_answers : null
164 )
165 );
166
167 // saving material uris in the database
168 $this->saveMaterial();
169 $this->saveCategoriesToDb();
170 }
171 }
172
173 public function saveCategoriesToDb()
174 {
176
177 $affectedRows = $ilDB->manipulateF(
178 "DELETE FROM svy_variable WHERE question_fi = %s",
179 array('integer'),
180 array($this->getId())
181 );
182
183 for ($i = 0; $i < $this->categories->getCategoryCount(); $i++) {
184 $cat = $this->categories->getCategory($i);
185 $category_id = $this->saveCategoryToDb($cat->title, $cat->neutral);
186 $next_id = $ilDB->nextId('svy_variable');
187 $affectedRows = $ilDB->manipulateF(
188 "INSERT INTO svy_variable (variable_id, category_fi, question_fi, value1, other, sequence, scale, tstamp) VALUES (%s, %s, %s, %s, %s, %s, %s, %s)",
189 array('integer','integer','integer','float','integer','integer', 'integer','integer'),
190 array($next_id, $category_id, $this->getId(), ($i + 1), $cat->other, $i, ($cat->scale > 0) ? $cat->scale : null, time())
191 );
192 }
193 $this->saveCompletionStatus();
194 }
195
202 public function toXML($a_include_header = true, $obligatory_state = "")
203 {
204 $a_xml_writer = new ilXmlWriter;
205 $a_xml_writer->xmlHeader();
206 $this->insertXML($a_xml_writer, $a_include_header, $obligatory_state);
207 $xml = $a_xml_writer->xmlDumpMem(false);
208 if (!$a_include_header) {
209 $pos = strpos($xml, "?>");
210 $xml = substr($xml, $pos + 2);
211 }
212 return $xml;
213 }
214
222 public function insertXML(&$a_xml_writer, $a_include_header = true)
223 {
224 $attrs = array(
225 "id" => $this->getId(),
226 "title" => $this->getTitle(),
227 "type" => $this->getQuestiontype(),
228 "obligatory" => $this->getObligatory()
229 );
230 $a_xml_writer->xmlStartTag("question", $attrs);
231
232 $a_xml_writer->xmlElement("description", null, $this->getDescription());
233 $a_xml_writer->xmlElement("author", null, $this->getAuthor());
234 if (strlen($this->label)) {
235 $attrs = array(
236 "label" => $this->label,
237 );
238 } else {
239 $attrs = array();
240 }
241 $a_xml_writer->xmlStartTag("questiontext", $attrs);
242 $this->addMaterialTag($a_xml_writer, $this->getQuestiontext());
243 $a_xml_writer->xmlEndTag("questiontext");
244
245 $a_xml_writer->xmlStartTag("responses");
246
247 for ($i = 0; $i < $this->categories->getCategoryCount(); $i++) {
248 $attrs = array(
249 "id" => $i
250 );
251 if (strlen($this->categories->getCategory($i)->other)) {
252 $attrs['other'] = $this->categories->getCategory($i)->other;
253 }
254 if (strlen($this->categories->getCategory($i)->neutral)) {
255 $attrs['neutral'] = $this->categories->getCategory($i)->neutral;
256 }
257 if (strlen($this->categories->getCategory($i)->label)) {
258 $attrs['label'] = $this->categories->getCategory($i)->label;
259 }
260 if (strlen($this->categories->getCategory($i)->scale)) {
261 $attrs['scale'] = $this->categories->getCategory($i)->scale;
262 }
263 $a_xml_writer->xmlStartTag("response_multiple", $attrs);
264 $this->addMaterialTag($a_xml_writer, $this->categories->getCategory($i)->title);
265 $a_xml_writer->xmlEndTag("response_multiple");
266 }
267
268 $a_xml_writer->xmlEndTag("responses");
269
270 if (count($this->material)) {
271 if (preg_match("/il_(\d*?)_(\w+)_(\d+)/", $this->material["internal_link"], $matches)) {
272 $attrs = array(
273 "label" => $this->material["title"]
274 );
275 $a_xml_writer->xmlStartTag("material", $attrs);
276 $intlink = "il_" . IL_INST_ID . "_" . $matches[2] . "_" . $matches[3];
277 if (strcmp($matches[1], "") != 0) {
278 $intlink = $this->material["internal_link"];
279 }
280 $a_xml_writer->xmlElement("mattext", null, $intlink);
281 $a_xml_writer->xmlEndTag("material");
282 }
283 }
284
285 $a_xml_writer->xmlStartTag("metadata");
286 $a_xml_writer->xmlStartTag("metadatafield");
287 $a_xml_writer->xmlElement("fieldlabel", null, "orientation");
288 $a_xml_writer->xmlElement("fieldentry", null, $this->getOrientation());
289 $a_xml_writer->xmlEndTag("metadatafield");
290 $a_xml_writer->xmlStartTag("metadatafield");
291 $a_xml_writer->xmlElement("fieldlabel", null, "use_min_answers");
292 $a_xml_writer->xmlElement("fieldentry", null, $this->use_min_answers);
293 $a_xml_writer->xmlEndTag("metadatafield");
294 $a_xml_writer->xmlStartTag("metadatafield");
295 $a_xml_writer->xmlElement("fieldlabel", null, "nr_min_answers");
296 $a_xml_writer->xmlElement("fieldentry", null, $this->nr_min_answers);
297 $a_xml_writer->xmlEndTag("metadatafield");
298 $a_xml_writer->xmlStartTag("metadatafield");
299 $a_xml_writer->xmlElement("fieldlabel", null, "nr_max_answers");
300 $a_xml_writer->xmlElement("fieldentry", null, $this->nr_max_answers);
301 $a_xml_writer->xmlEndTag("metadatafield");
302 $a_xml_writer->xmlEndTag("metadata");
303
304 $a_xml_writer->xmlEndTag("question");
305 }
306
313 public function getQuestionType()
314 {
315 return "SurveyMultipleChoiceQuestion";
316 }
317
324 public function getAdditionalTableName()
325 {
326 return "svy_qst_mc";
327 }
328
335 public function &getWorkingDataFromUserInput($post_data)
336 {
337 $entered_value = $post_data[$this->getId() . "_value"];
338 $data = array();
339 if (is_array($entered_value)) {
340 foreach ($entered_value as $idx => $value) {
341 array_push($data, array("value" => $value, "textanswer" => $post_data[$this->getId() . '_' . $value . '_other']));
342 }
343 }
344 for ($i = 0; $i < $this->categories->getCategoryCount(); $i++) {
345 $cat = $this->categories->getCategory($i);
346 if ($cat->other) {
347 // #18212
348 if (!is_array($entered_value) || !in_array($i, $entered_value)) {
349 if (strlen($post_data[$this->getId() . "_" . $i . "_other"])) {
350 array_push($data, array("value" => $i, "textanswer" => $post_data[$this->getId() . '_' . $i . '_other'], "uncheck" => true));
351 }
352 }
353 }
354 }
355 return $data;
356 }
357
367 public function checkUserInput($post_data, $survey_id)
368 {
369 $entered_value = (array) $post_data[$this->getId() . "_value"];
370 if (!$this->getObligatory($survey_id) && (!is_array($entered_value) || count($entered_value) == 0)) {
371 return "";
372 }
373
374 if ($this->use_min_answers && $this->nr_min_answers > 0 && $this->nr_max_answers > 0 && $this->nr_min_answers == $this->nr_max_answers && count($entered_value) != $this->nr_max_answers) {
375 return sprintf($this->lng->txt("err_no_exact_answers"), $this->nr_min_answers);
376 }
377 if ($this->use_min_answers && $this->nr_min_answers > 0 && count($entered_value) < $this->nr_min_answers) {
378 return sprintf($this->lng->txt("err_no_min_answers"), $this->nr_min_answers);
379 }
380 if ($this->use_min_answers && $this->nr_max_answers > 0 && count($entered_value) > $this->nr_max_answers) {
381 return sprintf($this->lng->txt("err_no_max_answers"), $this->nr_max_answers);
382 }
383 if (count($entered_value) == 0) {
384 return $this->lng->txt("question_mr_not_checked");
385 }
386 for ($i = 0; $i < $this->categories->getCategoryCount(); $i++) {
387 $cat = $this->categories->getCategory($i);
388 if ($cat->other) {
389 if (in_array($i, $entered_value)) {
390 if (array_key_exists($this->getId() . "_" . $i . "_other", $post_data) && !strlen($post_data[$this->getId() . "_" . $i . "_other"])) {
391 return $this->lng->txt("question_mr_no_other_answer");
392 }
393 } else {
394 if (strlen($post_data[$this->getId() . "_" . $i . "_other"])) {
395 return $this->lng->txt("question_mr_no_other_answer_checked");
396 }
397 }
398 }
399 }
400 return "";
401 }
402
403 public function saveUserInput($post_data, $active_id, $a_return = false)
404 {
406
407 if ($a_return) {
408 $return_data = array();
409 }
410 if (is_array($post_data[$this->getId() . "_value"])) {
411 foreach ($post_data[$this->getId() . "_value"] as $entered_value) {
412 if (strlen($entered_value) > 0) {
413 if (!$a_return) {
414 $next_id = $ilDB->nextId('svy_answer');
415
416 #20216
417 $fields = array();
418 $fields['answer_id'] = array("integer", $next_id);
419 $fields['question_fi'] = array("integer", $this->getId());
420 $fields['active_fi'] = array("integer", $active_id);
421 $fields['value'] = array("float", (strlen($entered_value)) ? $entered_value : null);
422 $fields['textanswer'] = array("clob", ($post_data[$this->getId() . "_" . $entered_value . "_other"]) ? $this->stripSlashesAddSpaceFallback($post_data[$this->getId() . "_" . $entered_value . "_other"]) : null);
423 $fields['tstamp'] = array("integer", time());
424
425 $affectedRows = $ilDB->insert("svy_answer", $fields);
426 } else {
427 $return_data[] = array("value" => $entered_value,
428 "textanswer" => $post_data[$this->getId() . "_" . $entered_value . "_other"]);
429 }
430 }
431 }
432 }
433 if ($a_return) {
434 return $return_data;
435 }
436 }
437
446 public function importAdditionalMetadata($a_meta)
447 {
448 foreach ($a_meta as $key => $value) {
449 switch ($value["label"]) {
450 case "orientation":
451 $this->setOrientation($value["entry"]);
452 break;
453 case "use_min_answers":
454 $this->use_min_answers = $value["entry"];
455 break;
456 case "nr_min_answers":
457 $this->nr_min_answers = $value["entry"];
458 break;
459 case "nr_max_answers":
460 $this->nr_max_answers = $value["entry"];
461 break;
462 }
463 }
464 }
465
472 public function importResponses($a_data)
473 {
474 foreach ($a_data as $id => $data) {
475 $categorytext = "";
476 foreach ($data["material"] as $material) {
477 $categorytext .= $material["text"];
478 }
479 $this->categories->addCategory(
480 $categorytext,
481 strlen($data['other']) ? $data['other'] : 0,
482 strlen($data['neutral']) ? $data['neutral'] : 0,
483 strlen($data['label']) ? $data['label'] : null,
484 strlen($data['scale']) ? $data['scale'] : null
485 );
486 }
487 }
488
495 public function usableForPrecondition()
496 {
497 return true;
498 }
499
506 public function getAvailableRelations()
507 {
508 return array("=", "<>");
509 }
510
516 public function getPreconditionOptions()
517 {
519
520 $options = array();
521 for ($i = 0; $i < $this->categories->getCategoryCount(); $i++) {
522 $category = $this->categories->getCategory($i);
523 $options[$category->scale - 1] = $category->scale . " - " . $category->title;
524 }
525 return $options;
526 }
527
534 public function getPreconditionSelectValue($default = "", $title, $variable)
535 {
536 $step3 = new ilSelectInputGUI($title, $variable);
537 $options = $this->getPreconditionOptions();
538 $step3->setOptions($options);
539 $step3->setValue($default);
540 return $step3;
541 }
542
550 public function getPreconditionValueOutput($value)
551 {
552 // #18136
553 $category = $this->categories->getCategoryForScale($value + 1);
554
555 // #17895 - see getPreconditionOptions()
556 return $category->scale .
557 " - " .
558 ((strlen($category->title)) ? $category->title : $this->lng->txt('other_answer'));
559 }
560
561 public function getCategories()
562 {
563 return $this->categories;
564 }
565}
$result
An exception for terminatinating execution or to throw for unit testing.
Class SurveyCategories.
toXML($a_include_header=true, $obligatory_state="")
Returns an xml representation of the question.
getPreconditionValueOutput($value)
Returns the output for a precondition value.
getAvailableRelations()
Returns the available relations for the question.
getPreconditionSelectValue($default="", $title, $variable)
Creates a form property for the precondition value.
checkUserInput($post_data, $survey_id)
Checks the input of the active user for obligatory status and entered values.
saveUserInput($post_data, $active_id, $a_return=false)
importResponses($a_data)
Import response data from the question import file.
isComplete()
Returns true if the question is complete for use.
getQuestionType()
Returns the question type of the question.
loadFromDb($id)
Loads a SurveyMultipleChoiceQuestion object from the database.
usableForPrecondition()
Returns if the question is usable for preconditions.
getAdditionalTableName()
Returns the name of the additional question data table in the database.
getQuestionDataArray($id)
Returns the question data fields from the database.
saveToDb($original_id="")
Saves a SurveyMultipleChoiceQuestion object to a database.
insertXML(&$a_xml_writer, $a_include_header=true)
Adds the question XML to a given XMLWriter object.
getPreconditionOptions()
Returns the options for preconditions.
importAdditionalMetadata($a_meta)
Import additional meta data from the question import file.
__construct($title="", $description="", $author="", $questiontext="", $owner=-1, $orientation=0)
The constructor takes possible arguments an creates an instance of the SurveyMultipleChoiceQuestion o...
& getWorkingDataFromUserInput($post_data)
Creates the user data of the svy_answer table from the POST data.
Basic class for all survey question types.
setQuestiontext($questiontext="")
Sets the questiontext of the SurveyQuestion object.
setId($id=-1)
Sets the id of the SurveyQuestion object.
setAuthor($author="")
Sets the authors name of the SurveyQuestion object.
stripSlashesAddSpaceFallback($a_str)
Strip slashes with add space fallback, see https://mantis.ilias.de/view.php?id=19727 and https://mant...
getDescription()
Gets the description string of the SurveyQuestion object.
getId()
Gets the id of the SurveyQuestion object.
setDescription($description="")
Sets the description string of the SurveyQuestion object.
setObjId($obj_id=0)
Set the reference id of the container object.
getAuthor()
Gets the authors name of the SurveyQuestion object.
setOriginalId($original_id)
getQuestiontext()
Gets the questiontext of the SurveyQuestion object.
getObligatory($survey_id="")
Gets the obligatory state of the question.
setOrientation($orientation=0)
Sets the orientation of the question output.
saveCategoryToDb($categorytext, $neutral=0)
Saves a category to the database.
getTitle()
Gets the title string of the SurveyQuestion object.
setComplete($a_complete)
Sets the complete state of the question.
saveMaterial()
save material to db
setOwner($owner="")
Sets the creator/owner ID of the SurveyQuestion object.
setTitle($title="")
Sets the title string of the SurveyQuestion object.
saveCompletionStatus($original_id="")
Saves the complete flag to the database.
getOrientation()
Gets the orientation of the question output.
addMaterialTag(&$a_xml_writer, $a_material, $close_material_tag=true, $add_mobs=true, $a_attrs=null)
Creates an XML material tag from a plain text or xhtml text.
setObligatory($obligatory=1)
Sets the obligatory state of the question.
static _replaceMediaObjectImageSrc($a_text, $a_direction=0, $nic=IL_INST_ID)
Replaces image source from mob image urls with the mob id or replaces mob id with the correct image s...
This class represents a selection list property in a property form.
XML writer class.
xmlHeader()
Writes xml header @access public.
$i
Definition: metadata.php:24
$xml
Definition: metadata.php:332
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
global $ilDB
$data
Definition: storeScorm.php:23
$DIC
Definition: xapitoken.php:46