ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.SurveySingleChoiceQuestion.php
Go to the documentation of this file.
1<?php
2
28{
30
31 public function __construct(
32 string $title = "",
33 string $description = "",
34 string $author = "",
35 string $questiontext = "",
36 int $owner = -1,
37 int $orientation = 1
38 ) {
39 global $DIC;
40
41 $this->db = $DIC->database();
42 $this->user = $DIC->user();
43 $this->lng = $DIC->language();
45
46 $this->orientation = $orientation;
47 $this->categories = new SurveyCategories();
48 }
49
50
51 public function getQuestionDataArray(int $id): array
52 {
54
55 $result = $ilDB->queryF(
56 "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",
57 array('integer'),
58 array($id)
59 );
60 if ($result->numRows() === 1) {
61 return $ilDB->fetchAssoc($result);
62 } else {
63 return array();
64 }
65 }
66
67 public function loadFromDb(int $question_id): void
68 {
70
71 $result = $ilDB->queryF(
72 "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",
73 array('integer'),
74 array($question_id)
75 );
76 if ($result->numRows() === 1) {
77 $data = $ilDB->fetchAssoc($result);
78 $this->setId((int) $data["question_id"]);
79 $this->setTitle((string) $data["title"]);
80 $this->label = (string) $data['label'];
81 $this->setDescription((string) $data["description"]);
82 $this->setObjId((int) $data["obj_fi"]);
83 $this->setAuthor((string) $data["author"]);
84 $this->setOwner((int) $data["owner_fi"]);
85 $this->setQuestiontext(ilRTE::_replaceMediaObjectImageSrc((string) $data["questiontext"], 1));
86 $this->setObligatory((bool) $data["obligatory"]);
87 $this->setComplete((bool) $data["complete"]);
88 $this->setOriginalId((int) $data["original_id"]);
89 $this->setOrientation((int) $data["orientation"]);
90
91 $this->categories->flushCategories();
92 $result = $ilDB->queryF(
93 "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",
94 array('integer'),
95 array($question_id)
96 );
97 if ($result->numRows() > 0) {
98 while ($data = $ilDB->fetchAssoc($result)) {
99 $this->categories->addCategory($data["title"], $data["other"], $data["neutral"], null, ($data['scale']) ?: ($data['sequence'] + 1));
100 }
101 }
102 }
103 parent::loadFromDb($question_id);
104 }
105
106 public function isComplete(): bool
107 {
108 if (
109 $this->getTitle() !== '' &&
110 $this->getAuthor() !== '' &&
111 $this->getQuestiontext() !== '' &&
112 $this->categories->getCategoryCount()
113 ) {
114 return true;
115 } else {
116 return false;
117 }
118 }
119
120 public function saveToDb(int $original_id = 0): int
121 {
123
124 $affectedRows = parent::saveToDb($original_id);
125 if ($affectedRows === 1) {
126 $this->log->debug("Before save Category-> DELETE from svy_qst_sc WHERE question_fi = " . $this->getId() . " AND INSERT again the same id and orientation in svy_qst_sc");
127 $ilDB->manipulateF(
128 "DELETE FROM " . $this->getAdditionalTableName() . " WHERE question_fi = %s",
129 array('integer'),
130 array($this->getId())
131 );
132 $ilDB->manipulateF(
133 "INSERT INTO " . $this->getAdditionalTableName() . " (question_fi, orientation) VALUES (%s, %s)",
134 array('integer', 'text'),
135 array(
136 $this->getId(),
137 $this->getOrientation()
138 )
139 );
140
141 $this->saveCategoriesToDb();
142 }
143 return $affectedRows;
144 }
145
146 public function saveCategoriesToDb(): void
147 {
149
150 $this->log->debug("DELETE from svy_variable before the INSERT into svy_variable. if scale > 0 we get scale value else we get null");
151
152 $affectedRows = $ilDB->manipulateF(
153 "DELETE FROM svy_variable WHERE question_fi = %s",
154 array('integer'),
155 array($this->getId())
156 );
157
158 for ($i = 0; $i < $this->categories->getCategoryCount(); $i++) {
159 $cat = $this->categories->getCategory($i);
160 $category_id = $this->saveCategoryToDb($cat->title, $cat->neutral);
161 $next_id = $ilDB->nextId('svy_variable');
162 $affectedRows = $ilDB->manipulateF(
163 "INSERT INTO svy_variable (variable_id, category_fi, question_fi, value1, other, sequence, scale, tstamp) VALUES (%s, %s, %s, %s, %s, %s, %s, %s)",
164 array('integer','integer','integer','float','integer','integer', 'integer','integer'),
165 array($next_id, $category_id, $this->getId(), ($i + 1), $cat->other, $i, ($cat->scale > 0) ? $cat->scale : null, time())
166 );
167
168 $debug_scale = ($cat->scale > 0) ? $cat->scale : null;
169 $this->log->debug("INSERT INTO svy_variable category_fi= " . $category_id . " question_fi= " . $this->getId() . " value1= " . ($i + 1) . " other= " . $cat->other . " sequence= " . $i . " scale =" . $debug_scale);
170 }
171 $this->saveCompletionStatus();
172 }
173
174 public function toXML(
175 bool $a_include_header = true,
176 bool $obligatory_state = false
177 ): string {
178 $a_xml_writer = new ilXmlWriter();
179 $a_xml_writer->xmlHeader();
180 $this->insertXML($a_xml_writer, $a_include_header);
181 $xml = $a_xml_writer->xmlDumpMem(false);
182 if (!$a_include_header) {
183 $pos = strpos($xml, "?>");
184 $xml = substr($xml, $pos + 2);
185 }
186 return $xml;
187 }
188
189 public function insertXML(
190 ilXmlWriter $a_xml_writer,
191 bool $a_include_header = true
192 ): void {
193 $attrs = array(
194 "id" => $this->getId(),
195 "title" => $this->getTitle(),
196 "type" => $this->getQuestionType(),
197 "obligatory" => $this->getObligatory()
198 );
199 $a_xml_writer->xmlStartTag("question", $attrs);
200
201 $a_xml_writer->xmlElement("description", null, $this->getDescription());
202 $a_xml_writer->xmlElement("author", null, $this->getAuthor());
203 if (strlen($this->label ?? "")) {
204 $attrs = array(
205 "label" => $this->label,
206 );
207 } else {
208 $attrs = array();
209 }
210 $a_xml_writer->xmlStartTag("questiontext", $attrs);
211 $this->addMaterialTag($a_xml_writer, $this->getQuestiontext());
212 $a_xml_writer->xmlEndTag("questiontext");
213
214 $a_xml_writer->xmlStartTag("responses");
215
216 for ($i = 0; $i < $this->categories->getCategoryCount(); $i++) {
217 $attrs = array(
218 "id" => $i
219 );
220 if (strlen($this->categories->getCategory($i)->other ?? "")) {
221 $attrs['other'] = $this->categories->getCategory($i)->other;
222 }
223 if (strlen($this->categories->getCategory($i)->neutral ?? "")) {
224 $attrs['neutral'] = $this->categories->getCategory($i)->neutral;
225 }
226 if (strlen($this->categories->getCategory($i)->label ?? "")) {
227 $attrs['label'] = $this->categories->getCategory($i)->label;
228 }
229 if (strlen($this->categories->getCategory($i)->scale ?? "")) {
230 $attrs['scale'] = $this->categories->getCategory($i)->scale;
231 }
232 $a_xml_writer->xmlStartTag("response_single", $attrs);
233 $this->addMaterialTag($a_xml_writer, $this->categories->getCategory($i)->title);
234 $a_xml_writer->xmlEndTag("response_single");
235 }
236
237 $a_xml_writer->xmlEndTag("responses");
238
239 if (count($this->material)) {
240 if (preg_match("/il_(\d*?)_(\w+)_(\d+)/", $this->material["internal_link"] ?? "", $matches)) {
241 $attrs = array(
242 "label" => $this->material["title"]
243 );
244 $a_xml_writer->xmlStartTag("material", $attrs);
245 $intlink = "il_" . IL_INST_ID . "_" . $matches[2] . "_" . $matches[3];
246 if (strcmp($matches[1], "") != 0) {
247 $intlink = $this->material["internal_link"];
248 }
249 $a_xml_writer->xmlElement("mattext", null, $intlink);
250 $a_xml_writer->xmlEndTag("material");
251 }
252 }
253
254 $a_xml_writer->xmlStartTag("metadata");
255 $a_xml_writer->xmlStartTag("metadatafield");
256 $a_xml_writer->xmlElement("fieldlabel", null, "orientation");
257 $a_xml_writer->xmlElement("fieldentry", null, $this->getOrientation());
258 $a_xml_writer->xmlEndTag("metadatafield");
259 $a_xml_writer->xmlEndTag("metadata");
260
261 $a_xml_writer->xmlEndTag("question");
262 }
263
264 public function importAdditionalMetadata(array $a_meta): void
265 {
266 foreach ($a_meta as $key => $value) {
267 switch ($value["label"]) {
268 case "orientation":
269 $this->setOrientation($value["entry"]);
270 break;
271 }
272 }
273 }
274
278 public function addStandardNumbers(
279 int $lower_limit,
280 int $upper_limit
281 ): void {
282 for ($i = $lower_limit; $i <= $upper_limit; $i++) {
283 $this->categories->addCategory($i);
284 }
285 }
286
287 public function getQuestionType(): string
288 {
289 return "SurveySingleChoiceQuestion";
290 }
291
292 public function getAdditionalTableName(): string
293 {
294 return "svy_qst_sc";
295 }
296
298 array $post_data
299 ): array {
300 $entered_value = $post_data[$this->getId() . "_value"] ?? "";
301 $data = array();
302 if (strlen($entered_value ?? "")) {
303 $data[] = array("value" => $entered_value,
304 "textanswer" => $post_data[$this->getId() . '_' . $entered_value . '_other'] ?? ""
305 );
306 }
307 for ($i = 0; $i < $this->categories->getCategoryCount(); $i++) {
308 $cat = $this->categories->getCategory($i);
309 if ($cat->other) {
310 if ($i != $entered_value) {
311 if (strlen($post_data[$this->getId() . "_" . $i . "_other"] ?? "")) {
312 $data[] = array("value" => $i,
313 "textanswer" => $post_data[$this->getId() . '_' . $i . '_other'] ?? "",
314 "uncheck" => true
315 );
316 }
317 }
318 }
319 }
320 return $data;
321 }
322
327 public function checkUserInput(
328 array $post_data,
329 int $survey_id
330 ): string {
331 $entered_value = $post_data[$this->getId() . "_value"] ?? "";
332
333 $this->log->debug("Entered value = " . $entered_value);
334
335 if ((!$this->getObligatory()) && (strlen($entered_value ?? "") == 0)) {
336 return "";
337 }
338
339 if (strlen($entered_value ?? "") == 0) {
340 return $this->lng->txt("question_not_checked");
341 }
342
343 for ($i = 0; $i < $this->categories->getCategoryCount(); $i++) {
344 $cat = $this->categories->getCategory($i);
345 if ($cat->other) {
346 if ($i == $entered_value) {
347 if (array_key_exists($this->getId() . "_" . $entered_value . "_other", $post_data) && !strlen($post_data[$this->getId() . "_" . $entered_value . "_other"] ?? "")) {
348 return $this->lng->txt("question_mr_no_other_answer");
349 }
350 } elseif (strlen($post_data[$this->getId() . "_" . $i . "_other"] ?? "")) {
351 return $this->lng->txt("question_sr_no_other_answer_checked");
352 }
353 }
354 }
355
356 return "";
357 }
358
359 public function saveUserInput(
360 array $post_data,
361 int $active_id,
362 bool $a_return = false
363 ): ?array {
364 $ilDB = $this->db;
365
366 $entered_value = $post_data[$this->getId() . "_value"] ?? "";
367
368 if ($a_return) {
369 return array(array("value" => $entered_value,
370 "textanswer" => $post_data[$this->getId() . "_" . $entered_value . "_other"] ?? ""));
371 }
372 if (strlen($entered_value ?? "") == 0) {
373 return null;
374 }
375
376 $next_id = $ilDB->nextId('svy_answer');
377 #20216
378 $fields = array();
379 $fields['answer_id'] = array("integer", $next_id);
380 $fields['question_fi'] = array("integer", $this->getId());
381 $fields['active_fi'] = array("integer", $active_id);
382 $fields['value'] = array("float", (strlen($entered_value ?? "")) ? $entered_value : null);
383 $fields['textanswer'] = array("clob", isset($post_data[$this->getId() . "_" . $entered_value . "_other"]) ?
384 $this->stripSlashesAddSpaceFallback($post_data[$this->getId() . "_" . $entered_value . "_other"]) : null);
385 $fields['tstamp'] = array("integer", time());
386
387 $affectedRows = $ilDB->insert("svy_answer", $fields);
388
389 $debug_value = (strlen($entered_value ?? "")) ? $entered_value : "NULL";
390 $debug_answer = $post_data[$this->getId() . "_" . $entered_value . "_other"] ?? "NULL";
391 $this->log->debug("INSERT svy_answer answer_id=" . $next_id . " question_fi=" . $this->getId() . " active_fi=" . $active_id . " value=" . $debug_value . " textanswer=" . $debug_answer);
392 return null;
393 }
394
395 public function importResponses(array $a_data): void
396 {
397 foreach ($a_data as $id => $data) {
398 $categorytext = "";
399 foreach ($data["material"] as $material) {
400 $categorytext .= $material["text"];
401 }
402 $this->categories->addCategory(
403 $categorytext,
404 strlen($data['other'] ?? "") ? $data['other'] : 0,
405 strlen($data['neutral'] ?? "") ? $data['neutral'] : 0,
406 strlen($data['label'] ?? "") ? $data['label'] : null,
407 strlen($data['scale'] ?? "") ? $data['scale'] : null
408 );
409 }
410 }
411
412 public function usableForPrecondition(): bool
413 {
414 return true;
415 }
416
417 public function getAvailableRelations(): array
418 {
419 return array("<", "<=", "=", "<>", ">=", ">");
420 }
421
422 public function getPreconditionOptions(): array
423 {
424 $options = array();
425 for ($i = 0; $i < $this->categories->getCategoryCount(); $i++) {
426 $category = $this->categories->getCategory($i);
427 $options[$category->scale - 1] = $category->scale . " - " . $category->title;
428 }
429 return $options;
430 }
431
433 string $default,
434 string $title,
435 string $variable
437 $step3 = new ilSelectInputGUI($title, $variable);
438 $options = $this->getPreconditionOptions();
439 $step3->setOptions($options);
440 $step3->setValue($default);
441 return $step3;
442 }
443
445 string $value
446 ): string {
447 // #18136
448 $category = $this->categories->getCategoryForScale((int) $value + 1);
449
450 $scale = "";
451 $title = "";
452 if ($category) {
453 $scale = $category->scale;
454 $title = $category->title;
455 }
456
457 // #17895 - see getPreconditionOptions()
458 return $scale .
459 " - " .
460 ((strlen($title)) ? $title : $this->lng->txt('other_answer'));
461 }
462
464 {
465 return $this->categories;
466 }
467
468 public static function getMaxSumScore(int $survey_id): int
469 {
470 global $DIC;
471
472 // we need max scale values of single choice questions (type 2)
473 $db = $DIC->database();
474 $set = $db->queryF(
475 "SELECT SUM(max_sum_score) sum_sum_score FROM (SELECT MAX(scale) max_sum_score FROM svy_svy_qst sq " .
476 "JOIN svy_question q ON (sq.question_fi = q.question_id) " .
477 "JOIN svy_variable v ON (v.question_fi = q.question_id) " .
478 "WHERE sq.survey_fi = %s AND q.questiontype_fi = %s " .
479 "GROUP BY (q.question_id)) x",
480 ["integer", "integer"],
481 [$survey_id, 2]
482 );
483 $rec = $db->fetchAssoc($set);
484 return (int) $rec["sum_sum_score"];
485 }
486
487 protected function isSumScoreValid(int $nr_answer_records): bool
488 {
489 if ($nr_answer_records == 1) {
490 return true;
491 }
492 return false;
493 }
494
495 public static function compressable(
496 int $id1,
497 int $id2
498 ): bool {
500 $q1 = SurveyQuestion::_instanciateQuestion($id1);
503 if ($q1->getOrientation() !== 1 || $q2->getOrientation() !== 1) {
504 return false;
505 }
506 if (self::getCompressCompareString($q1) === self::getCompressCompareString($q2)) {
507 return true;
508 }
509 return false;
510 }
511
512 public static function getCompressCompareString(
514 ): string {
515 $str = "";
516 for ($i = 0; $i < $q->categories->getCategoryCount(); $i++) {
517 $cat = $q->categories->getCategory($i);
518 $str .= ":" . $cat->scale . ":" . $cat->title;
519 }
520 return $str;
521 }
522}
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
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...
setTitle(string $title="")
saveCategoryToDb(string $categorytext, int $neutral=0)
Saves a category to the database.
setQuestiontext(string $questiontext="")
setDescription(string $description="")
setObjId(int $obj_id=0)
Set the reference(?) id of the container object.
setOrientation(int $orientation=0)
setOwner(int $owner=0)
static _instanciateQuestion(int $question_id)
Get question object.
setComplete(bool $a_complete)
setOriginalId(?int $original_id)
saveCompletionStatus(int $original_id=0)
Saves the complete flag to the database.
setObligatory(bool $obligatory=true)
setAuthor(string $author="")
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
insertXML(ilXmlWriter $a_xml_writer, bool $a_include_header=true)
saveToDb(int $original_id=0)
Saves a SurveyQuestion object to a database.
saveUserInput(array $post_data, int $active_id, bool $a_return=false)
getPreconditionOptions()
Returns the options for preconditions.
checkUserInput(array $post_data, int $survey_id)
Checks the input of the active user for obligatory status and entered values.
loadFromDb(int $question_id)
load question data into object note: this base implementation only loads the material data
__construct(string $title="", string $description="", string $author="", string $questiontext="", int $owner=-1, int $orientation=1)
getQuestionDataArray(int $id)
Returns the question data.
usableForPrecondition()
Returns if the question is usable for preconditions.
importResponses(array $a_data)
Import response data from the question import file.
static getCompressCompareString(SurveySingleChoiceQuestion $q)
getPreconditionValueOutput(string $value)
Returns the output for a precondition value.
getPreconditionSelectValue(string $default, string $title, string $variable)
Creates a form property for the precondition value.
getAvailableRelations()
Returns the available relations for the question.
toXML(bool $a_include_header=true, bool $obligatory_state=false)
importAdditionalMetadata(array $a_meta)
Import additional meta data from the question import file.
addStandardNumbers(int $lower_limit, int $upper_limit)
Adds standard numbers as categories.
getWorkingDataFromUserInput(array $post_data)
Creates the user data of the svy_answer table from the POST data.
static getMaxSumScore(int $survey_id)
Get max sum score for specific survey (and this question type)
This class represents a property in a property form.
static _replaceMediaObjectImageSrc(string $a_text, int $a_direction=0, string $nic='')
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.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
xmlElement(string $tag, $attrs=null, $data=null, $encode=true, $escape=true)
Writes a basic element (no children, just textual content)
xmlHeader()
Writes xml header.
xmlEndTag(string $tag)
Writes an endtag.
xmlStartTag(string $tag, ?array $attrs=null, bool $empty=false, bool $encode=true, bool $escape=true)
Writes a starttag.
const IL_INST_ID
Definition: constants.php:40
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
global $DIC
Definition: shib_login.php:26
$q
Definition: shib_logout.php:23