ILIAS  Release_5_0_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.SurveyMultipleChoiceQuestion.php
Go to the documentation of this file.
1 <?php
2  /*
3  +----------------------------------------------------------------------------+
4  | ILIAS open source |
5  +----------------------------------------------------------------------------+
6  | Copyright (c) 1998-2001 ILIAS open source, University of Cologne |
7  | |
8  | This program is free software; you can redistribute it and/or |
9  | modify it under the terms of the GNU General Public License |
10  | as published by the Free Software Foundation; either version 2 |
11  | of the License, or (at your option) any later version. |
12  | |
13  | This program is distributed in the hope that it will be useful, |
14  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16  | GNU General Public License for more details. |
17  | |
18  | You should have received a copy of the GNU General Public License |
19  | along with this program; if not, write to the Free Software |
20  | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
21  +----------------------------------------------------------------------------+
22 */
23 
24 include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestion.php";
25 
38 {
45 
56  $title = "",
57  $description = "",
58  $author = "",
59  $questiontext = "",
60  $owner = -1,
61  $orientation = 0
62  )
63  {
65  $this->orientation = $orientation;
66  include_once "./Modules/SurveyQuestionPool/classes/class.SurveyCategories.php";
67  $this->categories = new SurveyCategories();
68  }
69 
78  {
79  global $ilDB;
80 
81  $result = $ilDB->queryF("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",
82  array('integer'),
83  array($id)
84  );
85  if ($result->numRows() == 1)
86  {
87  return $ilDB->fetchAssoc($result);
88  }
89  else
90  {
91  return array();
92  }
93  }
94 
101  function loadFromDb($id)
102  {
103  global $ilDB;
104 
105  $result = $ilDB->queryF("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",
106  array('integer'),
107  array($id)
108  );
109  if ($result->numRows() == 1)
110  {
111  $data = $ilDB->fetchAssoc($result);
112  $this->setId($data["question_id"]);
113  $this->setTitle($data["title"]);
114  $this->label = $data['label'];
115  $this->setDescription($data["description"]);
116  $this->setObjId($data["obj_fi"]);
117  $this->setAuthor($data["author"]);
118  $this->setOwner($data["owner_fi"]);
119  include_once("./Services/RTE/classes/class.ilRTE.php");
120  $this->setQuestiontext(ilRTE::_replaceMediaObjectImageSrc($data["questiontext"], 1));
121  $this->setObligatory($data["obligatory"]);
122  $this->setComplete($data["complete"]);
123  $this->setOriginalId($data["original_id"]);
124  $this->setOrientation($data["orientation"]);
125  $this->use_min_answers = ($data['use_min_answers']) ? true : false;
126  $this->nr_min_answers = $data['nr_min_answers'];
127  $this->nr_max_answers = $data['nr_max_answers'];
128 
129  $this->categories->flushCategories();
130  $result = $ilDB->queryF("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",
131  array('integer'),
132  array($id)
133  );
134  if ($result->numRows() > 0)
135  {
136  while ($data = $ilDB->fetchAssoc($result))
137  {
138  $this->categories->addCategory($data["title"], $data["other"], $data["neutral"], null, ($data['scale']) ? $data['scale'] : ($data['sequence'] + 1));
139  }
140  }
141  }
143  }
144 
151  function isComplete()
152  {
153  if (
154  strlen($this->getTitle()) &&
155  strlen($this->getAuthor()) &&
156  strlen($this->getQuestiontext()) &&
157  $this->categories->getCategoryCount()
158  )
159  {
160  return 1;
161  }
162  else
163  {
164  return 0;
165  }
166  }
167 
173  function saveToDb($original_id = "")
174  {
175  global $ilDB;
176 
177  $affectedRows = parent::saveToDb($original_id);
178  if ($affectedRows == 1)
179  {
180  $affectedRows = $ilDB->manipulateF("DELETE FROM " . $this->getAdditionalTableName() . " WHERE question_fi = %s",
181  array('integer'),
182  array($this->getId())
183  );
184  $affectedRows = $ilDB->manipulateF("INSERT INTO " . $this->getAdditionalTableName() . " (question_fi, orientation, use_min_answers, nr_min_answers, nr_max_answers) VALUES (%s, %s, %s, %s, %s)",
185  array('integer', 'text', 'integer', 'integer', 'integer'),
186  array(
187  $this->getId(),
188  $this->getOrientation(),
189  ($this->use_min_answers) ? 1 : 0,
190  ($this->nr_min_answers > 0) ? $this->nr_min_answers : null,
191  ($this->nr_max_answers > 0) ? $this->nr_max_answers : null
192  )
193  );
194 
195  // saving material uris in the database
196  $this->saveMaterial();
197  $this->saveCategoriesToDb();
198  }
199  }
200 
202  {
203  global $ilDB;
204 
205  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_variable WHERE question_fi = %s",
206  array('integer'),
207  array($this->getId())
208  );
209 
210  for ($i = 0; $i < $this->categories->getCategoryCount(); $i++)
211  {
212  $cat = $this->categories->getCategory($i);
213  $category_id = $this->saveCategoryToDb($cat->title, $cat->neutral);
214  $next_id = $ilDB->nextId('svy_variable');
215  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_variable (variable_id, category_fi, question_fi, value1, other, sequence, scale, tstamp) VALUES (%s, %s, %s, %s, %s, %s, %s, %s)",
216  array('integer','integer','integer','float','integer','integer', 'integer','integer'),
217  array($next_id, $category_id, $this->getId(), ($i + 1), $cat->other, $i, ($cat->scale > 0) ? $cat->scale : null, time())
218  );
219  }
220  $this->saveCompletionStatus();
221  }
222 
229  function toXML($a_include_header = TRUE, $obligatory_state = "")
230  {
231  include_once("./Services/Xml/classes/class.ilXmlWriter.php");
232  $a_xml_writer = new ilXmlWriter;
233  $a_xml_writer->xmlHeader();
234  $this->insertXML($a_xml_writer, $a_include_header, $obligatory_state);
235  $xml = $a_xml_writer->xmlDumpMem(FALSE);
236  if (!$a_include_header)
237  {
238  $pos = strpos($xml, "?>");
239  $xml = substr($xml, $pos + 2);
240  }
241  return $xml;
242  }
243 
252  function insertXML(&$a_xml_writer, $a_include_header = TRUE, $obligatory_state = "")
253  {
254  $attrs = array(
255  "id" => $this->getId(),
256  "title" => $this->getTitle(),
257  "type" => $this->getQuestiontype(),
258  "obligatory" => $this->getObligatory()
259  );
260  $a_xml_writer->xmlStartTag("question", $attrs);
261 
262  $a_xml_writer->xmlElement("description", NULL, $this->getDescription());
263  $a_xml_writer->xmlElement("author", NULL, $this->getAuthor());
264  if (strlen($this->label))
265  {
266  $attrs = array(
267  "label" => $this->label,
268  );
269  }
270  else
271  {
272  $attrs = array();
273  }
274  $a_xml_writer->xmlStartTag("questiontext", $attrs);
275  $this->addMaterialTag($a_xml_writer, $this->getQuestiontext());
276  $a_xml_writer->xmlEndTag("questiontext");
277 
278  $a_xml_writer->xmlStartTag("responses");
279 
280  for ($i = 0; $i < $this->categories->getCategoryCount(); $i++)
281  {
282  $attrs = array(
283  "id" => $i
284  );
285  if (strlen($this->categories->getCategory($i)->other)) $attrs['other'] = $this->categories->getCategory($i)->other;
286  if (strlen($this->categories->getCategory($i)->neutral)) $attrs['neutral'] = $this->categories->getCategory($i)->neutral;
287  if (strlen($this->categories->getCategory($i)->label)) $attrs['label'] = $this->categories->getCategory($i)->label;
288  if (strlen($this->categories->getCategory($i)->scale)) $attrs['scale'] = $this->categories->getCategory($i)->scale;
289  $a_xml_writer->xmlStartTag("response_multiple", $attrs);
290  $this->addMaterialTag($a_xml_writer, $this->categories->getCategory($i)->title);
291  $a_xml_writer->xmlEndTag("response_multiple");
292  }
293 
294  $a_xml_writer->xmlEndTag("responses");
295 
296  if (count($this->material))
297  {
298  if (preg_match("/il_(\d*?)_(\w+)_(\d+)/", $this->material["internal_link"], $matches))
299  {
300  $attrs = array(
301  "label" => $this->material["title"]
302  );
303  $a_xml_writer->xmlStartTag("material", $attrs);
304  $intlink = "il_" . IL_INST_ID . "_" . $matches[2] . "_" . $matches[3];
305  if (strcmp($matches[1], "") != 0)
306  {
307  $intlink = $this->material["internal_link"];
308  }
309  $a_xml_writer->xmlElement("mattext", NULL, $intlink);
310  $a_xml_writer->xmlEndTag("material");
311  }
312  }
313 
314  $a_xml_writer->xmlStartTag("metadata");
315  $a_xml_writer->xmlStartTag("metadatafield");
316  $a_xml_writer->xmlElement("fieldlabel", NULL, "orientation");
317  $a_xml_writer->xmlElement("fieldentry", NULL, $this->getOrientation());
318  $a_xml_writer->xmlEndTag("metadatafield");
319  $a_xml_writer->xmlStartTag("metadatafield");
320  $a_xml_writer->xmlElement("fieldlabel", NULL, "use_min_answers");
321  $a_xml_writer->xmlElement("fieldentry", NULL, $this->use_min_answers);
322  $a_xml_writer->xmlEndTag("metadatafield");
323  $a_xml_writer->xmlStartTag("metadatafield");
324  $a_xml_writer->xmlElement("fieldlabel", NULL, "nr_min_answers");
325  $a_xml_writer->xmlElement("fieldentry", NULL, $this->nr_min_answers);
326  $a_xml_writer->xmlEndTag("metadatafield");
327  $a_xml_writer->xmlStartTag("metadatafield");
328  $a_xml_writer->xmlElement("fieldlabel", NULL, "nr_max_answers");
329  $a_xml_writer->xmlElement("fieldentry", NULL, $this->nr_max_answers);
330  $a_xml_writer->xmlEndTag("metadatafield");
331  $a_xml_writer->xmlEndTag("metadata");
332 
333  $a_xml_writer->xmlEndTag("question");
334  }
335 
342  function getQuestionType()
343  {
344  return "SurveyMultipleChoiceQuestion";
345  }
346 
354  {
355  return "svy_qst_mc";
356  }
357 
364  function &getWorkingDataFromUserInput($post_data)
365  {
366  $entered_value = $post_data[$this->getId() . "_value"];
367  $data = array();
368  if (is_array($entered_value))
369  {
370  foreach ($entered_value as $idx => $value)
371  {
372  array_push($data, array("value" => $value, "textanswer" => $post_data[$this->getId() . '_' . $value . '_other']));
373  }
374  }
375  for ($i = 0; $i < $this->categories->getCategoryCount(); $i++)
376  {
377  $cat = $this->categories->getCategory($i);
378  if ($cat->other)
379  {
380  if (!in_array($i, $entered_value))
381  {
382  if (strlen($post_data[$this->getId() . "_" . $i . "_other"]))
383  {
384  array_push($data, array("value" => $i, "textanswer" => $post_data[$this->getId() . '_' . $i . '_other'], "uncheck" => true));
385  }
386  }
387  }
388  }
389  return $data;
390  }
391 
401  function checkUserInput($post_data, $survey_id)
402  {
403  $entered_value = $post_data[$this->getId() . "_value"];
404  if (!$this->getObligatory($survey_id) && count($entered_value) == 0) return "";
405 
406  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)
407  {
408  return sprintf($this->lng->txt("err_no_exact_answers"), $this->nr_min_answers);
409  }
410  if ($this->use_min_answers && $this->nr_min_answers > 0 && count($entered_value) < $this->nr_min_answers)
411  {
412  return sprintf($this->lng->txt("err_no_min_answers"), $this->nr_min_answers);
413  }
414  if ($this->use_min_answers && $this->nr_max_answers > 0 && count($entered_value) > $this->nr_max_answers)
415  {
416  return sprintf($this->lng->txt("err_no_max_answers"), $this->nr_max_answers);
417  }
418  if (!is_array($entered_value))
419  {
420  return $this->lng->txt("question_mr_not_checked");
421  }
422  for ($i = 0; $i < $this->categories->getCategoryCount(); $i++)
423  {
424  $cat = $this->categories->getCategory($i);
425  if ($cat->other)
426  {
427  if (in_array($i, $entered_value))
428  {
429  if (array_key_exists($this->getId() . "_" . $i . "_other", $post_data) && !strlen($post_data[$this->getId() . "_" . $i . "_other"]))
430  {
431  return $this->lng->txt("question_mr_no_other_answer");
432  }
433  }
434  else
435  {
436  if (strlen($post_data[$this->getId() . "_" . $i . "_other"]))
437  {
438  return $this->lng->txt("question_mr_no_other_answer_checked");
439  }
440  }
441  }
442  }
443  return "";
444  }
445 
451  public function saveRandomData($active_id)
452  {
453  global $ilDB;
454  // multiple responses
455  for ($i = 0; $i < $this->categories->getCategoryCount(); $i++)
456  {
457  if (rand(0,1))
458  {
459  $cat = $this->categories->getCategory($i);
460  $next_id = $ilDB->nextId('svy_answer');
461  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_answer (answer_id, question_fi, active_fi, value, textanswer, tstamp) VALUES (%s, %s, %s, %s, %s, %s)",
462  array('integer','integer','integer','float','text','integer'),
463  array($next_id, $this->getId(), $active_id, $i, ($cat->other) ? "Random Data" : null, time())
464  );
465  }
466  }
467  }
468 
469  function saveUserInput($post_data, $active_id, $a_return = false)
470  {
471  global $ilDB;
472 
473  if($a_return)
474  {
475  $return_data = array();
476  }
477  if (is_array($post_data[$this->getId() . "_value"]))
478  {
479  foreach ($post_data[$this->getId() . "_value"] as $entered_value)
480  {
481  if (strlen($entered_value) > 0)
482  {
483  if(!$a_return)
484  {
485  $next_id = $ilDB->nextId('svy_answer');
486  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_answer (answer_id, question_fi, active_fi, value, textanswer, tstamp) VALUES (%s, %s, %s, %s, %s, %s)",
487  array('integer','integer','integer','float','text','integer'),
488  array($next_id, $this->getId(), $active_id, (strlen($entered_value)) ? $entered_value : NULL, ($post_data[$this->getId() . "_" . $entered_value . "_other"]) ? $post_data[$this->getId() . "_" . $entered_value . "_other"] : null, time())
489  );
490  }
491  else
492  {
493  $return_data[] = array("value"=>$entered_value,
494  "textanswer"=>$post_data[$this->getId() . "_" . $entered_value . "_other"]);
495  }
496  }
497  }
498  }
499  if($a_return)
500  {
501  return $return_data;
502  }
503  }
504 
505  function &getCumulatedResults($survey_id, $nr_of_users, $finished_ids)
506  {
507  global $ilDB;
508 
509  $question_id = $this->getId();
510 
511  $result_array = array();
512  $cumulated = array();
513 
514  $sql = "SELECT svy_answer.* FROM svy_answer".
515  " JOIN svy_finished ON (svy_finished.finished_id = svy_answer.active_fi)".
516  " WHERE svy_answer.question_fi = ".$ilDB->quote($question_id, "integer").
517  " AND svy_finished.survey_fi = ".$ilDB->quote($survey_id, "integer");
518  if($finished_ids)
519  {
520  $sql .= " AND ".$ilDB->in("svy_finished.finished_id", $finished_ids, "", "integer");
521  }
522 
523  $result = $ilDB->query($sql);
524  $numrows = $result->numRows();
525 
526  // count the answers for every answer value
527  $textanswers = array();
528  while ($row = $ilDB->fetchAssoc($result))
529  {
530  $cumulated[$row["value"]]++;
531 
532  // add text value to result array
533  if ($row["textanswer"])
534  {
535  $textanswers[$row["value"]][] = $row["textanswer"];
536  }
537  }
538  // sort textanswers by value
539  if (is_array($textanswers))
540  {
541  ksort($textanswers, SORT_NUMERIC);
542  }
543  asort($cumulated, SORT_NUMERIC);
544  end($cumulated);
545 
546  $sql = "SELECT svy_answer.answer_id, svy_answer.question_fi, svy_answer.active_fi".
547  " FROM svy_answer".
548  " JOIN svy_finished ON (svy_finished.finished_id = svy_answer.active_fi)".
549  " WHERE svy_answer.question_fi = ".$ilDB->quote($question_id, "integer").
550  " AND svy_finished.survey_fi = ".$ilDB->quote($survey_id, "integer");
551  if($finished_ids)
552  {
553  $sql .= " AND ".$ilDB->in("svy_finished.finished_id", $finished_ids, "", "integer");
554  }
555 
556  $mcmr_result = $ilDB->query($sql);
557  $found = array();
558  while ($row = $ilDB->fetchAssoc($mcmr_result))
559  {
560  $found[$row["question_fi"] . "_" . $row["active_fi"]] = 1;
561  }
562  $result_array["USERS_ANSWERED"] = count($found);
563  $result_array["USERS_SKIPPED"] = $nr_of_users - count($found);
564  $numrows = count($found);
565 
566  $result_array["MEDIAN"] = "";
567  $result_array["ARITHMETIC_MEAN"] = "";
568  if(sizeof($cumulated))
569  {
570  $prefix = "";
571  if (strcmp(key($cumulated), "") != 0)
572  {
573  $prefix = (key($cumulated)+1) . " - ";
574  }
575  $category = $this->categories->getCategoryForScale(key($cumulated)+1);
576  $result_array["MODE"] = $prefix . $category->title;
577  $result_array["MODE_VALUE"] = key($cumulated)+1;
578  $result_array["MODE_NR_OF_SELECTIONS"] = $cumulated[key($cumulated)];
579  }
580  $result_array["QUESTION_TYPE"] = "SurveyMultipleChoiceQuestion";
581  $maxvalues = 0;
582  for ($key = 0; $key < $this->categories->getCategoryCount(); $key++)
583  {
584  $cat = $this->categories->getCategory($key);
585  $maxvalues += $cumulated[$cat->scale-1];
586  }
587  for ($key = 0; $key < $this->categories->getCategoryCount(); $key++)
588  {
589  $cat = $this->categories->getCategory($key);
590  $percentage = 0;
591  if ($numrows > 0)
592  {
593  if ($maxvalues > 0)
594  {
595  $percentage = ($maxvalues > 0) ? (float)((int)$cumulated[$cat->scale-1]/$maxvalues) : 0;
596  }
597  }
598  if(isset($textanswers[$cat->scale-1]))
599  {
600  // #12138
601  $result_array["textanswers"][$key] = $textanswers[$cat->scale-1];
602  }
603  $result_array["variables"][$key] = array("title" => $cat->title, "selected" => (int)$cumulated[$cat->scale-1], "percentage" => $percentage);
604  }
605  return $result_array;
606  }
607 
617  function setExportDetailsXLS(&$workbook, &$format_title, &$format_bold, &$eval_data, $export_label)
618  {
619  include_once ("./Services/Excel/classes/class.ilExcelUtils.php");
620  $worksheet =& $workbook->addWorksheet();
621  $rowcounter = 0;
622  switch ($export_label)
623  {
624  case 'label_only':
625  $worksheet->writeString(0, 0, ilExcelUtils::_convert_text($this->lng->txt("label")), $format_bold);
626  $worksheet->writeString(0, 1, ilExcelUtils::_convert_text($this->label));
627  break;
628  case 'title_only':
629  $worksheet->writeString(0, 0, ilExcelUtils::_convert_text($this->lng->txt("title")), $format_bold);
630  $worksheet->writeString(0, 1, ilExcelUtils::_convert_text($this->getTitle()));
631  break;
632  default:
633  $worksheet->writeString(0, 0, ilExcelUtils::_convert_text($this->lng->txt("title")), $format_bold);
634  $worksheet->writeString(0, 1, ilExcelUtils::_convert_text($this->getTitle()));
635  $rowcounter++;
636  $worksheet->writeString($rowcounter, 0, ilExcelUtils::_convert_text($this->lng->txt("label")), $format_bold);
637  $worksheet->writeString($rowcounter, 1, ilExcelUtils::_convert_text($this->label));
638  break;
639  }
640  $rowcounter++;
641  $worksheet->writeString($rowcounter, 0, ilExcelUtils::_convert_text($this->lng->txt("question")), $format_bold);
642  $worksheet->writeString($rowcounter, 1, ilExcelUtils::_convert_text($this->getQuestiontext()));
643  $rowcounter++;
644  $worksheet->writeString($rowcounter, 0, ilExcelUtils::_convert_text($this->lng->txt("question_type")), $format_bold);
645  $worksheet->writeString($rowcounter, 1, ilExcelUtils::_convert_text($this->lng->txt($this->getQuestionType())));
646  $rowcounter++;
647  $worksheet->writeString($rowcounter, 0, ilExcelUtils::_convert_text($this->lng->txt("users_answered")), $format_bold);
648  $worksheet->write($rowcounter, 1, $eval_data["USERS_ANSWERED"]);
649  $rowcounter++;
650  $worksheet->writeString($rowcounter, 0, ilExcelUtils::_convert_text($this->lng->txt("users_skipped")), $format_bold);
651  $worksheet->write($rowcounter, 1, $eval_data["USERS_SKIPPED"]);
652  $rowcounter++;
653 
654  $worksheet->write($rowcounter, 0, ilExcelUtils::_convert_text($this->lng->txt("mode")), $format_bold);
655  $worksheet->write($rowcounter++, 1, ilExcelUtils::_convert_text($eval_data["MODE_VALUE"]));
656  $worksheet->write($rowcounter, 0, ilExcelUtils::_convert_text($this->lng->txt("mode_text")), $format_bold);
657  $worksheet->write($rowcounter++, 1, ilExcelUtils::_convert_text($eval_data["MODE"]));
658  $worksheet->write($rowcounter, 0, ilExcelUtils::_convert_text($this->lng->txt("mode_nr_of_selections")), $format_bold);
659  $worksheet->write($rowcounter++, 1, ilExcelUtils::_convert_text($eval_data["MODE_NR_OF_SELECTIONS"]));
660  $worksheet->write($rowcounter, 0, ilExcelUtils::_convert_text($this->lng->txt("categories")), $format_bold);
661  $worksheet->write($rowcounter, 1, ilExcelUtils::_convert_text($this->lng->txt("title")), $format_title);
662  $worksheet->write($rowcounter, 2, ilExcelUtils::_convert_text($this->lng->txt("value")), $format_title);
663  $worksheet->write($rowcounter, 3, ilExcelUtils::_convert_text($this->lng->txt("category_nr_selected")), $format_title);
664  $worksheet->write($rowcounter++, 4, ilExcelUtils::_convert_text($this->lng->txt("percentage_of_selections")), $format_title);
665  foreach ($eval_data["variables"] as $key => $value)
666  {
667  $worksheet->write($rowcounter, 1, ilExcelUtils::_convert_text($value["title"]));
668  $category = $this->categories->getCategory($key);
669  $worksheet->write($rowcounter, 2, $category->scale);
670  $worksheet->write($rowcounter, 3, ilExcelUtils::_convert_text($value["selected"]));
671  $worksheet->write($rowcounter++, 4, ilExcelUtils::_convert_text($value["percentage"]), $format_percent);
672  }
673 
674  // add text answers to detailed results
675  if (is_array($eval_data["textanswers"]))
676  {
677  $worksheet->write($rowcounter, 0, ilExcelUtils::_convert_text($this->lng->txt("freetext_answers")), $format_bold);
678  $worksheet->write($rowcounter, 1, ilExcelUtils::_convert_text($this->lng->txt("title")), $format_title);
679  $worksheet->write($rowcounter++, 2, ilExcelUtils::_convert_text($this->lng->txt("answer")), $format_title);
680 
681  foreach ($eval_data["textanswers"] as $key => $answers)
682  {
683  $title = $eval_data["variables"][$key]["title"];
684  foreach ($answers as $answer)
685  {
686  $worksheet->write($rowcounter, 1, ilExcelUtils::_convert_text($title));
687  $worksheet->write($rowcounter++, 2, ilExcelUtils::_convert_text($answer));
688  }
689  }
690  }
691  }
692 
699  function addUserSpecificResultsExportTitles(&$a_array, $a_use_label = false, $a_substitute = true)
700  {
701  parent::addUserSpecificResultsExportTitles($a_array, $a_use_label, $a_substitute);
702 
703  for ($index = 0; $index < $this->categories->getCategoryCount(); $index++)
704  {
705  $category = $this->categories->getCategory($index);
706  $title = $category->title;
707 
708  if(!$a_use_label || $a_substitute)
709  {
710  array_push($a_array, $title);
711  }
712  else
713  {
714  array_push($a_array, "");
715  }
716 
717  // optionally add headers for text answers
718  if ($category->other)
719  {
720  if(!$a_use_label || $a_substitute)
721  {
722  array_push($a_array, $title . " - ". $this->lng->txt("other"));
723  }
724  else
725  {
726  array_push($a_array, "");
727  }
728  }
729  }
730  }
731 
739  function addUserSpecificResultsData(&$a_array, &$resultset)
740  {
741  if (count($resultset["answers"][$this->getId()]))
742  {
743  array_push($a_array, "");
744  for ($index = 0; $index < $this->categories->getCategoryCount(); $index++)
745  {
746  $category = $this->categories->getCategory($index);
747  $incoming_value = $category->scale ? $category->scale-1 : $index;
748 
749  $found = 0;
750  $textanswer = "";
751  foreach ($resultset["answers"][$this->getId()] as $answerdata)
752  {
753  if (strcmp($incoming_value, $answerdata["value"]) == 0)
754  {
755  $found = $answerdata["value"]+1;
756  $textanswer = $answerdata["textanswer"];
757  }
758  }
759  if ($found)
760  {
761  array_push($a_array, $found);
762  }
763  else
764  {
765  array_push($a_array, "0");
766  }
767  if ($category->other)
768  {
769  array_push($a_array, $textanswer);
770  }
771  }
772  }
773  else
774  {
775  array_push($a_array, $this->getSkippedValue());
776  for ($index = 0; $index < $this->categories->getCategoryCount(); $index++)
777  {
778  array_push($a_array, "");
779 
780  // add empty text answers for skipped question
781  $category = $this->categories->getCategory($index);
782  if ($category->other)
783  {
784  array_push($a_array, "");
785  }
786  }
787  }
788  }
789 
797  function &getUserAnswers($survey_id, $finished_ids)
798  {
799  global $ilDB;
800 
801  $answers = array();
802 
803  $sql = "SELECT svy_answer.* FROM svy_answer".
804  " JOIN svy_finished ON (svy_finished.finished_id = svy_answer.active_fi)".
805  " WHERE svy_answer.question_fi = ".$ilDB->quote($this->getId(), "integer").
806  " AND svy_finished.survey_fi = ".$ilDB->quote($survey_id, "integer");
807  if($finished_ids)
808  {
809  $sql .= " AND ".$ilDB->in("svy_finished.finished_id", $finished_ids, "", "integer");
810  }
811 
812  $result = $ilDB->query($sql);
813  while ($row = $ilDB->fetchAssoc($result))
814  {
815  $category = $this->categories->getCategoryForScale($row["value"]+1);
816  if (!is_array($answers[$row["active_fi"]]))
817  {
818  $answers[$row["active_fi"]] = array();
819  }
820  $title = $row["value"] + 1 . " - " . $category->title;
821  if ($category->other) $title .= ": " . $row["textanswer"];
822  $catindex = $this->categories->getIndex($category);
823  if ($catindex !== null)
824  {
825  $answers[$row["active_fi"]][$catindex] = $title;
826  }
827  else
828  {
829  array_push($answers[$row["active_fi"]], $title);
830  }
831  ksort($answers[$row["active_fi"]], SORT_NUMERIC);
832  }
833  return $answers;
834  }
835 
844  function importAdditionalMetadata($a_meta)
845  {
846  foreach ($a_meta as $key => $value)
847  {
848  switch ($value["label"])
849  {
850  case "orientation":
851  $this->setOrientation($value["entry"]);
852  break;
853  case "use_min_answers":
854  $this->use_min_answers = $value["entry"];
855  break;
856  case "nr_min_answers":
857  $this->nr_min_answers = $value["entry"];
858  break;
859  case "nr_max_answers":
860  $this->nr_max_answers = $value["entry"];
861  break;
862  }
863  }
864  }
865 
872  function importResponses($a_data)
873  {
874  foreach ($a_data as $id => $data)
875  {
876  $categorytext = "";
877  foreach ($data["material"] as $material)
878  {
879  $categorytext .= $material["text"];
880  }
881  $this->categories->addCategory(
882  $categorytext,
883  strlen($data['other']) ? $data['other'] : 0,
884  strlen($data['neutral']) ? $data['neutral'] : 0,
885  strlen($data['label']) ? $data['label'] : null,
886  strlen($data['scale']) ? $data['scale'] : null
887  );
888  }
889  }
890 
898  {
899  return TRUE;
900  }
901 
909  {
910  return array("=", "<>");
911  }
912 
918  public function getPreconditionOptions()
919  {
920  global $lng;
921 
922  $options = array();
923  for ($i = 0; $i < $this->categories->getCategoryCount(); $i++)
924  {
925  $category = $this->categories->getCategory($i);
926  $options[$category->scale-1] = $category->scale . " - " . $category->title;
927  }
928  return $options;
929  }
930 
937  public function getPreconditionSelectValue($default = "", $title, $variable)
938  {
939  include_once "./Services/Form/classes/class.ilSelectInputGUI.php";
940  $step3 = new ilSelectInputGUI($title, $variable);
941  $options = $this->getPreconditionOptions();
942  $step3->setOptions($options);
943  $step3->setValue($default);
944  return $step3;
945  }
946 
954  function getPreconditionValueOutput($value)
955  {
956  // #18136
957  $category = $this->categories->getCategoryForScale($value+1);
958 
959  // #17895 - see getPreconditionOptions()
960  return $category->scale .
961  " - " .
962  ((strlen($category->title)) ? $category->title : $this->lng->txt('other_answer'));
963  }
964 
965  public function getCategories()
966  {
967  return $this->categories;
968  }
969 
970 }
971 ?>