ILIAS  Release_4_0_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.SurveySingleChoiceQuestion.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 
59  $title = "",
60  $description = "",
61  $author = "",
62  $questiontext = "",
63  $owner = -1,
64  $orientation = 1
65  )
66  {
68  include_once "./Modules/SurveyQuestionPool/classes/class.SurveyCategories.php";
69  $this->orientation = $orientation;
70  $this->categories = new SurveyCategories();
71  }
72 
80  function &getCategoriesForPhrase($phrase_id)
81  {
82  global $ilDB;
83  $categories = array();
84  $result = $ilDB->queryF("SELECT svy_category.* FROM svy_category, svy_phrase_cat WHERE svy_phrase_cat.category_fi = svy_category.category_id AND svy_phrase_cat.phrase_fi = %s ORDER BY svy_phrase_cat.sequence",
85  array('integer'),
86  array($phrase_id)
87  );
88  while ($row = $ilDB->fetchAssoc($result))
89  {
90  if (($row["defaultvalue"] == 1) and ($row["owner_fi"] == 0))
91  {
92  $categories[$row["category_id"]] = $this->lng->txt($row["title"]);
93  }
94  else
95  {
96  $categories[$row["category_id"]] = $row["title"];
97  }
98  }
99  return $categories;
100  }
101 
108  function addPhrase($phrase_id)
109  {
110  global $ilUser;
111  global $ilDB;
112 
113  $result = $ilDB->queryF("SELECT svy_category.* FROM svy_category, svy_phrase_cat WHERE svy_phrase_cat.category_fi = svy_category.category_id AND svy_phrase_cat.phrase_fi = %s AND (svy_category.owner_fi = 0 OR svy_category.owner_fi = %s) ORDER BY svy_phrase_cat.sequence",
114  array('integer', 'integer'),
115  array($phrase_id, $ilUser->getId())
116  );
117  while ($row = $ilDB->fetchAssoc($result))
118  {
119  if (($row["defaultvalue"] == 1) and ($row["owner_fi"] == 0))
120  {
121  $this->categories->addCategory($this->lng->txt($row["title"]));
122  }
123  else
124  {
125  $this->categories->addCategory($row["title"]);
126  }
127  }
128  }
129 
138  {
139  global $ilDB;
140 
141  $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",
142  array('integer'),
143  array($id)
144  );
145  if ($result->numRows() == 1)
146  {
147  return $ilDB->fetchAssoc($result);
148  }
149  else
150  {
151  return array();
152  }
153  }
154 
161  function loadFromDb($id)
162  {
163  global $ilDB;
164 
165  $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",
166  array('integer'),
167  array($id)
168  );
169  if ($result->numRows() == 1)
170  {
171  $data = $ilDB->fetchAssoc($result);
172  $this->setId($data["question_id"]);
173  $this->setTitle($data["title"]);
174  $this->setDescription($data["description"]);
175  $this->setObjId($data["obj_fi"]);
176  $this->setAuthor($data["author"]);
177  $this->setOwner($data["owner_fi"]);
178  include_once("./Services/RTE/classes/class.ilRTE.php");
179  $this->setQuestiontext(ilRTE::_replaceMediaObjectImageSrc($data["questiontext"], 1));
180  $this->setObligatory($data["obligatory"]);
181  $this->setComplete($data["complete"]);
182  $this->setOriginalId($data["original_id"]);
183  $this->setOrientation($data["orientation"]);
184 
185  $this->categories->flushCategories();
186  $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",
187  array('integer'),
188  array($id)
189  );
190  if ($result->numRows() > 0)
191  {
192  while ($data = $ilDB->fetchAssoc($result))
193  {
194  $this->categories->addCategory($data["title"]);
195  }
196  }
197  }
199  }
200 
207  function isComplete()
208  {
209  if ($this->title and $this->author and $this->questiontext and $this->categories->getCategoryCount())
210  {
211  return 1;
212  }
213  else
214  {
215  return 0;
216  }
217  }
218 
224  function saveToDb($original_id = "")
225  {
226  global $ilDB;
227 
228  $affectedRows = parent::saveToDb($original_id);
229  if ($affectedRows == 1)
230  {
231  $affectedRows = $ilDB->manipulateF("DELETE FROM " . $this->getAdditionalTableName() . " WHERE question_fi = %s",
232  array('integer'),
233  array($this->getId())
234  );
235  $affectedRows = $ilDB->manipulateF("INSERT INTO " . $this->getAdditionalTableName() . " (question_fi, orientation) VALUES (%s, %s)",
236  array('integer', 'text'),
237  array($this->getId(), $this->getOrientation())
238  );
239 
240  $this->saveMaterial();
241  $this->saveCategoriesToDb();
242  }
243  }
244 
246  {
247  global $ilDB;
248 
249  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_variable WHERE question_fi = %s",
250  array('integer'),
251  array($this->getId())
252  );
253 
254  for ($i = 0; $i < $this->categories->getCategoryCount(); $i++)
255  {
256  $category_id = $this->saveCategoryToDb($this->categories->getCategory($i));
257  $next_id = $ilDB->nextId('svy_variable');
258  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_variable (variable_id, category_fi, question_fi, value1, sequence, tstamp) VALUES (%s, %s, %s, %s, %s, %s)",
259  array('integer','integer','integer','float','integer','integer'),
260  array($next_id, $category_id, $this->getId(), ($i + 1), $i, time())
261  );
262  }
263  $this->saveCompletionStatus();
264  }
265 
272  function toXML($a_include_header = TRUE, $obligatory_state = "")
273  {
274  include_once("./classes/class.ilXmlWriter.php");
275  $a_xml_writer = new ilXmlWriter;
276  $a_xml_writer->xmlHeader();
277  $this->insertXML($a_xml_writer, $a_include_header, $obligatory_state);
278  $xml = $a_xml_writer->xmlDumpMem(FALSE);
279  if (!$a_include_header)
280  {
281  $pos = strpos($xml, "?>");
282  $xml = substr($xml, $pos + 2);
283  }
284  return $xml;
285  }
286 
295  function insertXML(&$a_xml_writer, $a_include_header = TRUE, $obligatory_state = "")
296  {
297  $attrs = array(
298  "id" => $this->getId(),
299  "title" => $this->getTitle(),
300  "type" => $this->getQuestiontype(),
301  "obligatory" => $this->getObligatory()
302  );
303  $a_xml_writer->xmlStartTag("question", $attrs);
304 
305  $a_xml_writer->xmlElement("description", NULL, $this->getDescription());
306  $a_xml_writer->xmlElement("author", NULL, $this->getAuthor());
307  $a_xml_writer->xmlStartTag("questiontext");
308  $this->addMaterialTag($a_xml_writer, $this->getQuestiontext());
309  $a_xml_writer->xmlEndTag("questiontext");
310 
311  $a_xml_writer->xmlStartTag("responses");
312 
313  for ($i = 0; $i < $this->categories->getCategoryCount(); $i++)
314  {
315  $attrs = array(
316  "id" => $i
317  );
318  $a_xml_writer->xmlStartTag("response_single", $attrs);
319  $this->addMaterialTag($a_xml_writer, $this->categories->getCategory($i));
320  $a_xml_writer->xmlEndTag("response_single");
321  }
322 
323  $a_xml_writer->xmlEndTag("responses");
324 
325  if (count($this->material))
326  {
327  if (preg_match("/il_(\d*?)_(\w+)_(\d+)/", $this->material["internal_link"], $matches))
328  {
329  $attrs = array(
330  "label" => $this->material["title"]
331  );
332  $a_xml_writer->xmlStartTag("material", $attrs);
333  $intlink = "il_" . IL_INST_ID . "_" . $matches[2] . "_" . $matches[3];
334  if (strcmp($matches[1], "") != 0)
335  {
336  $intlink = $this->material["internal_link"];
337  }
338  $a_xml_writer->xmlElement("mattext", NULL, $intlink);
339  $a_xml_writer->xmlEndTag("material");
340  }
341  }
342 
343  $a_xml_writer->xmlStartTag("metadata");
344  $a_xml_writer->xmlStartTag("metadatafield");
345  $a_xml_writer->xmlElement("fieldlabel", NULL, "orientation");
346  $a_xml_writer->xmlElement("fieldentry", NULL, $this->getOrientation());
347  $a_xml_writer->xmlEndTag("metadatafield");
348  $a_xml_writer->xmlEndTag("metadata");
349 
350  $a_xml_writer->xmlEndTag("question");
351  }
352 
361 function importAdditionalMetadata($a_meta)
362 {
363  foreach ($a_meta as $key => $value)
364  {
365  switch ($value["label"])
366  {
367  case "orientation":
368  $this->setOrientation($value["entry"]);
369  break;
370  }
371  }
372 }
373 
381  function addStandardNumbers($lower_limit, $upper_limit)
382  {
383  for ($i = $lower_limit; $i <= $upper_limit; $i++)
384  {
385  $this->categories->addCategory($i);
386  }
387  }
388 
396  function savePhrase($phrases, $title)
397  {
398  global $ilUser;
399  global $ilDB;
400 
401  $next_id = $ilDB->nextId('svy_phrase');
402  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_phrase (phrase_id, title, defaultvalue, owner_fi, tstamp) VALUES (%s, %s, %s, %s, %s)",
403  array('integer','text','text','integer','integer'),
404  array($next_id, $title, 1, $ilUser->getId(), time())
405  );
406  $phrase_id = $next_id;
407 
408  $counter = 1;
409  foreach ($phrases as $category)
410  {
411  $next_id = $ilDB->nextId('svy_category');
412  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_category (category_id, title, defaultvalue, owner_fi, tstamp) VALUES (%s, %s, %s, %s, %s)",
413  array('integer','text','text','integer','integer'),
414  array($next_id, $category, 1, $ilUser->getId(), time())
415  );
416  $category_id = $next_id;
417  $next_id = $ilDB->nextId('svy_phrase_cat');
418  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_phrase_cat (phrase_category_id, phrase_fi, category_fi, sequence) VALUES (%s, %s, %s, %s)",
419  array('integer', 'integer', 'integer','integer'),
420  array($next_id, $phrase_id, $category_id, $counter)
421  );
422  $counter++;
423  }
424  }
425 
432  function getQuestionType()
433  {
434  return "SurveySingleChoiceQuestion";
435  }
436 
444  {
445  return "svy_qst_sc";
446  }
447 
454  function &getWorkingDataFromUserInput($post_data)
455  {
456  $entered_value = $post_data[$this->getId() . "_value"];
457  $data = array();
458  if (strlen($entered_value))
459  {
460  array_push($data, array("value" => $entered_value));
461  }
462  return $data;
463  }
464 
474  function checkUserInput($post_data, $survey_id)
475  {
476  $entered_value = $post_data[$this->getId() . "_value"];
477 
478  if ((!$this->getObligatory($survey_id)) && (strlen($entered_value) == 0)) return "";
479 
480  if (strlen($entered_value) == 0) return $this->lng->txt("question_not_checked");
481 
482  return "";
483  }
484 
490  public function saveRandomData($active_id)
491  {
492  global $ilDB;
493  // single response
494  $category = rand(0, $this->categories->getCategoryCount()-1);
495  $next_id = $ilDB->nextId('svy_answer');
496  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_answer (answer_id, question_fi, active_fi, value, textanswer, tstamp) VALUES (%s, %s, %s, %s, %s, %s)",
497  array('integer','integer','integer','float','text','integer'),
498  array($next_id, $this->getId(), $active_id, $category, NULL, time())
499  );
500  }
501 
502  function saveUserInput($post_data, $active_id)
503  {
504  global $ilDB;
505 
506  $entered_value = $post_data[$this->getId() . "_value"];
507  if (strlen($entered_value) == 0) return;
508  $next_id = $ilDB->nextId('svy_answer');
509  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_answer (answer_id, question_fi, active_fi, value, textanswer, tstamp) VALUES (%s, %s, %s, %s, %s, %s)",
510  array('integer','integer','integer','float','text','integer'),
511  array($next_id, $this->getId(), $active_id, (strlen($entered_value)) ? $entered_value : NULL, NULL, time())
512  );
513  }
514 
515  function &getCumulatedResults($survey_id, $nr_of_users)
516  {
517  global $ilDB;
518 
519  $question_id = $this->getId();
520 
521  $result_array = array();
522  $cumulated = array();
523 
524  $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",
525  array('integer', 'integer'),
526  array($question_id, $survey_id)
527  );
528 
529  while ($row = $ilDB->fetchAssoc($result))
530  {
531  $cumulated[$row["value"]]++;
532  }
533  asort($cumulated, SORT_NUMERIC);
534  end($cumulated);
535  $numrows = $result->numRows();
536  $result_array["USERS_ANSWERED"] = $result->numRows();
537  $result_array["USERS_SKIPPED"] = $nr_of_users - $result->numRows();
538 
539  $prefix = "";
540  if (strcmp(key($cumulated), "") != 0)
541  {
542  $prefix = (key($cumulated)+1) . " - ";
543  }
544  $result_array["MODE"] = $prefix . $this->categories->getCategory(key($cumulated));
545  $result_array["MODE_VALUE"] = key($cumulated)+1;
546  $result_array["MODE_NR_OF_SELECTIONS"] = $cumulated[key($cumulated)];
547  for ($key = 0; $key < $this->categories->getCategoryCount(); $key++)
548  {
549  $percentage = 0;
550  if ($numrows > 0)
551  {
552  $percentage = (float)((int)$cumulated[$key]/$numrows);
553  }
554  $result_array["variables"][$key] = array("title" => $this->categories->getCategory($key), "selected" => (int)$cumulated[$key], "percentage" => $percentage);
555  }
556  ksort($cumulated, SORT_NUMERIC);
557  $median = array();
558  $total = 0;
559  foreach ($cumulated as $value => $key)
560  {
561  $total += $key;
562  for ($i = 0; $i < $key; $i++)
563  {
564  array_push($median, $value+1);
565  }
566  }
567  if ($total > 0)
568  {
569  if (($total % 2) == 0)
570  {
571  $median_value = 0.5 * ($median[($total/2)-1] + $median[($total/2)]);
572  if (round($median_value) != $median_value)
573  {
574  $median_value = $median_value . "<br />" . "(" . $this->lng->txt("median_between") . " " . (floor($median_value)) . "-" . $this->categories->getCategory((int)floor($median_value)-1) . " " . $this->lng->txt("and") . " " . (ceil($median_value)) . "-" . $this->categories->getCategory((int)ceil($median_value)-1) . ")";
575  }
576  }
577  else
578  {
579  $median_value = $median[(($total+1)/2)-1];
580  }
581  }
582  else
583  {
584  $median_value = "";
585  }
586  $result_array["ARITHMETIC_MEAN"] = "";
587  $result_array["MEDIAN"] = $median_value;
588  $result_array["QUESTION_TYPE"] = "SurveySingleChoiceQuestion";
589  return $result_array;
590  }
591 
601  function setExportDetailsXLS(&$workbook, &$format_title, &$format_bold, &$eval_data)
602  {
603  include_once ("./Services/Excel/classes/class.ilExcelUtils.php");
604  $worksheet =& $workbook->addWorksheet();
605  $worksheet->writeString(0, 0, ilExcelUtils::_convert_text($this->lng->txt("title")), $format_bold);
606  $worksheet->writeString(0, 1, ilExcelUtils::_convert_text($this->getTitle()));
607  $worksheet->writeString(1, 0, ilExcelUtils::_convert_text($this->lng->txt("question")), $format_bold);
608  $worksheet->writeString(1, 1, ilExcelUtils::_convert_text($this->getQuestiontext()));
609  $worksheet->writeString(2, 0, ilExcelUtils::_convert_text($this->lng->txt("question_type")), $format_bold);
610  $worksheet->writeString(2, 1, ilExcelUtils::_convert_text($this->lng->txt($this->getQuestionType())));
611  $worksheet->writeString(3, 0, ilExcelUtils::_convert_text($this->lng->txt("users_answered")), $format_bold);
612  $worksheet->write(3, 1, $eval_data["USERS_ANSWERED"]);
613  $worksheet->writeString(4, 0, ilExcelUtils::_convert_text($this->lng->txt("users_skipped")), $format_bold);
614  $worksheet->write(4, 1, $eval_data["USERS_SKIPPED"]);
615  $rowcounter = 5;
616 
617  preg_match("/(.*?)\s+-\s+(.*)/", $eval_data["MODE"], $matches);
618  $worksheet->write($rowcounter, 0, ilExcelUtils::_convert_text($this->lng->txt("mode")), $format_bold);
619  $worksheet->write($rowcounter++, 1, ilExcelUtils::_convert_text($matches[1]));
620  $worksheet->write($rowcounter, 0, ilExcelUtils::_convert_text($this->lng->txt("mode_text")), $format_bold);
621  $worksheet->write($rowcounter++, 1, ilExcelUtils::_convert_text($matches[2]));
622  $worksheet->write($rowcounter, 0, ilExcelUtils::_convert_text($this->lng->txt("mode_nr_of_selections")), $format_bold);
623  $worksheet->write($rowcounter++, 1, ilExcelUtils::_convert_text($eval_data["MODE_NR_OF_SELECTIONS"]));
624  $worksheet->write($rowcounter, 0, ilExcelUtils::_convert_text($this->lng->txt("median")), $format_bold);
625  $worksheet->write($rowcounter++, 1, ilExcelUtils::_convert_text(str_replace("<br />", " ", $eval_data["MEDIAN"])));
626  $worksheet->write($rowcounter, 0, ilExcelUtils::_convert_text($this->lng->txt("categories")), $format_bold);
627  $worksheet->write($rowcounter, 1, ilExcelUtils::_convert_text($this->lng->txt("title")), $format_title);
628  $worksheet->write($rowcounter, 2, ilExcelUtils::_convert_text($this->lng->txt("value")), $format_title);
629  $worksheet->write($rowcounter, 3, ilExcelUtils::_convert_text($this->lng->txt("category_nr_selected")), $format_title);
630  $worksheet->write($rowcounter++, 4, ilExcelUtils::_convert_text($this->lng->txt("percentage_of_selections")), $format_title);
631 
632  foreach ($eval_data["variables"] as $key => $value)
633  {
634  $worksheet->write($rowcounter, 1, ilExcelUtils::_convert_text($value["title"]));
635  $worksheet->write($rowcounter, 2, $key+1);
636  $worksheet->write($rowcounter, 3, ilExcelUtils::_convert_text($value["selected"]));
637  $worksheet->write($rowcounter++, 4, ilExcelUtils::_convert_text($value["percentage"]), $format_percent);
638  }
639  }
640 
648  function addUserSpecificResultsData(&$a_array, &$resultset)
649  {
650  if (count($resultset["answers"][$this->getId()]))
651  {
652  foreach ($resultset["answers"][$this->getId()] as $key => $answer)
653  {
654  array_push($a_array, $answer["value"]+1);
655  }
656  }
657  else
658  {
659  array_push($a_array, $this->lng->txt("skipped"));
660  }
661  }
662 
671  {
672  global $ilDB;
673 
674  $answers = array();
675 
676  $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",
677  array('integer','integer'),
678  array($survey_id, $this->getId())
679  );
680  while ($row = $ilDB->fetchAssoc($result))
681  {
682  $category = $this->categories->getCategory($row["value"]);
683  $answers[$row["active_fi"]] = $row["value"] + 1 . " - " . $category;
684  }
685  return $answers;
686  }
687 
694  function importResponses($a_data)
695  {
696  foreach ($a_data as $id => $data)
697  {
698  $categorytext = "";
699  foreach ($data["material"] as $material)
700  {
701  $categorytext .= $material["text"];
702  }
703  $this->categories->addCategory($categorytext);
704  }
705  }
706 
714  {
715  return TRUE;
716  }
717 
725  {
726  return array("<", "<=", "=", "<>", ">=", ">");
727  }
728 
735  function getPreconditionSelectValue($default = "")
736  {
737  global $lng;
738 
739  include_once "./classes/class.ilTemplate.php";
740  $template = new ilTemplate("tpl.il_svy_svy_precondition_select_value_combobox.html", TRUE, TRUE, "Modules/Survey");
741  for ($i = 0; $i < $this->categories->getCategoryCount(); $i++)
742  {
743  $template->setCurrentBlock("option_v");
744  $template->setVariable("OPTION_VALUE", $i);
745  $template->setVariable("OPTION_TEXT", ($i+1) . " - " . $this->categories->getCategory($i));
746  if ($i == $default)
747  {
748  $template->setVariable("OPTION_CHECKED", " selected=\"selected\"");
749  }
750  $template->parseCurrentBlock();
751  }
752  $template->setVariable("SELECT_VALUE", $lng->txt("step") . " 3: " . $lng->txt("select_value"));
753  return $template->get();
754  }
755 
763  function getPreconditionValueOutput($value)
764  {
765  return ($value + 1) . " - " . $this->categories->getCategory($value);
766  }
767 
776  function outChart($survey_id, $type = "")
777  {
778  if (count($this->cumulated) == 0)
779  {
780  include_once "./Modules/Survey/classes/class.ilObjSurvey.php";
782  $this->cumulated =& $this->getCumulatedResults($survey_id, $nr_of_users);
783  }
784 
785  foreach ($this->cumulated["variables"] as $key => $value)
786  {
787  foreach ($value as $key2 => $value2)
788  {
789  $this->cumulated["variables"][$key][$key2] = utf8_decode($value2);
790  }
791  }
792  include_once "./Modules/SurveyQuestionPool/classes/class.SurveyChart.php";
793  $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"]);
794  }
795 
796  public function getCategories()
797  {
798  return $this->categories;
799  }
800 
801 }
802 ?>