ILIAS  Release_4_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 include_once "./Modules/Survey/classes/inc.SurveyConstants.php";
26 
39 {
46 
57  $title = "",
58  $description = "",
59  $author = "",
60  $questiontext = "",
61  $owner = -1,
62  $orientation = 0
63  )
64  {
66  $this->orientation = $orientation;
67  include_once "./Modules/SurveyQuestionPool/classes/class.SurveyCategories.php";
68  $this->categories = new SurveyCategories();
69  }
70 
79  {
80  global $ilDB;
81 
82  $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",
83  array('integer'),
84  array($id)
85  );
86  if ($result->numRows() == 1)
87  {
88  return $ilDB->fetchAssoc($result);
89  }
90  else
91  {
92  return array();
93  }
94  }
95 
102  function loadFromDb($id)
103  {
104  global $ilDB;
105 
106  $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",
107  array('integer'),
108  array($id)
109  );
110  if ($result->numRows() == 1)
111  {
112  $data = $ilDB->fetchAssoc($result);
113  $this->setId($data["question_id"]);
114  $this->setTitle($data["title"]);
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 
126  $this->categories->flushCategories();
127  $result = $ilDB->queryF("SELECT svy_variable.*, svy_category.title FROM svy_variable, svy_category WHERE svy_variable.question_fi = %s AND svy_variable.category_fi = svy_category.category_id ORDER BY sequence ASC",
128  array('integer'),
129  array($id)
130  );
131  if ($result->numRows() > 0)
132  {
133  while ($data = $ilDB->fetchAssoc($result))
134  {
135  $this->categories->addCategory($data["title"]);
136  }
137  }
138  }
140  }
141 
148  function isComplete()
149  {
150  if (strlen($this->title) && strlen($this->author) && strlen($this->questiontext) && $this->categories->getCategoryCount())
151  {
152  return 1;
153  }
154  else
155  {
156  return 0;
157  }
158  }
159 
165  function saveToDb($original_id = "")
166  {
167  global $ilDB;
168 
169  $affectedRows = parent::saveToDb($original_id);
170  if ($affectedRows == 1)
171  {
172  $affectedRows = $ilDB->manipulateF("DELETE FROM " . $this->getAdditionalTableName() . " WHERE question_fi = %s",
173  array('integer'),
174  array($this->getId())
175  );
176  $affectedRows = $ilDB->manipulateF("INSERT INTO " . $this->getAdditionalTableName() . " (question_fi, orientation) VALUES (%s, %s)",
177  array('integer', 'text'),
178  array($this->getId(), $this->getOrientation())
179  );
180 
181  // saving material uris in the database
182  $this->saveMaterial();
183  $this->saveCategoriesToDb();
184  }
185  }
186 
188  {
189  global $ilDB;
190 
191  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_variable WHERE question_fi = %s",
192  array('integer'),
193  array($this->getId())
194  );
195 
196  for ($i = 0; $i < $this->categories->getCategoryCount(); $i++)
197  {
198  $category_id = $this->saveCategoryToDb($this->categories->getCategory($i));
199  $next_id = $ilDB->nextId('svy_variable');
200  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_variable (variable_id, category_fi, question_fi, value1, sequence, tstamp) VALUES (%s, %s, %s, %s, %s, %s)",
201  array('integer','integer','integer','float','integer','integer'),
202  array($next_id, $category_id, $this->getId(), ($i + 1), $i, time())
203  );
204  }
205  $this->saveCompletionStatus();
206  }
207 
214  function toXML($a_include_header = TRUE, $obligatory_state = "")
215  {
216  include_once("./classes/class.ilXmlWriter.php");
217  $a_xml_writer = new ilXmlWriter;
218  $a_xml_writer->xmlHeader();
219  $this->insertXML($a_xml_writer, $a_include_header, $obligatory_state);
220  $xml = $a_xml_writer->xmlDumpMem(FALSE);
221  if (!$a_include_header)
222  {
223  $pos = strpos($xml, "?>");
224  $xml = substr($xml, $pos + 2);
225  }
226  return $xml;
227  }
228 
237  function insertXML(&$a_xml_writer, $a_include_header = TRUE, $obligatory_state = "")
238  {
239  $attrs = array(
240  "id" => $this->getId(),
241  "title" => $this->getTitle(),
242  "type" => $this->getQuestiontype(),
243  "obligatory" => $this->getObligatory()
244  );
245  $a_xml_writer->xmlStartTag("question", $attrs);
246 
247  $a_xml_writer->xmlElement("description", NULL, $this->getDescription());
248  $a_xml_writer->xmlElement("author", NULL, $this->getAuthor());
249  $a_xml_writer->xmlStartTag("questiontext");
250  $this->addMaterialTag($a_xml_writer, $this->getQuestiontext());
251  $a_xml_writer->xmlEndTag("questiontext");
252 
253  $a_xml_writer->xmlStartTag("responses");
254 
255  for ($i = 0; $i < $this->categories->getCategoryCount(); $i++)
256  {
257  $attrs = array(
258  "id" => $i
259  );
260  $a_xml_writer->xmlStartTag("response_multiple", $attrs);
261  $this->addMaterialTag($a_xml_writer, $this->categories->getCategory($i));
262  $a_xml_writer->xmlEndTag("response_multiple");
263  }
264 
265  $a_xml_writer->xmlEndTag("responses");
266 
267  if (count($this->material))
268  {
269  if (preg_match("/il_(\d*?)_(\w+)_(\d+)/", $this->material["internal_link"], $matches))
270  {
271  $attrs = array(
272  "label" => $this->material["title"]
273  );
274  $a_xml_writer->xmlStartTag("material", $attrs);
275  $intlink = "il_" . IL_INST_ID . "_" . $matches[2] . "_" . $matches[3];
276  if (strcmp($matches[1], "") != 0)
277  {
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->xmlEndTag("metadata");
291 
292  $a_xml_writer->xmlEndTag("question");
293  }
294 
301  function getQuestionType()
302  {
303  return "SurveyMultipleChoiceQuestion";
304  }
305 
313  {
314  return "svy_qst_mc";
315  }
316 
323  function &getWorkingDataFromUserInput($post_data)
324  {
325  $entered_value = $post_data[$this->getId() . "_value"];
326  $data = array();
327  if (is_array($entered_value))
328  {
329  foreach ($entered_value as $value)
330  {
331  array_push($data, array("value" => $value));
332  }
333  }
334  return $data;
335  }
336 
346  function checkUserInput($post_data, $survey_id)
347  {
348  // multiple response questions are always non-obligatory
349  $entered_value = $post_data[$this->getId() . "_value"];
350  if (!$this->getObligatory($survey_id)) return "";
351 
352  if (!is_array($entered_value))
353  {
354  return $this->lng->txt("question_mr_not_checked");
355  }
356  return "";
357  }
358 
364  public function saveRandomData($active_id)
365  {
366  global $ilDB;
367  // multiple responses
368  for ($i = 0; $i < $this->categories->getCategoryCount(); $i++)
369  {
370  if (rand(0,1))
371  {
372  $next_id = $ilDB->nextId('svy_answer');
373  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_answer (answer_id, question_fi, active_fi, value, textanswer, tstamp) VALUES (%s, %s, %s, %s, %s, %s)",
374  array('integer','integer','integer','float','text','integer'),
375  array($next_id, $this->getId(), $active_id, $i, NULL, time())
376  );
377  }
378  }
379  }
380 
381  function saveUserInput($post_data, $active_id)
382  {
383  global $ilDB;
384 
385  if (is_array($post_data[$this->getId() . "_value"]))
386  {
387  foreach ($post_data[$this->getId() . "_value"] as $value)
388  {
389  $entered_value = $value;
390  if (strlen($entered_value) > 0)
391  {
392  $next_id = $ilDB->nextId('svy_answer');
393  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_answer (answer_id, question_fi, active_fi, value, textanswer, tstamp) VALUES (%s, %s, %s, %s, %s, %s)",
394  array('integer','integer','integer','float','text','integer'),
395  array($next_id, $this->getId(), $active_id, (strlen($entered_value)) ? $entered_value : NULL, NULL, time())
396  );
397  }
398  }
399  }
400  else
401  {
402  $entered_value = $post_data[$this->getId() . "_value"];
403  if (strlen($entered_value) == 0) return;
404  $next_id = $ilDB->nextId('svy_answer');
405  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_answer (answer_id, question_fi, active_fi, value, textanswer, tstamp) VALUES (%s, %s, %s, %s, %s, %s)",
406  array('integer','integer','integer','float','text','integer'),
407  array($next_id, $this->getId(), $active_id, (strlen($entered_value)) ? $entered_value : NULL, NULL, time())
408  );
409  }
410  }
411 
412  function &getCumulatedResults($survey_id, $nr_of_users)
413  {
414  global $ilDB;
415 
416  $question_id = $this->getId();
417 
418  $result_array = array();
419  $cumulated = array();
420 
421  $result = $ilDB->queryF("SELECT svy_answer.* FROM svy_answer, svy_finished WHERE svy_answer.question_fi = %s AND svy_finished.survey_fi = %s AND svy_finished.finished_id = svy_answer.active_fi",
422  array('integer', 'integer'),
423  array($question_id, $survey_id)
424  );
425  $numrows = $result->numRows();
426 
427  // count the answers for every answer value
428  while ($row = $ilDB->fetchAssoc($result))
429  {
430  $cumulated[$row["value"]]++;
431  }
432  asort($cumulated, SORT_NUMERIC);
433  end($cumulated);
434 
435  $mcmr_result = $ilDB->queryF("SELECT svy_answer.answer_id, svy_answer.question_fi, svy_answer.active_fi FROM svy_answer, svy_finished WHERE svy_answer.question_fi = %s AND svy_finished.survey_fi = %s AND svy_finished.finished_id = svy_answer.active_fi",
436  array('integer', 'integer'),
437  array($question_id, $survey_id)
438  );
439  $found = array();
440  while ($row = $ilDB->fetchAssoc($mcmr_result))
441  {
442  $found[$row["question_fi"] . "_" . $row["active_fi"]] = 1;
443  }
444  $result_array["USERS_ANSWERED"] = count($found);
445  $result_array["USERS_SKIPPED"] = $nr_of_users - count($found);
446  $numrows = count($found);
447 
448  $result_array["MEDIAN"] = "";
449  $result_array["ARITHMETIC_MEAN"] = "";
450  $prefix = "";
451  if (strcmp(key($cumulated), "") != 0)
452  {
453  $prefix = (key($cumulated)+1) . " - ";
454  }
455  $result_array["MODE"] = $prefix . $this->categories->getCategory(key($cumulated));
456  $result_array["MODE_VALUE"] = key($cumulated)+1;
457  $result_array["MODE_NR_OF_SELECTIONS"] = $cumulated[key($cumulated)];
458  $result_array["QUESTION_TYPE"] = "SurveyMultipleChoiceQuestion";
459  $maxvalues = 0;
460  for ($key = 0; $key < $this->categories->getCategoryCount(); $key++)
461  {
462  $maxvalues += $cumulated[$key];
463  }
464  for ($key = 0; $key < $this->categories->getCategoryCount(); $key++)
465  {
466  $percentage = 0;
467  if ($numrows > 0)
468  {
469  if ($maxvalues > 0)
470  {
471  $percentage = ($result_array["USERS_ANSWERED"] > 0) ? (float)((int)$cumulated[$key]/$result_array["USERS_ANSWERED"]) : 0;
472  }
473  }
474  $result_array["variables"][$key] = array("title" => $this->categories->getCategory($key), "selected" => (int)$cumulated[$key], "percentage" => $percentage);
475  }
476  return $result_array;
477  }
478 
488  function setExportDetailsXLS(&$workbook, &$format_title, &$format_bold, &$eval_data)
489  {
490  include_once ("./Services/Excel/classes/class.ilExcelUtils.php");
491  $worksheet =& $workbook->addWorksheet();
492  $worksheet->writeString(0, 0, ilExcelUtils::_convert_text($this->lng->txt("title")), $format_bold);
493  $worksheet->writeString(0, 1, ilExcelUtils::_convert_text($this->getTitle()));
494  $worksheet->writeString(1, 0, ilExcelUtils::_convert_text($this->lng->txt("question")), $format_bold);
495  $worksheet->writeString(1, 1, ilExcelUtils::_convert_text($this->getQuestiontext()));
496  $worksheet->writeString(2, 0, ilExcelUtils::_convert_text($this->lng->txt("question_type")), $format_bold);
497  $worksheet->writeString(2, 1, ilExcelUtils::_convert_text($this->lng->txt($this->getQuestionType())));
498  $worksheet->writeString(3, 0, ilExcelUtils::_convert_text($this->lng->txt("users_answered")), $format_bold);
499  $worksheet->write(3, 1, $eval_data["USERS_ANSWERED"]);
500  $worksheet->writeString(4, 0, ilExcelUtils::_convert_text($this->lng->txt("users_skipped")), $format_bold);
501  $worksheet->write(4, 1, $eval_data["USERS_SKIPPED"]);
502  $rowcounter = 5;
503 
504  $worksheet->write($rowcounter, 0, ilExcelUtils::_convert_text($this->lng->txt("mode")), $format_bold);
505  $worksheet->write($rowcounter++, 1, ilExcelUtils::_convert_text($eval_data["MODE_VALUE"]));
506  $worksheet->write($rowcounter, 0, ilExcelUtils::_convert_text($this->lng->txt("mode_text")), $format_bold);
507  $worksheet->write($rowcounter++, 1, ilExcelUtils::_convert_text($eval_data["MODE"]));
508  $worksheet->write($rowcounter, 0, ilExcelUtils::_convert_text($this->lng->txt("mode_nr_of_selections")), $format_bold);
509  $worksheet->write($rowcounter++, 1, ilExcelUtils::_convert_text($eval_data["MODE_NR_OF_SELECTIONS"]));
510  $worksheet->write($rowcounter, 0, ilExcelUtils::_convert_text($this->lng->txt("categories")), $format_bold);
511  $worksheet->write($rowcounter, 1, ilExcelUtils::_convert_text($this->lng->txt("title")), $format_title);
512  $worksheet->write($rowcounter, 2, ilExcelUtils::_convert_text($this->lng->txt("value")), $format_title);
513  $worksheet->write($rowcounter, 3, ilExcelUtils::_convert_text($this->lng->txt("category_nr_selected")), $format_title);
514  $worksheet->write($rowcounter++, 4, ilExcelUtils::_convert_text($this->lng->txt("percentage_of_selections")), $format_title);
515  foreach ($eval_data["variables"] as $key => $value)
516  {
517  $worksheet->write($rowcounter, 1, ilExcelUtils::_convert_text($value["title"]));
518  $worksheet->write($rowcounter, 2, $key+1);
519  $worksheet->write($rowcounter, 3, ilExcelUtils::_convert_text($value["selected"]));
520  $worksheet->write($rowcounter++, 4, ilExcelUtils::_convert_text($value["percentage"]), $format_percent);
521  }
522  }
523 
531  {
533  for ($index = 0; $index < $this->categories->getCategoryCount(); $index++)
534  {
535  $category = $this->categories->getCategory($index);
536  array_push($a_array, ($index+1) . " - $category");
537  }
538  }
539 
547  function addUserSpecificResultsData(&$a_array, &$resultset)
548  {
549  if (count($resultset["answers"][$this->getId()]))
550  {
551  array_push($a_array, "");
552  for ($index = 0; $index < $this->categories->getCategoryCount(); $index++)
553  {
554  $category = $this->categories->getCategory($index);
555  $found = 0;
556  foreach ($resultset["answers"][$this->getId()] as $answerdata)
557  {
558  if (strcmp($index, $answerdata["value"]) == 0)
559  {
560  $found = 1;
561  }
562  }
563  if ($found)
564  {
565  array_push($a_array, "1");
566  }
567  else
568  {
569  array_push($a_array, "0");
570  }
571  }
572  }
573  else
574  {
575  array_push($a_array, $this->lng->txt("skipped"));
576  for ($index = 0; $index < $this->categories->getCategoryCount(); $index++)
577  {
578  array_push($a_array, "");
579  }
580  }
581  }
582 
591  {
592  global $ilDB;
593 
594  $answers = array();
595 
596  $result = $ilDB->queryF("SELECT svy_answer.* FROM svy_answer, svy_finished WHERE svy_finished.survey_fi = %s AND svy_answer.question_fi = %s AND svy_finished.finished_id = svy_answer.active_fi",
597  array('integer', 'integer'),
598  array($survey_id, $this->getId())
599  );
600  while ($row = $ilDB->fetchAssoc($result))
601  {
602  $category = $this->categories->getCategory($row["value"]);
603  if (!is_array($answers[$row["active_fi"]]))
604  {
605  $answers[$row["active_fi"]] = array();
606  }
607  array_push($answers[$row["active_fi"]], $row["value"] + 1 . " - " . $category);
608  }
609  return $answers;
610  }
611 
620  function importAdditionalMetadata($a_meta)
621  {
622  foreach ($a_meta as $key => $value)
623  {
624  switch ($value["label"])
625  {
626  case "orientation":
627  $this->setOrientation($value["entry"]);
628  break;
629  }
630  }
631  }
632 
639  function importResponses($a_data)
640  {
641  foreach ($a_data as $id => $data)
642  {
643  $categorytext = "";
644  foreach ($data["material"] as $material)
645  {
646  $categorytext .= $material["text"];
647  }
648  $this->categories->addCategory($categorytext);
649  }
650  }
651 
659  {
660  return TRUE;
661  }
662 
670  {
671  return array("=", "<>");
672  }
673 
680  function getPreconditionSelectValue($default = "")
681  {
682  global $lng;
683 
684  include_once "./classes/class.ilTemplate.php";
685  $template = new ilTemplate("tpl.il_svy_svy_precondition_select_value_combobox.html", TRUE, TRUE, "Modules/Survey");
686  for ($i = 0; $i < $this->categories->getCategoryCount(); $i++)
687  {
688  $template->setCurrentBlock("option_v");
689  $template->setVariable("OPTION_VALUE", $i);
690  $template->setVariable("OPTION_TEXT", ($i+1) . " - " . $this->categories->getCategory($i));
691  if ($i == $default)
692  {
693  $template->setVariable("OPTION_CHECKED", " selected=\"selected\"");
694  }
695  $template->parseCurrentBlock();
696  }
697  $template->setVariable("SELECT_VALUE", $lng->txt("step") . " 3: " . $lng->txt("select_value"));
698  return $template->get();
699  }
700 
708  function getPreconditionValueOutput($value)
709  {
710  return ($value + 1) . " - " . $this->categories->getCategory($value);
711  }
712 
713 
722  function outChart($survey_id, $type = "")
723  {
724  if (count($this->cumulated) == 0)
725  {
726  include_once "./Modules/Survey/classes/class.ilObjSurvey.php";
728  $this->cumulated =& $this->getCumulatedResults($survey_id, $nr_of_users);
729  }
730 
731  foreach ($this->cumulated["variables"] as $key => $value)
732  {
733  foreach ($value as $key2 => $value2)
734  {
735  $this->cumulated["variables"][$key][$key2] = utf8_decode($value2);
736  }
737  }
738  include_once "./Modules/SurveyQuestionPool/classes/class.SurveyChart.php";
739  $b1 = new SurveyChart("bars",400,250,utf8_decode($this->getTitle()),utf8_decode($this->lng->txt("answers")),utf8_decode($this->lng->txt("users_answered")),$this->cumulated["variables"]);
740  }
741 
742  public function getCategories()
743  {
744  return $this->categories;
745  }
746 }
747 ?>