ILIAS  release_7 Revision v7.30-3-g800a261c036
All Data Structures Namespaces Files Functions Variables Modules Pages
class.SurveyMetricQuestion.php
Go to the documentation of this file.
1 <?php
2 
3 /* Copyright (c) 1998-2019 ILIAS open source, Extended GPL, see docs/LICENSE */
4 
14 {
18  protected $db;
19 
20  const SUBTYPE_NON_RATIO = 3;
23 
31  public $subtype;
32 
38  public $minimum;
39 
45  public $maximum;
46 
58  public function __construct($title = "", $description = "", $author = "", $questiontext = "", $owner = -1, $subtype = self::SUBTYPE_NON_RATIO)
59  {
60  global $DIC;
61 
62  $this->db = $DIC->database();
64 
65  $this->subtype = $subtype;
66  $this->minimum = "";
67  $this->maximum = "";
68  }
69 
77  public function setSubtype($subtype = self::SUBTYPE_NON_RATIO)
78  {
79  $this->subtype = $subtype;
80  }
81 
89  public function setMinimum($minimum = 0)
90  {
91  if ($minimum !== null) {
92  $minimum = (float) $minimum;
93  }
94  if (!$minimum) {
95  $minimum = null;
96  }
97  $this->minimum = $minimum;
98  }
99 
107  public function setMaximum($maximum = "")
108  {
109  if ($maximum !== null) {
110  $maximum = (float) $maximum;
111  }
112  if (!$maximum) {
113  $maximum = null;
114  }
115  $this->maximum = $maximum;
116  }
117 
125  public function getSubtype()
126  {
127  return $this->subtype;
128  }
129 
137  public function getMinimum()
138  {
139  if ((strlen($this->minimum) == 0) && ($this->getSubtype() > 3)) {
140  $this->minimum = 0;
141  }
142  return (strlen($this->minimum)) ? $this->minimum : null;
143  }
144 
152  public function getMaximum()
153  {
154  return (strlen($this->maximum)) ? $this->maximum : null;
155  }
156 
164  public function getQuestionDataArray($id)
165  {
166  $ilDB = $this->db;
167 
168  $result = $ilDB->queryF(
169  "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",
170  array('integer'),
171  array($id)
172  );
173  if ($result->numRows() == 1) {
174  return $ilDB->fetchAssoc($result);
175  } else {
176  return array();
177  }
178  }
179 
186  public function loadFromDb($id)
187  {
188  $ilDB = $this->db;
189 
190  $result = $ilDB->queryF(
191  "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",
192  array('integer'),
193  array($id)
194  );
195  if ($result->numRows() == 1) {
196  $data = $ilDB->fetchAssoc($result);
197  $this->setId($data["question_id"]);
198  $this->setTitle($data["title"]);
199  $this->setDescription($data["description"]);
200  $this->setObjId($data["obj_fi"]);
201  $this->setAuthor($data["author"]);
202  $this->setOwner($data["owner_fi"]);
203  $this->label = $data['label'];
204  $this->setQuestiontext(ilRTE::_replaceMediaObjectImageSrc($data["questiontext"], 1));
205  $this->setObligatory($data["obligatory"]);
206  $this->setComplete($data["complete"]);
207  $this->setOriginalId($data["original_id"]);
208  $this->setSubtype($data["subtype"]);
209 
210  $result = $ilDB->queryF(
211  "SELECT svy_variable.* FROM svy_variable WHERE svy_variable.question_fi = %s",
212  array('integer'),
213  array($id)
214  );
215  if ($result->numRows() > 0) {
216  if ($data = $ilDB->fetchAssoc($result)) {
217  $this->minimum = $data["value1"];
218  if (($data["value2"] < 0) or (strcmp($data["value2"], "") == 0)) {
219  $this->maximum = "";
220  } else {
221  $this->maximum = $data["value2"];
222  }
223  }
224  }
225  }
226  parent::loadFromDb($id);
227  }
228 
235  public function isComplete()
236  {
237  if (
238  strlen($this->getTitle()) &&
239  strlen($this->getAuthor()) &&
240  strlen($this->getQuestiontext())
241  ) {
242  return 1;
243  } else {
244  return 0;
245  }
246  }
247 
253  public function saveToDb($original_id = "")
254  {
255  $ilDB = $this->db;
256 
257  $affectedRows = parent::saveToDb($original_id);
258  if ($affectedRows == 1) {
259  $affectedRows = $ilDB->manipulateF(
260  "DELETE FROM " . $this->getAdditionalTableName() . " WHERE question_fi = %s",
261  array('integer'),
262  array($this->getId())
263  );
264  $affectedRows = $ilDB->manipulateF(
265  "INSERT INTO " . $this->getAdditionalTableName() . " (question_fi, subtype) VALUES (%s, %s)",
266  array('integer', 'text'),
267  array($this->getId(), $this->getSubType())
268  );
269 
270  // saving material uris in the database
271  $this->saveMaterial();
272 
273  // save categories
274  $affectedRows = $ilDB->manipulateF(
275  "DELETE FROM svy_variable WHERE question_fi = %s",
276  array('integer'),
277  array($this->getId())
278  );
279 
280  if (preg_match("/[\D]/", $this->maximum) or (strcmp($this->maximum, "&infin;") == 0)) {
281  $max = -1;
282  } else {
283  $max = $this->getMaximum();
284  }
285  $next_id = $ilDB->nextId('svy_variable');
286  $affectedRows = $ilDB->manipulateF(
287  "INSERT INTO svy_variable (variable_id, category_fi, question_fi, value1, value2, sequence, tstamp) VALUES (%s, %s, %s, %s, %s, %s, %s)",
288  array('integer','integer','integer','float','float','integer','integer'),
289  array($next_id, 0, $this->getId(), $this->getMinimum(), $max, 0, time())
290  );
291  }
292  }
293 
300  public function toXML($a_include_header = true, $obligatory_state = "")
301  {
302  $a_xml_writer = new ilXmlWriter;
303  $a_xml_writer->xmlHeader();
304  $this->insertXML($a_xml_writer, $a_include_header, $obligatory_state);
305  $xml = $a_xml_writer->xmlDumpMem(false);
306  if (!$a_include_header) {
307  $pos = strpos($xml, "?>");
308  $xml = substr($xml, $pos + 2);
309  }
310  return $xml;
311  }
312 
320  public function insertXML(&$a_xml_writer, $a_include_header = true)
321  {
322  $attrs = array(
323  "id" => $this->getId(),
324  "title" => $this->getTitle(),
325  "type" => $this->getQuestiontype(),
326  "subtype" => $this->getSubtype(),
327  "obligatory" => $this->getObligatory()
328  );
329  $a_xml_writer->xmlStartTag("question", $attrs);
330 
331  $a_xml_writer->xmlElement("description", null, $this->getDescription());
332  $a_xml_writer->xmlElement("author", null, $this->getAuthor());
333  $a_xml_writer->xmlStartTag("questiontext");
334  $this->addMaterialTag($a_xml_writer, $this->getQuestiontext());
335  $a_xml_writer->xmlEndTag("questiontext");
336 
337  $a_xml_writer->xmlStartTag("responses");
338  switch ($this->getSubtype()) {
339  case 3:
340  $attrs = array(
341  "id" => "0",
342  "format" => "double"
343  );
344  if (strlen($this->getMinimum())) {
345  $attrs["min"] = $this->getMinimum();
346  }
347  if (strlen($this->getMaximum())) {
348  $attrs["max"] = $this->getMaximum();
349  }
350  break;
351  case 4:
352  $attrs = array(
353  "id" => "0",
354  "format" => "double"
355  );
356  if (strlen($this->getMinimum())) {
357  $attrs["min"] = $this->getMinimum();
358  }
359  if (strlen($this->getMaximum())) {
360  $attrs["max"] = $this->getMaximum();
361  }
362  break;
363  case 5:
364  $attrs = array(
365  "id" => "0",
366  "format" => "integer"
367  );
368  if (strlen($this->getMinimum())) {
369  $attrs["min"] = $this->getMinimum();
370  }
371  if (strlen($this->getMaximum())) {
372  $attrs["max"] = $this->getMaximum();
373  }
374  break;
375  }
376  $a_xml_writer->xmlStartTag("response_num", $attrs);
377  $a_xml_writer->xmlEndTag("response_num");
378 
379  $a_xml_writer->xmlEndTag("responses");
380 
381  if (count($this->material)) {
382  if (preg_match("/il_(\d*?)_(\w+)_(\d+)/", $this->material["internal_link"], $matches)) {
383  $attrs = array(
384  "label" => $this->material["title"]
385  );
386  $a_xml_writer->xmlStartTag("material", $attrs);
387  $intlink = "il_" . IL_INST_ID . "_" . $matches[2] . "_" . $matches[3];
388  if (strcmp($matches[1], "") != 0) {
389  $intlink = $this->material["internal_link"];
390  }
391  $a_xml_writer->xmlElement("mattext", null, $intlink);
392  $a_xml_writer->xmlEndTag("material");
393  }
394  }
395 
396  $a_xml_writer->xmlEndTag("question");
397  }
398 
405  public function getQuestionTypeID()
406  {
407  $ilDB = $this->db;
408  $result = $ilDB->queryF(
409  "SELECT questiontype_id FROM svy_qtype WHERE type_tag = %s",
410  array('text'),
411  array($this->getQuestionType())
412  );
413  $row = $ilDB->fetchAssoc($result);
414  return $row["questiontype_id"];
415  }
416 
423  public function getQuestionType()
424  {
425  return "SurveyMetricQuestion";
426  }
427 
434  public function getAdditionalTableName()
435  {
436  return "svy_qst_metric";
437  }
438 
445  public function &getWorkingDataFromUserInput($post_data)
446  {
447  $entered_value = $post_data[$this->getId() . "_metric_question"];
448  $data = array();
449  if (strlen($entered_value)) {
450  array_push($data, array("value" => $entered_value));
451  }
452  return $data;
453  }
454 
464  public function checkUserInput($post_data, $survey_id)
465  {
466  $entered_value = $post_data[$this->getId() . "_metric_question"];
467  // replace german notation with international notation
468  $entered_value = str_replace(",", ".", $entered_value);
469 
470  if ((!$this->getObligatory($survey_id)) && (strlen($entered_value) == 0)) {
471  return "";
472  }
473 
474  if (strlen($entered_value) == 0) {
475  return $this->lng->txt("survey_question_obligatory");
476  }
477 
478  if (strlen($this->getMinimum())) {
479  if ($entered_value < $this->getMinimum()) {
480  return $this->lng->txt("metric_question_out_of_bounds");
481  }
482  }
483 
484  if (strlen($this->getMaximum())) {
485  if (($this->getMaximum() == 1) && ($this->getMaximum() < $this->getMinimum())) {
486  // old &infty; values as maximum
487  } else {
488  if ($entered_value > $this->getMaximum()) {
489  return $this->lng->txt("metric_question_out_of_bounds");
490  }
491  }
492  }
493 
494  if (!is_numeric($entered_value)) {
495  return $this->lng->txt("metric_question_not_a_value");
496  }
497 
498  if (($this->getSubType() == self::SUBTYPE_RATIO_ABSOLUTE) && (intval($entered_value) != doubleval($entered_value))) {
499  return $this->lng->txt("metric_question_floating_point");
500  }
501  return "";
502  }
503 
504  public function saveUserInput($post_data, $active_id, $a_return = false)
505  {
506  $ilDB = $this->db;
507 
508  $entered_value = $post_data[$this->getId() . "_metric_question"];
509 
510  // replace german notation with international notation
511  $entered_value = str_replace(",", ".", $entered_value);
512 
513  if ($a_return) {
514  return array(array("value" => $entered_value, "textanswer" => null));
515  }
516  if (strlen($entered_value) == 0) {
517  return;
518  }
519 
520  $next_id = $ilDB->nextId('svy_answer');
521  #20216
522  $fields = array();
523  $fields['answer_id'] = array("integer", $next_id);
524  $fields['question_fi'] = array("integer", $this->getId());
525  $fields['active_fi'] = array("integer", $active_id);
526  $fields['value'] = array("float", (strlen($entered_value)) ? $entered_value : null);
527  $fields['textanswer'] = array("clob", null);
528  $fields['tstamp'] = array("integer", time());
529 
530  $affectedRows = $ilDB->insert("svy_answer", $fields);
531  }
532 
539  public function importResponses($a_data)
540  {
541  foreach ($a_data as $id => $data) {
542  $this->setMinimum($data["min"]);
543  $this->setMaximum($data["max"]);
544  }
545  }
546 
553  public function usableForPrecondition()
554  {
555  return true;
556  }
557 
564  public function getAvailableRelations()
565  {
566  return array("<", "<=", "=", "<>", ">=", ">");
567  }
568 
575  public function outPreconditionSelectValue(&$template)
576  {
577  $template->setCurrentBlock("textfield");
578  $template->setVariable("TEXTFIELD_VALUE", "");
579  $template->parseCurrentBlock();
580  }
581 
588  public function getPreconditionSelectValue($default = "", $title, $variable)
589  {
590  $step3 = new ilNumberInputGUI($title, $variable);
591  $step3->setValue($default);
592  return $step3;
593  }
594 
601  public function getMinMaxText()
602  {
603  $min = $this->getMinimum();
604  $max = $this->getMaximum();
605  if (strlen($min) && strlen($max)) {
606  return "(" . $min . " " . strtolower($this->lng->txt("to")) . " " . $max . ")";
607  } elseif (strlen($min)) {
608  return "(&gt;= " . $min . ")";
609  } elseif (strlen($max)) {
610  return "(&lt;= " . $max . ")";
611  } else {
612  return "";
613  }
614  }
615 }
getQuestionTypeID()
Returns the question type ID of the question.
outPreconditionSelectValue(&$template)
Creates a value selection for preconditions.
getAuthor()
Gets the authors name of the SurveyQuestion object.
getTitle()
Gets the title string of the SurveyQuestion object.
$data
Definition: storeScorm.php:23
const IL_INST_ID
Definition: constants.php:38
$result
getObligatory($survey_id="")
Gets the obligatory state of the question.
setSubtype($subtype=self::SUBTYPE_NON_RATIO)
Sets the question subtype.
getMaximum()
Returns the maximum value of the question.
setObligatory($obligatory=1)
Sets the obligatory state of the question.
setId($id=-1)
Sets the id of the SurveyQuestion object.
getAvailableRelations()
Returns the available relations for the question.
XML writer class.
getQuestiontext()
Gets the questiontext of the SurveyQuestion object.
getSubtype()
Gets the question subtype.
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.
isComplete()
Returns true if the question is complete for use.
setComplete($a_complete)
Sets the complete state of the question.
getAdditionalTableName()
Returns the name of the additional question data table in the database.
setMinimum($minimum=0)
Sets the minimum value.
loadFromDb($id)
Loads a SurveyMetricQuestion object from the database.
setOriginalId($original_id)
toXML($a_include_header=true, $obligatory_state="")
Returns an xml representation of the question.
setQuestiontext($questiontext="")
Sets the questiontext of the SurveyQuestion object.
getId()
Gets the id of the SurveyQuestion object.
getMinimum()
Returns the minimum value of the question.
saveToDb($original_id="")
Saves a SurveyMetricQuestion object to a database.
This class represents a number property in a property form.
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.
importResponses($a_data)
Import response data from the question import file.
Basic class for all survey question types.
global $DIC
Definition: goto.php:24
saveMaterial()
save material to db
insertXML(&$a_xml_writer, $a_include_header=true)
Adds the question XML to a given XMLWriter object.
xmlHeader()
Writes xml header public.
$xml
Definition: metadata.php:332
usableForPrecondition()
Returns if the question is usable for preconditions.
getQuestionType()
Returns the question type of the question.
saveUserInput($post_data, $active_id, $a_return=false)
setAuthor($author="")
Sets the authors name of the SurveyQuestion object.
__construct(Container $dic, ilPlugin $plugin)
setDescription($description="")
Sets the description string of the SurveyQuestion object.
global $ilDB
checkUserInput($post_data, $survey_id)
Checks the input of the active user for obligatory status and entered values.
getMinMaxText()
Creates a text for the input range of the metric question.
getPreconditionSelectValue($default="", $title, $variable)
Creates a form property for the precondition value.
__construct($title="", $description="", $author="", $questiontext="", $owner=-1, $subtype=self::SUBTYPE_NON_RATIO)
SurveyMetricQuestion constructor.
getDescription()
Gets the description string of the SurveyQuestion object.
setObjId($obj_id=0)
Set the reference id of the container object.
Metric survey question.
getQuestionDataArray($id)
Returns the question data fields from the database.
setMaximum($maximum="")
Sets the maximum value.
& getWorkingDataFromUserInput($post_data)
Creates the user data of the svy_answer table from the POST data.
setTitle($title="")
Sets the title string of the SurveyQuestion object.