ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
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 
55  function __construct($title = "", $description = "", $author = "", $questiontext = "", $owner = -1, $orientation = 0)
56  {
57  parent::__construct($title, $description, $author, $questiontext, $owner);
58 
59  $this->orientation = $orientation;
60  include_once "./Modules/SurveyQuestionPool/classes/class.SurveyCategories.php";
61  $this->categories = new SurveyCategories();
62  }
63 
72  {
73  global $ilDB;
74 
75  $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",
76  array('integer'),
77  array($id)
78  );
79  if ($result->numRows() == 1)
80  {
81  return $ilDB->fetchAssoc($result);
82  }
83  else
84  {
85  return array();
86  }
87  }
88 
95  function loadFromDb($id)
96  {
97  global $ilDB;
98 
99  $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",
100  array('integer'),
101  array($id)
102  );
103  if ($result->numRows() == 1)
104  {
105  $data = $ilDB->fetchAssoc($result);
106  $this->setId($data["question_id"]);
107  $this->setTitle($data["title"]);
108  $this->label = $data['label'];
109  $this->setDescription($data["description"]);
110  $this->setObjId($data["obj_fi"]);
111  $this->setAuthor($data["author"]);
112  $this->setOwner($data["owner_fi"]);
113  include_once("./Services/RTE/classes/class.ilRTE.php");
114  $this->setQuestiontext(ilRTE::_replaceMediaObjectImageSrc($data["questiontext"], 1));
115  $this->setObligatory($data["obligatory"]);
116  $this->setComplete($data["complete"]);
117  $this->setOriginalId($data["original_id"]);
118  $this->setOrientation($data["orientation"]);
119  $this->use_min_answers = ($data['use_min_answers']) ? true : false;
120  $this->nr_min_answers = $data['nr_min_answers'];
121  $this->nr_max_answers = $data['nr_max_answers'];
122 
123  $this->categories->flushCategories();
124  $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",
125  array('integer'),
126  array($id)
127  );
128  if ($result->numRows() > 0)
129  {
130  while ($data = $ilDB->fetchAssoc($result))
131  {
132  $this->categories->addCategory($data["title"], $data["other"], $data["neutral"], null, ($data['scale']) ? $data['scale'] : ($data['sequence'] + 1));
133  }
134  }
135  }
136  parent::loadFromDb($id);
137  }
138 
145  function isComplete()
146  {
147  if (
148  strlen($this->getTitle()) &&
149  strlen($this->getAuthor()) &&
150  strlen($this->getQuestiontext()) &&
151  $this->categories->getCategoryCount()
152  )
153  {
154  return 1;
155  }
156  else
157  {
158  return 0;
159  }
160  }
161 
167  function saveToDb($original_id = "")
168  {
169  global $ilDB;
170 
171  $affectedRows = parent::saveToDb($original_id);
172  if ($affectedRows == 1)
173  {
174  $affectedRows = $ilDB->manipulateF("DELETE FROM " . $this->getAdditionalTableName() . " WHERE question_fi = %s",
175  array('integer'),
176  array($this->getId())
177  );
178  $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)",
179  array('integer', 'text', 'integer', 'integer', 'integer'),
180  array(
181  $this->getId(),
182  $this->getOrientation(),
183  ($this->use_min_answers) ? 1 : 0,
184  ($this->nr_min_answers > 0) ? $this->nr_min_answers : null,
185  ($this->nr_max_answers > 0) ? $this->nr_max_answers : null
186  )
187  );
188 
189  // saving material uris in the database
190  $this->saveMaterial();
191  $this->saveCategoriesToDb();
192  }
193  }
194 
196  {
197  global $ilDB;
198 
199  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_variable WHERE question_fi = %s",
200  array('integer'),
201  array($this->getId())
202  );
203 
204  for ($i = 0; $i < $this->categories->getCategoryCount(); $i++)
205  {
206  $cat = $this->categories->getCategory($i);
207  $category_id = $this->saveCategoryToDb($cat->title, $cat->neutral);
208  $next_id = $ilDB->nextId('svy_variable');
209  $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)",
210  array('integer','integer','integer','float','integer','integer', 'integer','integer'),
211  array($next_id, $category_id, $this->getId(), ($i + 1), $cat->other, $i, ($cat->scale > 0) ? $cat->scale : null, time())
212  );
213  }
214  $this->saveCompletionStatus();
215  }
216 
223  function toXML($a_include_header = TRUE, $obligatory_state = "")
224  {
225  include_once("./Services/Xml/classes/class.ilXmlWriter.php");
226  $a_xml_writer = new ilXmlWriter;
227  $a_xml_writer->xmlHeader();
228  $this->insertXML($a_xml_writer, $a_include_header, $obligatory_state);
229  $xml = $a_xml_writer->xmlDumpMem(FALSE);
230  if (!$a_include_header)
231  {
232  $pos = strpos($xml, "?>");
233  $xml = substr($xml, $pos + 2);
234  }
235  return $xml;
236  }
237 
245  function insertXML(&$a_xml_writer, $a_include_header = TRUE)
246  {
247  $attrs = array(
248  "id" => $this->getId(),
249  "title" => $this->getTitle(),
250  "type" => $this->getQuestiontype(),
251  "obligatory" => $this->getObligatory()
252  );
253  $a_xml_writer->xmlStartTag("question", $attrs);
254 
255  $a_xml_writer->xmlElement("description", NULL, $this->getDescription());
256  $a_xml_writer->xmlElement("author", NULL, $this->getAuthor());
257  if (strlen($this->label))
258  {
259  $attrs = array(
260  "label" => $this->label,
261  );
262  }
263  else
264  {
265  $attrs = array();
266  }
267  $a_xml_writer->xmlStartTag("questiontext", $attrs);
268  $this->addMaterialTag($a_xml_writer, $this->getQuestiontext());
269  $a_xml_writer->xmlEndTag("questiontext");
270 
271  $a_xml_writer->xmlStartTag("responses");
272 
273  for ($i = 0; $i < $this->categories->getCategoryCount(); $i++)
274  {
275  $attrs = array(
276  "id" => $i
277  );
278  if (strlen($this->categories->getCategory($i)->other)) $attrs['other'] = $this->categories->getCategory($i)->other;
279  if (strlen($this->categories->getCategory($i)->neutral)) $attrs['neutral'] = $this->categories->getCategory($i)->neutral;
280  if (strlen($this->categories->getCategory($i)->label)) $attrs['label'] = $this->categories->getCategory($i)->label;
281  if (strlen($this->categories->getCategory($i)->scale)) $attrs['scale'] = $this->categories->getCategory($i)->scale;
282  $a_xml_writer->xmlStartTag("response_multiple", $attrs);
283  $this->addMaterialTag($a_xml_writer, $this->categories->getCategory($i)->title);
284  $a_xml_writer->xmlEndTag("response_multiple");
285  }
286 
287  $a_xml_writer->xmlEndTag("responses");
288 
289  if (count($this->material))
290  {
291  if (preg_match("/il_(\d*?)_(\w+)_(\d+)/", $this->material["internal_link"], $matches))
292  {
293  $attrs = array(
294  "label" => $this->material["title"]
295  );
296  $a_xml_writer->xmlStartTag("material", $attrs);
297  $intlink = "il_" . IL_INST_ID . "_" . $matches[2] . "_" . $matches[3];
298  if (strcmp($matches[1], "") != 0)
299  {
300  $intlink = $this->material["internal_link"];
301  }
302  $a_xml_writer->xmlElement("mattext", NULL, $intlink);
303  $a_xml_writer->xmlEndTag("material");
304  }
305  }
306 
307  $a_xml_writer->xmlStartTag("metadata");
308  $a_xml_writer->xmlStartTag("metadatafield");
309  $a_xml_writer->xmlElement("fieldlabel", NULL, "orientation");
310  $a_xml_writer->xmlElement("fieldentry", NULL, $this->getOrientation());
311  $a_xml_writer->xmlEndTag("metadatafield");
312  $a_xml_writer->xmlStartTag("metadatafield");
313  $a_xml_writer->xmlElement("fieldlabel", NULL, "use_min_answers");
314  $a_xml_writer->xmlElement("fieldentry", NULL, $this->use_min_answers);
315  $a_xml_writer->xmlEndTag("metadatafield");
316  $a_xml_writer->xmlStartTag("metadatafield");
317  $a_xml_writer->xmlElement("fieldlabel", NULL, "nr_min_answers");
318  $a_xml_writer->xmlElement("fieldentry", NULL, $this->nr_min_answers);
319  $a_xml_writer->xmlEndTag("metadatafield");
320  $a_xml_writer->xmlStartTag("metadatafield");
321  $a_xml_writer->xmlElement("fieldlabel", NULL, "nr_max_answers");
322  $a_xml_writer->xmlElement("fieldentry", NULL, $this->nr_max_answers);
323  $a_xml_writer->xmlEndTag("metadatafield");
324  $a_xml_writer->xmlEndTag("metadata");
325 
326  $a_xml_writer->xmlEndTag("question");
327  }
328 
335  function getQuestionType()
336  {
337  return "SurveyMultipleChoiceQuestion";
338  }
339 
347  {
348  return "svy_qst_mc";
349  }
350 
357  function &getWorkingDataFromUserInput($post_data)
358  {
359  $entered_value = $post_data[$this->getId() . "_value"];
360  $data = array();
361  if (is_array($entered_value))
362  {
363  foreach ($entered_value as $idx => $value)
364  {
365  array_push($data, array("value" => $value, "textanswer" => $post_data[$this->getId() . '_' . $value . '_other']));
366  }
367  }
368  for ($i = 0; $i < $this->categories->getCategoryCount(); $i++)
369  {
370  $cat = $this->categories->getCategory($i);
371  if ($cat->other)
372  {
373  // #18212
374  if (!is_array($entered_value) || !in_array($i, $entered_value))
375  {
376  if (strlen($post_data[$this->getId() . "_" . $i . "_other"]))
377  {
378  array_push($data, array("value" => $i, "textanswer" => $post_data[$this->getId() . '_' . $i . '_other'], "uncheck" => true));
379  }
380  }
381  }
382  }
383  return $data;
384  }
385 
395  function checkUserInput($post_data, $survey_id)
396  {
397  $entered_value = $post_data[$this->getId() . "_value"];
398  if (!$this->getObligatory($survey_id) && count($entered_value) == 0) return "";
399 
400  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)
401  {
402  return sprintf($this->lng->txt("err_no_exact_answers"), $this->nr_min_answers);
403  }
404  if ($this->use_min_answers && $this->nr_min_answers > 0 && count($entered_value) < $this->nr_min_answers)
405  {
406  return sprintf($this->lng->txt("err_no_min_answers"), $this->nr_min_answers);
407  }
408  if ($this->use_min_answers && $this->nr_max_answers > 0 && count($entered_value) > $this->nr_max_answers)
409  {
410  return sprintf($this->lng->txt("err_no_max_answers"), $this->nr_max_answers);
411  }
412  if (!is_array($entered_value))
413  {
414  return $this->lng->txt("question_mr_not_checked");
415  }
416  for ($i = 0; $i < $this->categories->getCategoryCount(); $i++)
417  {
418  $cat = $this->categories->getCategory($i);
419  if ($cat->other)
420  {
421  if (in_array($i, $entered_value))
422  {
423  if (array_key_exists($this->getId() . "_" . $i . "_other", $post_data) && !strlen($post_data[$this->getId() . "_" . $i . "_other"]))
424  {
425  return $this->lng->txt("question_mr_no_other_answer");
426  }
427  }
428  else
429  {
430  if (strlen($post_data[$this->getId() . "_" . $i . "_other"]))
431  {
432  return $this->lng->txt("question_mr_no_other_answer_checked");
433  }
434  }
435  }
436  }
437  return "";
438  }
439 
440  function saveUserInput($post_data, $active_id, $a_return = false)
441  {
442  global $ilDB;
443 
444  if($a_return)
445  {
446  $return_data = array();
447  }
448  if (is_array($post_data[$this->getId() . "_value"]))
449  {
450  foreach ($post_data[$this->getId() . "_value"] as $entered_value)
451  {
452  if (strlen($entered_value) > 0)
453  {
454  if(!$a_return)
455  {
456  $next_id = $ilDB->nextId('svy_answer');
457 
458  #20216
459  $fields = array();
460  $fields['answer_id'] = array("integer", $next_id);
461  $fields['question_fi'] = array("integer", $this->getId());
462  $fields['active_fi'] = array("integer", $active_id);
463  $fields['value'] = array("float", (strlen($entered_value)) ? $entered_value : NULL);
464  $fields['textanswer'] = array("clob", ($post_data[$this->getId() . "_" . $entered_value . "_other"]) ? $post_data[$this->getId() . "_" . $entered_value . "_other"] : null);
465  $fields['tstamp'] = array("integer", time());
466 
467  $affectedRows = $ilDB->insert("svy_answer", $fields);
468  }
469  else
470  {
471  $return_data[] = array("value"=>$entered_value,
472  "textanswer"=>$post_data[$this->getId() . "_" . $entered_value . "_other"]);
473  }
474  }
475  }
476  }
477  if($a_return)
478  {
479  return $return_data;
480  }
481  }
482 
491  function importAdditionalMetadata($a_meta)
492  {
493  foreach ($a_meta as $key => $value)
494  {
495  switch ($value["label"])
496  {
497  case "orientation":
498  $this->setOrientation($value["entry"]);
499  break;
500  case "use_min_answers":
501  $this->use_min_answers = $value["entry"];
502  break;
503  case "nr_min_answers":
504  $this->nr_min_answers = $value["entry"];
505  break;
506  case "nr_max_answers":
507  $this->nr_max_answers = $value["entry"];
508  break;
509  }
510  }
511  }
512 
519  function importResponses($a_data)
520  {
521  foreach ($a_data as $id => $data)
522  {
523  $categorytext = "";
524  foreach ($data["material"] as $material)
525  {
526  $categorytext .= $material["text"];
527  }
528  $this->categories->addCategory(
529  $categorytext,
530  strlen($data['other']) ? $data['other'] : 0,
531  strlen($data['neutral']) ? $data['neutral'] : 0,
532  strlen($data['label']) ? $data['label'] : null,
533  strlen($data['scale']) ? $data['scale'] : null
534  );
535  }
536  }
537 
545  {
546  return TRUE;
547  }
548 
556  {
557  return array("=", "<>");
558  }
559 
565  public function getPreconditionOptions()
566  {
567  global $lng;
568 
569  $options = array();
570  for ($i = 0; $i < $this->categories->getCategoryCount(); $i++)
571  {
572  $category = $this->categories->getCategory($i);
573  $options[$category->scale-1] = $category->scale . " - " . $category->title;
574  }
575  return $options;
576  }
577 
584  public function getPreconditionSelectValue($default = "", $title, $variable)
585  {
586  include_once "./Services/Form/classes/class.ilSelectInputGUI.php";
587  $step3 = new ilSelectInputGUI($title, $variable);
588  $options = $this->getPreconditionOptions();
589  $step3->setOptions($options);
590  $step3->setValue($default);
591  return $step3;
592  }
593 
601  function getPreconditionValueOutput($value)
602  {
603  // #18136
604  $category = $this->categories->getCategoryForScale($value+1);
605 
606  // #17895 - see getPreconditionOptions()
607  return $category->scale .
608  " - " .
609  ((strlen($category->title)) ? $category->title : $this->lng->txt('other_answer'));
610  }
611 
612  public function getCategories()
613  {
614  return $this->categories;
615  }
616 
617 }
618 ?>
getPreconditionOptions()
Returns the options for preconditions.
getQuestionType()
Returns the question type of the question.
saveCategoryToDb($categorytext, $neutral=0)
Saves a category to the database.
saveUserInput($post_data, $active_id, $a_return=false)
saveCompletionStatus($original_id="")
Saves the complete flag to the database.
importAdditionalMetadata($a_meta)
Import additional meta data from the question import file.
getAuthor()
Gets the authors name of the SurveyQuestion object.
getTitle()
Gets the title string of the SurveyQuestion object.
This class represents a selection list property in a property form.
$result
getObligatory($survey_id="")
Gets the obligatory state of the question.
setObligatory($obligatory=1)
Sets the obligatory state of the question.
setOrientation($orientation=0)
Sets the orientation of the question output.
& getWorkingDataFromUserInput($post_data)
Creates the user data of the svy_answer table from the POST data.
setId($id=-1)
Sets the id of the SurveyQuestion object.
XML writer class.
loadFromDb($id)
Loads a SurveyMultipleChoiceQuestion object from the database.
getQuestionDataArray($id)
Returns the question data fields from the database.
getQuestiontext()
Gets the questiontext of the SurveyQuestion object.
getOrientation()
Gets the orientation of the question output.
checkUserInput($post_data, $survey_id)
Checks the input of the active user for obligatory status and entered values.
getAdditionalTableName()
Returns the name of the additional question data table in the database.
toXML($a_include_header=TRUE, $obligatory_state="")
Returns an xml representation 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...
setOwner($owner="")
Sets the creator/owner ID of the SurveyQuestion object.
setComplete($a_complete)
Sets the complete state of the question.
importResponses($a_data)
Import response 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...
setOriginalId($original_id)
setQuestiontext($questiontext="")
Sets the questiontext of the SurveyQuestion object.
Class SurveyCategories.
if(!is_array($argv)) $options
getId()
Gets the id of the SurveyQuestion object.
insertXML(&$a_xml_writer, $a_include_header=TRUE)
Adds the question XML to a given XMLWriter object.
saveToDb($original_id="")
Saves a SurveyMultipleChoiceQuestion object to a database.
Basic class for all survey question types.
saveMaterial()
save material to db
xmlHeader()
Writes xml header public.
usableForPrecondition()
Returns if the question is usable for preconditions.
getPreconditionValueOutput($value)
Returns the output for a precondition value.
Create styles array
The data for the language used.
getAvailableRelations()
Returns the available relations for the question.
setAuthor($author="")
Sets the authors name of the SurveyQuestion object.
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.
setDescription($description="")
Sets the description string of the SurveyQuestion object.
getPreconditionSelectValue($default="", $title, $variable)
Creates a form property for the precondition value.
global $ilDB
isComplete()
Returns true if the question is complete for use.
getDescription()
Gets the description string of the SurveyQuestion object.
Add data(end) time
Method that wraps PHPs time in order to allow simulations with the workflow.
setObjId($obj_id=0)
Set the reference id of the container object.
setTitle($title="")
Sets the title string of the SurveyQuestion object.