ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
class.assFormulaQuestion.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
4 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
5 include_once "./Modules/TestQuestionPool/classes/class.assFormulaQuestionResult.php";
6 include_once "./Modules/TestQuestionPool/classes/class.assFormulaQuestionVariable.php";
7 include_once "./Modules/TestQuestionPool/classes/class.ilUnitConfigurationRepository.php";
8 include_once "./Modules/Test/classes/inc.AssessmentConstants.php";
9 include_once "./Modules/TestQuestionPool/interfaces/interface.iQuestionCondition.php";
10 require_once './Modules/TestQuestionPool/classes/class.ilUserQuestionResult.php';
11 
20 {
21  private $variables;
22  private $results;
23  private $resultunits;
24 
28  private $unitrepository;
29 
41  public function __construct(
42  $title = "",
43  $comment = "",
44  $author = "",
45  $owner = -1,
46  $question = ""
47  ) {
48  parent::__construct($title, $comment, $author, $owner, $question);
49  $this->variables = array();
50  $this->results = array();
51  $this->resultunits = array();
52  $this->unitrepository = new ilUnitConfigurationRepository(0);
53  }
54 
55  public function clearVariables()
56  {
57  $this->variables = array();
58  }
59 
60  public function getVariables()
61  {
62  return $this->variables;
63  }
64 
65  public function getVariable($variable)
66  {
67  if (array_key_exists($variable, $this->variables)) {
68  return $this->variables[$variable];
69  }
70  return null;
71  }
72 
73  public function addVariable($variable)
74  {
75  $this->variables[$variable->getVariable()] = $variable;
76  }
77 
78  public function clearResults()
79  {
80  $this->results = array();
81  }
82 
83  public function getResults()
84  {
85  return $this->results;
86  }
87 
88  public function getResult($result)
89  {
90  if (array_key_exists($result, $this->results)) {
91  return $this->results[$result];
92  }
93  return null;
94  }
95 
96  public function addResult($result)
97  {
98  $this->results[$result->getResult()] = $result;
99  }
100 
101  public function addResultUnits($result, $unit_ids)
102  {
103  $this->resultunits[$result->getResult()] = array();
104  if ((!is_object($result)) || (!is_array($unit_ids))) {
105  return;
106  }
107  foreach ($unit_ids as $id) {
108  if (is_numeric($id) && ($id > 0)) {
109  $this->resultunits[$result->getResult()][$id] = $this->getUnitrepository()->getUnit($id);
110  }
111  }
112  }
113 
114  public function addResultUnit($result, $unit)
115  {
116  if (is_object($result) && is_object($unit)) {
117  if (!is_array($this->resultunits[$result->getResult()])) {
118  $this->resultunits[$result->getResult()] = array();
119  }
120  $this->resultunits[$result->getResult()][$unit->getId()] = $unit;
121  }
122  }
123 
124  public function getResultUnits($result)
125  {
126  if (array_key_exists($result->getResult(), $this->resultunits)) {
127  return $this->resultunits[$result->getResult()];
128  } else {
129  return array();
130  }
131  }
132 
133  public function hasResultUnit($result, $unit_id)
134  {
135  if (array_key_exists($result->getResult(), $this->resultunits)) {
136  if (array_key_exists($unit_id, $this->resultunits[$result->getResult()])) {
137  return true;
138  }
139  }
140 
141  return false;
142  }
143 
144  public function parseQuestionText()
145  {
146  $this->clearResults();
147  $this->clearVariables();
148  if (preg_match_all("/(\\\$v\\d+)/ims", $this->getQuestion(), $matches)) {
149  foreach ($matches[1] as $variable) {
150  $varObj = new assFormulaQuestionVariable($variable, 0, 0, null, 0);
151  $this->addVariable($varObj);
152  }
153  }
154 
155  if (preg_match_all("/(\\\$r\\d+)/ims", $this->getQuestion(), $rmatches)) {
156  foreach ($rmatches[1] as $result) {
157  $resObj = new assFormulaQuestionResult($result, null, null, 0, -1, null, 1, 1, true);
158  $this->addResult($resObj);
159  }
160  }
161  }
162 
163  public function checkForDuplicateVariables()
164  {
165  if (preg_match_all("/(\\\$v\\d+)/ims", $this->getQuestion(), $matches)) {
166  if ((count(array_unique($matches[1]))) != count($matches[1])) {
167  return false;
168  }
169  }
170  return true;
171  }
172 
173  public function checkForDuplicateResults()
174  {
175  if (preg_match_all("/(\\\$r\\d+)/ims", $this->getQuestion(), $rmatches)) {
176  if ((count(array_unique($rmatches[1]))) != count($rmatches[1])) {
177  return false;
178  }
179  }
180  return true;
181  }
182 
187  public function fetchAllResults($questionText)
188  {
189  $resObjects = array();
190  $matches = null;
191 
192  if (preg_match_all("/(\\\$r\\d+)/ims", $questionText, $matches)) {
193  foreach ($matches[1] as $resultKey) {
194  $resObjects[] = $this->getResult($resultKey);
195  }
196  }
197 
198  return $resObjects;
199  }
200 
205  public function fetchAllVariables($questionText)
206  {
207  $varObjects = array();
208  $matches = null;
209 
210  if (preg_match_all("/(\\\$v\\d+)/ims", $questionText, $matches)) {
211  foreach ($matches[1] as $variableKey) {
212  $varObjects[] = $this->getVariable($variableKey);
213  }
214  }
215 
216  return $varObjects;
217  }
218 
223  public function hasRequiredVariableSolutionValues(array $userSolution)
224  {
225  foreach ($this->fetchAllVariables($this->getQuestion()) as $varObj) {
226  if (!isset($userSolution[$varObj->getVariable()])) {
227  return false;
228  }
229 
230  if (!strlen($userSolution[$varObj->getVariable()])) {
231  return false;
232  }
233  }
234 
235  return true;
236  }
237 
242  {
243  foreach ($this->fetchAllResults($this->getQuestion()) as $resObj) {
244  $resObj->findValidRandomVariables($this->getVariables(), $this->getResults());
245  }
246 
247  $variableSolutionValues = array();
248 
249  foreach ($this->fetchAllVariables($this->getQuestion()) as $varObj) {
250  $variableSolutionValues[$varObj->getVariable()] = $varObj->getValue();
251  }
252 
253  return $variableSolutionValues;
254  }
255 
264  public function substituteVariables(array $userdata, $graphicalOutput = false, $forsolution = false, $result_output = false)
265  {
266  if ((count($this->results) == 0) && (count($this->variables) == 0)) {
267  return false;
268  }
269 
270  $text = $this->getQuestion();
271 
272  foreach ($this->fetchAllVariables($this->getQuestion()) as $varObj) {
273  if (isset($userdata[$varObj->getVariable()]) && strlen($userdata[$varObj->getVariable()])) {
274  $varObj->setValue($userdata[$varObj->getVariable()]);
275  }
276 
277  $unit = (is_object($varObj->getUnit())) ? $varObj->getUnit()->getUnit() : "";
278  $val = (strlen($varObj->getValue()) > 8) ? strtoupper(sprintf("%e", $varObj->getValue())) : $varObj->getValue();
279 
280  $text = preg_replace("/\\$" . substr($varObj->getVariable(), 1) . "(?![0-9]+)/", $val . " " . $unit . "\\1", $text);
281  }
282 
283  if (preg_match_all("/(\\\$r\\d+)/ims", $this->getQuestion(), $rmatches)) {
284  foreach ($rmatches[1] as $result) {
285  $resObj = $this->getResult($result);
286  $value = "";
287  $frac_helper = '';
288  $user_data[$result]['result_type'] = $resObj->getResultType();
289 
290  if (
291  $resObj->getResultType() == assFormulaQuestionResult::RESULT_FRAC ||
292  $resObj->getResultType() == assFormulaQuestionResult::RESULT_CO_FRAC
293  ) {
294  $is_frac = true;
295  }
296  if (is_array($userdata)) {
297  if (is_array($userdata[$result])) {
298  if (false && $forsolution && $result_output) { // fix for mantis #25956
299  $value_org = $resObj->calculateFormula($this->getVariables(), $this->getResults(), parent::getId());
300  $value = sprintf("%." . $resObj->getPrecision() . "f", $value_org);
301  if ($is_frac) {
303  if (is_array($value)) {
304  $frac_helper = $value[1];
305  $value = $value[0];
306  }
307  }
308  } else {
309  if ($forsolution) {
310  $value = $userdata[$result]["value"];
311  } else {
312  $value = ' value="' . $userdata[$result]["value"] . '"';
313  }
314  }
315  }
316  } else {
317  if ($forsolution) {
318  $value = $resObj->calculateFormula($this->getVariables(), $this->getResults(), parent::getId());
319  $value = sprintf("%." . $resObj->getPrecision() . "f", $value);
320 
321  if ($is_frac) {
323  if (is_array($value)) {
324  $frac_helper = $value[1];
325  $value = $value[0];
326  }
327  $value = ' value="' . $value . '"';
328  }
329  } else {
330  // Precision fix for Preview by tjoussen
331  // If all default values are set, this function is called in getPreview
332  $use_precision = !($userdata == null && $graphicalOutput == false && $forsolution == false && $result_output == false);
333 
334  $val = $resObj->calculateFormula($this->getVariables(), $this->getResults(), parent::getId(), $use_precision);
335 
336  if ($resObj->getResultType() == assFormulaQuestionResult::RESULT_FRAC
337  || $resObj->getResultType() == assFormulaQuestionResult::RESULT_CO_FRAC) {
338  $val = $resObj->convertDecimalToCoprimeFraction($val);
339  if (is_array($val)) {
340  $frac_helper = $val[1];
341  $val = $val[0];
342  }
343  } else {
344  $val = sprintf("%." . $resObj->getPrecision() . "f", $val);
345  $val = (strlen($val) > 8) ? strtoupper(sprintf("%e", $val)) : $val;
346  }
347  $value = ' value="' . $val . '"';
348  }
349  }
350 
351  if ($forsolution) {
352  $input = '<span class="ilc_qinput_TextInput solutionbox">' . ilUtil::prepareFormOutput($value) . '</span>';
353  } else {
354  $input = '<input class="ilc_qinput_TextInput" type="text" spellcheck="false" autocomplete="off" autocorrect="off" autocapitalize="off" name="result_' . $result . '"' . $value . ' />';
355  }
356 
357  $units = "";
358  if (count($this->getResultUnits($resObj)) > 0) {
359  if ($forsolution) {
360  if (is_array($userdata)) {
361  foreach ($this->getResultUnits($resObj) as $unit) {
362  if ($userdata[$result]["unit"] == $unit->getId()) {
363  $units = $unit->getUnit();
364  }
365  }
366  } else {
367  if ($resObj->getUnit()) {
368  $units = $resObj->getUnit()->getUnit();
369  }
370  }
371  } else {
372  $units = '<select name="result_' . $result . '_unit">';
373  $units .= '<option value="-1">' . $this->lng->txt("select_unit") . '</option>';
374  foreach ($this->getResultUnits($resObj) as $unit) {
375  $units .= '<option value="' . $unit->getId() . '"';
376  if ((is_array($userdata[$result])) && (strlen($userdata[$result]["unit"]))) {
377  if ($userdata[$result]["unit"] == $unit->getId()) {
378  $units .= ' selected="selected"';
379  }
380  }
381  $units .= '>' . $unit->getUnit() . '</option>';
382  }
383  $units .= '</select>';
384  }
385  } else {
386  $units = "";
387  }
388  switch ($resObj->getResultType()) {
390  $units .= ' ' . $this->lng->txt('expected_result_type') . ': ' . $this->lng->txt('result_dec');
391  break;
393  if (strlen($frac_helper)) {
394  $units .= ' &asymp; ' . $frac_helper . ', ';
395  } elseif (is_array($userdata) && isset($userdata[$result]) && strlen($userdata[$result]["frac_helper"])) {
396  if (!preg_match('-/-', $value)) {
397  $units .= ' &asymp; ' . $userdata[$result]["frac_helper"] . ', ';
398  }
399  }
400  $units .= ' ' . $this->lng->txt('expected_result_type') . ': ' . $this->lng->txt('result_frac');
401  break;
403  if (strlen($frac_helper)) {
404  $units .= ' &asymp; ' . $frac_helper . ', ';
405  } elseif (is_array($userdata) && isset($userdata[$result]) && strlen($userdata[$result]["frac_helper"])) {
406  if (!preg_match('-/-', $value)) {
407  $units .= ' &asymp; ' . $userdata[$result]["frac_helper"] . ', ';
408  }
409  }
410  $units .= ' ' . $this->lng->txt('expected_result_type') . ': ' . $this->lng->txt('result_co_frac');
411  break;
413  break;
414  }
415  $checkSign = "";
416  if ($graphicalOutput) {
417  $resunit = null;
418  $user_value = '';
419  if (is_array($userdata) && is_array($userdata[$result])) {
420  if ($userdata[$result]["unit"] > 0) {
421  $resunit = $this->getUnitrepository()->getUnit($userdata[$result]["unit"]);
422  }
423 
424  if (isset($userdata[$result]["value"])) {
425  $user_value = $userdata[$result]["value"];
426  }
427  }
428 
429  $template = new ilTemplate("tpl.il_as_qpl_formulaquestion_output_solution_image.html", true, true, 'Modules/TestQuestionPool');
430 
431  if ($resObj->isCorrect($this->getVariables(), $this->getResults(), $user_value, $resunit)) {
432  $template->setCurrentBlock("icon_ok");
433  $template->setVariable("ICON_OK", ilUtil::getImagePath("icon_ok.svg"));
434  $template->setVariable("TEXT_OK", $this->lng->txt("answer_is_right"));
435  $template->parseCurrentBlock();
436  } else {
437  $template->setCurrentBlock("icon_not_ok");
438  $template->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_not_ok.svg"));
439  $template->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_wrong"));
440  $template->parseCurrentBlock();
441  }
442  $checkSign = $template->get();
443  }
444  $resultOutput = "";
445  if ($result_output) {
446  $template = new ilTemplate("tpl.il_as_qpl_formulaquestion_output_solution_result.html", true, true, 'Modules/TestQuestionPool');
447 
448  if (is_array($userdata)) {
449  $found = $resObj->getResultInfo($this->getVariables(), $this->getResults(), $userdata[$resObj->getResult()]["value"], $userdata[$resObj->getResult()]["unit"], $this->getUnitrepository()->getUnits());
450  } else {
451  $found = $resObj->getResultInfo($this->getVariables(), $this->getResults(), $resObj->calculateFormula($this->getVariables(), $this->getResults(), parent::getId()), is_object($resObj->getUnit()) ? $resObj->getUnit()->getId() : null, $this->getUnitrepository()->getUnits());
452  }
453  $resulttext = "(";
454  if ($resObj->getRatingSimple()) {
455  if ($frac_helper) {
456  $resulttext .= "n/a";
457  } else {
458  $resulttext .= $found['points'] . " " . (($found['points'] == 1) ? $this->lng->txt('point') : $this->lng->txt('points'));
459  }
460  } else {
461  $resulttext .= $this->lng->txt("rated_sign") . " " . (($found['sign']) ? $found['sign'] : 0) . " " . (($found['sign'] == 1) ? $this->lng->txt('point') : $this->lng->txt('points')) . ", ";
462  $resulttext .= $this->lng->txt("rated_value") . " " . (($found['value']) ? $found['value'] : 0) . " " . (($found['value'] == 1) ? $this->lng->txt('point') : $this->lng->txt('points')) . ", ";
463  $resulttext .= $this->lng->txt("rated_unit") . " " . (($found['unit']) ? $found['unit'] : 0) . " " . (($found['unit'] == 1) ? $this->lng->txt('point') : $this->lng->txt('points'));
464  }
465 
466  $resulttext .= ")";
467  $template->setVariable("RESULT_OUTPUT", $resulttext);
468 
469  $resultOutput = $template->get();
470  }
471  $text = preg_replace("/\\\$" . substr($result, 1) . "(?![0-9]+)/", $input . " " . $units . " " . $checkSign . " " . $resultOutput . " " . "\\1", $text);
472  }
473  }
474  return $text;
475  }
476 
483  public function canUseAdvancedRating($result)
484  {
485  $result_units = $this->getResultUnits($result);
486  $resultunit = $result->getUnit();
487  $similar_units = 0;
488  foreach ($result_units as $unit) {
489  if (is_object($resultunit)) {
490  if ($resultunit->getId() != $unit->getId()) {
491  if ($resultunit->getBaseUnit() && $unit->getBaseUnit()) {
492  if ($resultunit->getBaseUnit() == $unit->getBaseUnit()) {
493  return false;
494  }
495  }
496  if ($resultunit->getBaseUnit()) {
497  if ($resultunit->getBaseUnit() == $unit->getId()) {
498  return false;
499  }
500  }
501  if ($unit->getBaseUnit()) {
502  if ($unit->getBaseUnit() == $resultunit->getId()) {
503  return false;
504  }
505  }
506  }
507  }
508  }
509  return true;
510  }
511 
516  public function isComplete()
517  {
518  if (($this->title) and ($this->author) and ($this->question) and ($this->getMaximumPoints() > 0)) {
519  return true;
520  } else {
521  return false;
522  }
523  }
524 
529  public function saveToDb($original_id = "")
530  {
531  global $DIC;
532  $ilDB = $DIC['ilDB'];
533 
535  // save variables
536  $affectedRows = $ilDB->manipulateF(
537  "
538  DELETE FROM il_qpl_qst_fq_var
539  WHERE question_fi = %s",
540  array("integer"),
541  array($this->getId())
542  );
543 
544  foreach ($this->variables as $variable) {
545  $next_id = $ilDB->nextId('il_qpl_qst_fq_var');
546  $ilDB->insert(
547  'il_qpl_qst_fq_var',
548  array(
549  'variable_id' => array('integer', $next_id),
550  'question_fi' => array('integer', $this->getId()),
551  'variable' => array('text', $variable->getVariable()),
552  'range_min' => array('float', ((strlen($variable->getRangeMin())) ? $variable->getRangeMin() : 0.0)),
553  'range_max' => array('float', ((strlen($variable->getRangeMax())) ? $variable->getRangeMax() : 0.0)),
554  'unit_fi' => array('integer', (is_object($variable->getUnit()) ? (int) $variable->getUnit()->getId() : 0)),
555  'varprecision' => array('integer', (int) $variable->getPrecision()),
556  'intprecision' => array('integer', (int) $variable->getIntprecision()),
557  'range_min_txt' => array('text', $variable->getRangeMinTxt()),
558  'range_max_txt' => array('text', $variable->getRangeMaxTxt())
559  )
560  );
561  }
562  // save results
563  $affectedRows = $ilDB->manipulateF(
564  "DELETE FROM il_qpl_qst_fq_res WHERE question_fi = %s",
565  array("integer"),
566  array($this->getId())
567  );
568 
569  foreach ($this->results as $result) {
570  $next_id = $ilDB->nextId('il_qpl_qst_fq_res');
571  if (is_object($result->getUnit())) {
572  $tmp_result_unit = $result->getUnit()->getId();
573  } else {
574  $tmp_result_unit = null;
575  }
576 
577  $formula = str_replace(",", ".", $result->getFormula());
578 
579  $ilDB->insert("il_qpl_qst_fq_res", array(
580  "result_id" => array("integer", $next_id),
581  "question_fi" => array("integer", $this->getId()),
582  "result" => array("text", $result->getResult()),
583  "range_min" => array("float", ((strlen($result->getRangeMin())) ? $result->getRangeMin() : 0)),
584  "range_max" => array("float", ((strlen($result->getRangeMax())) ? $result->getRangeMax() : 0)),
585  "tolerance" => array("float", ((strlen($result->getTolerance())) ? $result->getTolerance() : 0)),
586  "unit_fi" => array("integer", (int) $tmp_result_unit),
587  "formula" => array("clob", $formula),
588  "resprecision" => array("integer", $result->getPrecision()),
589  "rating_simple" => array("integer", ($result->getRatingSimple()) ? 1 : 0),
590  "rating_sign" => array("float", ($result->getRatingSimple()) ? 0 : $result->getRatingSign()),
591  "rating_value" => array("float", ($result->getRatingSimple()) ? 0 : $result->getRatingValue()),
592  "rating_unit" => array("float", ($result->getRatingSimple()) ? 0 : $result->getRatingUnit()),
593  "points" => array("float", $result->getPoints()),
594  "result_type" => array('integer', (int) $result->getResultType()),
595  "range_min_txt" => array("text", $result->getRangeMinTxt()),
596  "range_max_txt" => array("text", $result->getRangeMaxTxt())
597 
598  ));
599  }
600  // save result units
601  $affectedRows = $ilDB->manipulateF(
602  "DELETE FROM il_qpl_qst_fq_res_unit WHERE question_fi = %s",
603  array("integer"),
604  array($this->getId())
605  );
606  foreach ($this->results as $result) {
607  foreach ($this->getResultUnits($result) as $unit) {
608  $next_id = $ilDB->nextId('il_qpl_qst_fq_res_unit');
609  $affectedRows = $ilDB->manipulateF(
610  "INSERT INTO il_qpl_qst_fq_res_unit (result_unit_id, question_fi, result, unit_fi) VALUES (%s, %s, %s, %s)",
611  array('integer', 'integer', 'text', 'integer'),
612  array(
613  $next_id,
614  $this->getId(),
615  $result->getResult(),
616  $unit->getId()
617  )
618  );
619  }
620  }
621 
622  parent::saveToDb();
623  }
624 
629  public function loadFromDb($question_id)
630  {
631  global $DIC;
632  $ilDB = $DIC['ilDB'];
633 
634  $result = $ilDB->queryF(
635  "SELECT qpl_questions.* FROM qpl_questions WHERE question_id = %s",
636  array('integer'),
637  array($question_id)
638  );
639  if ($result->numRows() == 1) {
640  $data = $ilDB->fetchAssoc($result);
641  $this->setId($question_id);
642  $this->setTitle($data["title"]);
643  $this->setComment($data["description"]);
644  $this->setSuggestedSolution($data["solution_hint"]);
645  $this->setPoints($data['points']);
646  $this->setOriginalId($data["original_id"]);
647  $this->setObjId($data["obj_fi"]);
648  $this->setAuthor($data["author"]);
649  $this->setOwner($data["owner"]);
650 
651  try {
652  $this->setAdditionalContentEditingMode($data['add_cont_edit_mode']);
653  } catch (ilTestQuestionPoolException $e) {
654  }
655 
656  $this->unitrepository = new ilUnitConfigurationRepository($question_id);
657 
658  include_once("./Services/RTE/classes/class.ilRTE.php");
659  $this->setQuestion(ilRTE::_replaceMediaObjectImageSrc($data["question_text"], 1));
660  $this->setEstimatedWorkingTime(substr($data["working_time"], 0, 2), substr($data["working_time"], 3, 2), substr($data["working_time"], 6, 2));
661 
662  // load variables
663  $result = $ilDB->queryF(
664  "SELECT * FROM il_qpl_qst_fq_var WHERE question_fi = %s",
665  array('integer'),
666  array($question_id)
667  );
668  if ($result->numRows() > 0) {
669  while ($data = $ilDB->fetchAssoc($result)) {
670  $varObj = new assFormulaQuestionVariable($data["variable"], $data["range_min"], $data["range_max"], $this->getUnitrepository()->getUnit($data["unit_fi"]), $data["varprecision"], $data["intprecision"]);
671  $varObj->setRangeMinTxt($data['range_min_txt']);
672  $varObj->setRangeMaxTxt($data['range_max_txt']);
673  $this->addVariable($varObj);
674  }
675  }
676  // load results
677  $result = $ilDB->queryF(
678  "SELECT * FROM il_qpl_qst_fq_res WHERE question_fi = %s",
679  array('integer'),
680  array($question_id)
681  );
682  if ($result->numRows() > 0) {
683  while ($data = $ilDB->fetchAssoc($result)) {
684  $resObj = new assFormulaQuestionResult($data["result"], $data["range_min"], $data["range_max"], $data["tolerance"], $this->getUnitrepository()->getUnit($data["unit_fi"]), $data["formula"], $data["points"], $data["resprecision"], $data["rating_simple"], $data["rating_sign"], $data["rating_value"], $data["rating_unit"]);
685  $resObj->setResultType($data['result_type']);
686  $resObj->setRangeMinTxt($data['range_min_txt']);
687  $resObj->setRangeMaxTxt($data['range_max_txt']);
688  $this->addResult($resObj);
689  }
690  }
691 
692  // load result units
693  $result = $ilDB->queryF(
694  "SELECT * FROM il_qpl_qst_fq_res_unit WHERE question_fi = %s",
695  array('integer'),
696  array($question_id)
697  );
698  if ($result->numRows() > 0) {
699  while ($data = $ilDB->fetchAssoc($result)) {
700  $unit = $this->getUnitrepository()->getUnit($data["unit_fi"]);
701  $resObj = $this->getResult($data["result"]);
702  $this->addResultUnit($resObj, $unit);
703  }
704  }
705  }
706  parent::loadFromDb($question_id);
707  }
708 
713  public function duplicate($for_test = true, $title = "", $author = "", $owner = "", $testObjId = null)
714  {
715  if ($this->id <= 0) {
716  // The question has not been saved. It cannot be duplicated
717  return;
718  }
719  // duplicate the question in database
720  $this_id = $this->getId();
721  $thisObjId = $this->getObjId();
722 
723  $clone = $this;
724  include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
726  $clone->id = -1;
727 
728  if ((int) $testObjId > 0) {
729  $clone->setObjId($testObjId);
730  }
731 
732  if ($title) {
733  $clone->setTitle($title);
734  }
735 
736  if ($author) {
737  $clone->setAuthor($author);
738  }
739  if ($owner) {
740  $clone->setOwner($owner);
741  }
742 
743  if ($for_test) {
744  $clone->saveToDb($original_id);
745  } else {
746  $clone->saveToDb();
747  }
748 
749  $clone->unitrepository->cloneUnits($this_id, $clone->getId());
750 
751  // copy question page content
752  $clone->copyPageOfQuestion($this_id);
753  // copy XHTML media objects
754  $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
755  $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
756 
757  return $clone->id;
758  }
759 
764  public function copyObject($target_questionpool_id, $title = "")
765  {
766  if ($this->id <= 0) {
767  // The question has not been saved. It cannot be duplicated
768  return;
769  }
770  // duplicate the question in database
771  $clone = $this;
772  include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
774  $clone->id = -1;
775  $source_questionpool_id = $this->getObjId();
776  $clone->setObjId($target_questionpool_id);
777  if ($title) {
778  $clone->setTitle($title);
779  }
780  $clone->saveToDb();
781 
782  $clone->unitrepository->cloneUnits($original_id, $clone->getId());
783 
784  // copy question page content
785  $clone->copyPageOfQuestion($original_id);
786  // copy XHTML media objects
787  $clone->copyXHTMLMediaObjectsOfQuestion($original_id);
788 
789  $clone->onCopy($source_questionpool_id, $original_id, $clone->getObjId(), $clone->getId());
790 
791  return $clone->id;
792  }
793 
794  public function createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle = "")
795  {
796  if ($this->id <= 0) {
797  // The question has not been saved. It cannot be duplicated
798  return;
799  }
800 
801  include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
802 
803  $sourceQuestionId = $this->id;
804  $sourceParentId = $this->getObjId();
805 
806  // duplicate the question in database
807  $clone = $this;
808  $clone->id = -1;
809 
810  $clone->setObjId($targetParentId);
811 
812  if ($targetQuestionTitle) {
813  $clone->setTitle($targetQuestionTitle);
814  }
815 
816  $clone->saveToDb();
817  // copy question page content
818  $clone->copyPageOfQuestion($sourceQuestionId);
819  // copy XHTML media objects
820  $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
821 
822  $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
823 
824  return $clone->id;
825  }
826 
831  public function getMaximumPoints()
832  {
833  $points = 0;
834  foreach ($this->results as $result) {
835  $points += $result->getPoints();
836  }
837  return $points;
838  }
839 
848  public function calculateReachedPoints($active_id, $pass = null, $authorizedSolution = true, $returndetails = false)
849  {
850  if (is_null($pass)) {
851  $pass = $this->getSolutionMaxPass($active_id);
852  }
853  $solutions = &$this->getSolutionValues($active_id, $pass, $authorizedSolution);
854  $user_solution = array();
855  foreach ($solutions as $idx => $solution_value) {
856  if (preg_match("/^(\\\$v\\d+)$/", $solution_value["value1"], $matches)) {
857  $user_solution[$matches[1]] = $solution_value["value2"];
858  $varObj = $this->getVariable($solution_value["value1"]);
859  $varObj->setValue($solution_value["value2"]);
860  } elseif (preg_match("/^(\\\$r\\d+)$/", $solution_value["value1"], $matches)) {
861  if (!array_key_exists($matches[1], $user_solution)) {
862  $user_solution[$matches[1]] = array();
863  }
864  $user_solution[$matches[1]]["value"] = $solution_value["value2"];
865  } elseif (preg_match("/^(\\\$r\\d+)_unit$/", $solution_value["value1"], $matches)) {
866  if (!array_key_exists($matches[1], $user_solution)) {
867  $user_solution[$matches[1]] = array();
868  }
869  $user_solution[$matches[1]]["unit"] = $solution_value["value2"];
870  }
871  }
872  //vd($this->getResults());
873  $points = 0;
874  foreach ($this->getResults() as $result) {
875  //vd($user_solution[$result->getResult()]["value"]);
876  $points += $result->getReachedPoints($this->getVariables(), $this->getResults(), $user_solution[$result->getResult()]["value"], $user_solution[$result->getResult()]["unit"], $this->unitrepository->getUnits());
877  }
878 
879  return $points;
880  }
881 
883  {
884  $user_solution = $previewSession->getParticipantsSolution();
885 
886  $points = 0;
887  foreach ($this->getResults() as $result) {
888  $v = isset($user_solution[$result->getResult()]) ? $user_solution[$result->getResult()] : null;
889  $u = isset($user_solution[$result->getResult() . '_unit']) ? $user_solution[$result->getResult() . '_unit'] : null;
890 
891  $points += $result->getReachedPoints(
892  $this->getVariables(),
893  $this->getResults(),
894  $v,
895  $u,
896  $this->unitrepository->getUnits()
897  );
898  }
899 
900  $reachedPoints = $this->deductHintPointsFromReachedPoints($previewSession, $points);
901 
902  return $this->ensureNonNegativePoints($reachedPoints);
903  }
904 
905  protected function isValidSolutionResultValue($submittedValue)
906  {
907  $submittedValue = str_replace(',', '.', $submittedValue);
908 
909  if (is_numeric($submittedValue)) {
910  return true;
911  }
912 
913  if (preg_match('/^[-+]{0,1}\d+\/\d+$/', $submittedValue)) {
914  return true;
915  }
916 
917  return false;
918  }
919 
927  public function saveWorkingData($active_id, $pass = null, $authorized = true)
928  {
929  global $DIC;
930  $ilDB = $DIC['ilDB'];
931 
932  if (is_null($pass)) {
933  include_once "./Modules/Test/classes/class.ilObjTest.php";
934  $pass = ilObjTest::_getPass($active_id);
935  }
936 
937  $entered_values = false;
938 
939  $this->getProcessLocker()->executeUserSolutionUpdateLockOperation(function () use (&$entered_values, $ilDB, $active_id, $pass, $authorized) {
940  $solutionSubmit = $this->getSolutionSubmit();
941  foreach ($solutionSubmit as $key => $value) {
942  $matches = null;
943  if (preg_match("/^result_(\\\$r\\d+)$/", $key, $matches)) {
944  if (strlen($value)) {
945  $entered_values = true;
946  }
947 
948  $queryResult = "SELECT solution_id FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s AND authorized = %s AND " . $ilDB->like('value1', 'clob', $matches[1]);
949 
950  if ($this->getStep() !== null) {
951  $queryResult .= " AND step = " . $ilDB->quote((int) $this->getStep(), 'integer') . " ";
952  }
953 
954  $result = $ilDB->queryF(
955  $queryResult,
956  array('integer', 'integer', 'integer', 'integer'),
957  array($active_id, $pass, $this->getId(), (int) $authorized)
958  );
959  if ($result->numRows()) {
960  while ($row = $ilDB->fetchAssoc($result)) {
961  $ilDB->manipulateF(
962  "DELETE FROM tst_solutions WHERE solution_id = %s AND authorized = %s",
963  array('integer', 'integer'),
964  array($row['solution_id'], (int) $authorized)
965  );
966  }
967  }
968 
969  $this->saveCurrentSolution($active_id, $pass, $matches[1], str_replace(",", ".", $value), $authorized);
970  } elseif (preg_match("/^result_(\\\$r\\d+)_unit$/", $key, $matches)) {
971  $queryResultUnit = "SELECT solution_id FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s AND authorized = %s AND " . $ilDB->like('value1', 'clob', $matches[1] . "_unit");
972 
973  if ($this->getStep() !== null) {
974  $queryResultUnit .= " AND step = " . $ilDB->quote((int) $this->getStep(), 'integer') . " ";
975  }
976 
977  $result = $ilDB->queryF(
978  $queryResultUnit,
979  array('integer', 'integer', 'integer', 'integer'),
980  array($active_id, $pass, $this->getId(), (int) $authorized)
981  );
982  if ($result->numRows()) {
983  while ($row = $ilDB->fetchAssoc($result)) {
984  $ilDB->manipulateF(
985  "DELETE FROM tst_solutions WHERE solution_id = %s AND authorized = %s",
986  array('integer', 'integer'),
987  array($row['solution_id'], (int) $authorized)
988  );
989  }
990  }
991 
992  $this->saveCurrentSolution($active_id, $pass, $matches[1] . "_unit", $value, $authorized);
993  }
994  }
995  });
996 
997  if ($entered_values) {
998  include_once("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
1000  assQuestion::logAction($this->lng->txtlng("assessment", "log_user_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
1001  }
1002  } else {
1003  include_once("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
1005  assQuestion::logAction($this->lng->txtlng("assessment", "log_user_not_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
1006  }
1007  }
1008 
1009  return true;
1010  }
1011 
1012  // fau: testNav - overridden function lookupForExistingSolutions (specific for formula question: don't lookup variables)
1019  public function lookupForExistingSolutions($activeId, $pass)
1020  {
1021  global $DIC;
1022  $ilDB = $DIC['ilDB'];
1023 
1024  $return = array(
1025  'authorized' => false,
1026  'intermediate' => false
1027  );
1028 
1029  $query = "
1030  SELECT authorized, COUNT(*) cnt
1031  FROM tst_solutions
1032  WHERE active_fi = " . $ilDB->quote($activeId, 'integer') . "
1033  AND question_fi = " . $ilDB->quote($this->getId(), 'integer') . "
1034  AND pass = " . $ilDB->quote($pass, 'integer') . "
1035  AND value1 like '\$r%'
1036  AND value2 is not null
1037  AND value2 <> ''
1038  ";
1039 
1040  if ($this->getStep() !== null) {
1041  $query .= " AND step = " . $ilDB->quote((int) $this->getStep(), 'integer') . " ";
1042  }
1043 
1044  $query .= "
1045  GROUP BY authorized
1046  ";
1047 
1048  $result = $ilDB->query($query);
1049 
1050  while ($row = $ilDB->fetchAssoc($result)) {
1051  if ($row['authorized']) {
1052  $return['authorized'] = $row['cnt'] > 0;
1053  } else {
1054  $return['intermediate'] = $row['cnt'] > 0;
1055  }
1056  }
1057  return $return;
1058  }
1059  // fau.
1060 
1061  // fau: testNav - Remove an existing solution (specific for formula question: don't delete variables)
1068  public function removeExistingSolutions($activeId, $pass)
1069  {
1070  global $DIC;
1071  $ilDB = $DIC['ilDB'];
1072 
1073  $query = "
1074  DELETE FROM tst_solutions
1075  WHERE active_fi = " . $ilDB->quote($activeId, 'integer') . "
1076  AND question_fi = " . $ilDB->quote($this->getId(), 'integer') . "
1077  AND pass = " . $ilDB->quote($pass, 'integer') . "
1078  AND value1 like '\$r%'
1079  ";
1080 
1081  if ($this->getStep() !== null) {
1082  $query .= " AND step = " . $ilDB->quote((int) $this->getStep(), 'integer') . " ";
1083  }
1084 
1085  return $ilDB->manipulate($query);
1086  }
1087  // fau.
1088 
1089  protected function savePreviewData(ilAssQuestionPreviewSession $previewSession)
1090  {
1091  $userSolution = $previewSession->getParticipantsSolution();
1092 
1093  foreach ($this->getSolutionSubmit() as $key => $val) {
1094  $matches = null;
1095 
1096  if (preg_match("/^result_(\\\$r\\d+)$/", $key, $matches)) {
1097  $userSolution[$matches[1]] = $val;
1098  } elseif (preg_match("/^result_(\\\$r\\d+)_unit$/", $key, $matches)) {
1099  $userSolution[$matches[1] . "_unit"] = $val;
1100  }
1101  }
1102 
1103  $previewSession->setParticipantsSolution($userSolution);
1104  }
1105 
1110  public function getQuestionType()
1111  {
1112  return "assFormulaQuestion";
1113  }
1114 
1119  public function getAdditionalTableName()
1120  {
1121  return "";
1122  }
1123 
1128  public function getAnswerTableName()
1129  {
1130  return "";
1131  }
1132 
1138  public function deleteAnswers($question_id)
1139  {
1140  global $DIC;
1141  $ilDB = $DIC['ilDB'];
1142 
1143  $affectedRows = $ilDB->manipulateF(
1144  "DELETE FROM il_qpl_qst_fq_var WHERE question_fi = %s",
1145  array('integer'),
1146  array($question_id)
1147  );
1148 
1149  $affectedRows = $ilDB->manipulateF(
1150  "DELETE FROM il_qpl_qst_fq_res WHERE question_fi = %s",
1151  array('integer'),
1152  array($question_id)
1153  );
1154 
1155  $affectedRows = $ilDB->manipulateF(
1156  "DELETE FROM il_qpl_qst_fq_res_unit WHERE question_fi = %s",
1157  array('integer'),
1158  array($question_id)
1159  );
1160 
1161  $affectedRows = $ilDB->manipulateF(
1162  "DELETE FROM il_qpl_qst_fq_ucat WHERE question_fi = %s",
1163  array('integer'),
1164  array($question_id)
1165  );
1166 
1167  $affectedRows = $ilDB->manipulateF(
1168  "DELETE FROM il_qpl_qst_fq_unit WHERE question_fi = %s",
1169  array('integer'),
1170  array($question_id)
1171  );
1172  }
1173 
1178  public function getRTETextWithMediaObjects()
1179  {
1180  $text = parent::getRTETextWithMediaObjects();
1181  return $text;
1182  }
1183 
1187  public function setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
1188  {
1189  parent::setExportDetailsXLS($worksheet, $startrow, $active_id, $pass);
1190 
1191  $solution = $this->getSolutionValues($active_id, $pass);
1192 
1193  $i = 1;
1194  foreach ($solution as $solutionvalue) {
1195  $worksheet->setCell($startrow + $i, 0, $solutionvalue["value1"]);
1196  $worksheet->setBold($worksheet->getColumnCoord(0) . ($startrow + $i));
1197  if (strpos($solutionvalue["value1"], "_unit")) {
1198  $unit = $this->getUnitrepository()->getUnit($solutionvalue["value2"]);
1199  if (is_object($unit)) {
1200  $worksheet->setCell($startrow + $i, 1, $unit->getUnit());
1201  }
1202  } else {
1203  $worksheet->setCell($startrow + $i, 1, $solutionvalue["value2"]);
1204  }
1205  if (preg_match("/(\\\$v\\d+)/", $solutionvalue["value1"], $matches)) {
1206  $var = $this->getVariable($solutionvalue["value1"]);
1207  if (is_object($var) && (is_object($var->getUnit()))) {
1208  $worksheet->setCell($startrow + $i, 2, $var->getUnit()->getUnit());
1209  }
1210  }
1211  $i++;
1212  }
1213 
1214  return $startrow + $i + 1;
1215  }
1216 
1222  public function getBestSolution($solutions)
1223  {
1224  $user_solution = array();
1225 
1226  foreach ($solutions as $idx => $solution_value) {
1227  if (preg_match("/^(\\\$v\\d+)$/", $solution_value["value1"], $matches)) {
1228  $user_solution[$matches[1]] = $solution_value["value2"];
1229  $varObj = $this->getVariable($matches[1]);
1230  $varObj->setValue($solution_value["value2"]);
1231  } elseif (preg_match("/^(\\\$r\\d+)$/", $solution_value["value1"], $matches)) {
1232  if (!array_key_exists($matches[1], $user_solution)) {
1233  $user_solution[$matches[1]] = array();
1234  }
1235  $user_solution[$matches[1]]["value"] = $solution_value["value2"];
1236  } elseif (preg_match("/^(\\\$r\\d+)_unit$/", $solution_value["value1"], $matches)) {
1237  if (!array_key_exists($matches[1], $user_solution)) {
1238  $user_solution[$matches[1]] = array();
1239  }
1240  $user_solution[$matches[1]]["unit"] = $solution_value["value2"];
1241  }
1242  }
1243  foreach ($this->getResults() as $result) {
1244  $resVal = $result->calculateFormula($this->getVariables(), $this->getResults(), parent::getId(), false);
1245 
1246  if (is_object($result->getUnit())) {
1247  $user_solution[$result->getResult()]["unit"] = $result->getUnit()->getId();
1248  $user_solution[$result->getResult()]["value"] = $resVal;
1249  } elseif ($result->getUnit() == null) {
1250  $unit_factor = 1;
1251  // there is no fix result_unit, any "available unit" is accepted
1252 
1253  $available_units = $result->getAvailableResultUnits(parent::getId());
1254  $result_name = $result->getResult();
1255 
1256  if ($available_units[$result_name] != null) {
1257  $check_unit = in_array($user_solution[$result_name]['unit'], $available_units[$result_name]);
1258  }
1259 
1260  if ($check_unit == true) {
1261  //get unit-factor
1262  $unit_factor = assFormulaQuestionUnit::lookupUnitFactor($user_solution[$result_name]['unit']);
1263  }
1264 
1265  try {
1266  $user_solution[$result->getResult()]["value"] = ilMath::_div($resVal, $unit_factor, 55);
1267  } catch (ilMathDivisionByZeroException $ex) {
1268  $user_solution[$result->getResult()]["value"] = 0;
1269  }
1270  }
1271  if ($result->getResultType() == assFormulaQuestionResult::RESULT_CO_FRAC
1272  || $result->getResultType() == assFormulaQuestionResult::RESULT_FRAC) {
1274  if (is_array($value)) {
1275  $user_solution[$result->getResult()]["value"] = $value[0];
1276  $user_solution[$result->getResult()]["frac_helper"] = $value[1];
1277  } else {
1278  $user_solution[$result->getResult()]["value"] = $value;
1279  $user_solution[$result->getResult()]["frac_helper"] = null;
1280  }
1281  } else {
1282  $user_solution[$result->getResult()]["value"] = round($user_solution[$result->getResult()]["value"], $result->getPrecision());
1283  /*
1284  $user_solution[$result->getResult()]["value"] = ilMath::_div(
1285  $user_solution[$result->getResult()]["value"],
1286  1,
1287  $result->getPrecision()
1288  );
1289  */
1290  }
1291  }
1292  return $user_solution;
1293  }
1294 
1295  public function setId($id = -1)
1296  {
1297  parent::setId($id);
1298  $this->unitrepository->setConsumerId($this->getId());
1299  }
1300 
1304  public function __get($value)
1305  {
1306  switch ($value) {
1307  case "resultunits":
1308  return $this->resultunits;
1309  break;
1310  default:
1311  return parent::__get($value);
1312  break;
1313  }
1314  }
1315 
1320  {
1321  $this->unitrepository = $unitrepository;
1322  }
1323 
1327  public function getUnitrepository()
1328  {
1329  return $this->unitrepository;
1330  }
1331 
1335  protected function getSolutionSubmit()
1336  {
1337  $solutionSubmit = array();
1338  foreach ($_POST as $k => $v) {
1339  if (preg_match("/^result_(\\\$r\\d+)$/", $k)) {
1340  $solutionSubmit[$k] = $v;
1341  } elseif (preg_match("/^result_(\\\$r\\d+)_unit$/", $k)) {
1342  $solutionSubmit[$k] = $v;
1343  }
1344  }
1345  return $solutionSubmit;
1346  }
1347 
1348  public function validateSolutionSubmit()
1349  {
1350  foreach ($this->getSolutionSubmit() as $key => $value) {
1351  if (preg_match("/^result_(\\\$r\\d+)$/", $key)) {
1352  if (strlen($value) && !$this->isValidSolutionResultValue($value)) {
1353  ilUtil::sendFailure($this->lng->txt("err_no_numeric_value"), true);
1354  return false;
1355  }
1356  } elseif (preg_match("/^result_(\\\$r\\d+)_unit$/", $key)) {
1357  continue;
1358  }
1359  }
1360 
1361  return true;
1362  }
1363 
1372  public function getOperators($expression)
1373  {
1374  require_once "./Modules/TestQuestionPool/classes/class.ilOperatorsExpressionMapping.php";
1376  }
1377 
1382  public function getExpressionTypes()
1383  {
1384  return array(
1388  );
1389  }
1390 
1399  public function getUserQuestionResult($active_id, $pass)
1400  {
1402  global $DIC;
1403  $ilDB = $DIC['ilDB'];
1404  $result = new ilUserQuestionResult($this, $active_id, $pass);
1405 
1406  $maxStep = $this->lookupMaxStep($active_id, $pass);
1407 
1408  if ($maxStep !== null) {
1409  $data = $ilDB->queryF(
1410  "SELECT value1, value2 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s AND step = %s",
1411  array("integer", "integer", "integer",'integer'),
1412  array($active_id, $pass, $this->getId(), $maxStep)
1413  );
1414  } else {
1415  $data = $ilDB->queryF(
1416  "SELECT value1, value2 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s",
1417  array("integer", "integer", "integer"),
1418  array($active_id, $pass, $this->getId())
1419  );
1420  }
1421 
1422  while ($row = $ilDB->fetchAssoc($data)) {
1423  if (strstr($row["value1"], '$r') && $row["value2"] != null) {
1424  $result->addKeyValue(str_replace('$r', "", $row["value1"]), $row["value2"]);
1425  }
1426  }
1427 
1428  $points = $this->calculateReachedPoints($active_id, $pass);
1429  $max_points = $this->getMaximumPoints();
1430 
1431  $result->setReachedPercentage(($points / $max_points) * 100);
1432 
1433  return $result;
1434  }
1435 
1444  public function getAvailableAnswerOptions($index = null)
1445  {
1446  if ($index !== null) {
1447  return $this->getResult('$r' . ($index + 1));
1448  } else {
1449  return $this->getResults();
1450  }
1451  }
1452 }
getAvailableAnswerOptions($index=null)
If index is null, the function returns an array with all anwser options Else it returns the specific ...
static logAction($logtext="", $active_id="", $question_id="")
Logs an action into the Test&Assessment log.
addResultUnits($result, $unit_ids)
getId()
Gets the id of the assQuestion object.
static prepareFormOutput($a_str, $a_strip=false)
prepares string output for html forms public
static _getOriginalId($question_id)
Returns the original id of a question.
setSuggestedSolution($solution_id="", $subquestion_index=0, $is_import=false)
Sets a suggested solution for the question.
Class iQuestionCondition.
static _getPass($active_id)
Retrieves the actual pass of a given user for a given test.
$result
$template
global $DIC
Definition: saml.php:7
saveToDb($original_id="")
Saves a assFormulaQuestion object to a database public.
duplicate($for_test=true, $title="", $author="", $owner="", $testObjId=null)
Duplicates an assFormulaQuestion public.
substituteVariables(array $userdata, $graphicalOutput=false, $forsolution=false, $result_output=false)
Abstract basic class which is to be extended by the concrete assessment question type classes...
lookupForExistingSolutions($activeId, $pass)
Lookup if an authorized or intermediate solution exists.
getAdditionalTableName()
Returns the name of the additional question data table in the database.
setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
{}
ensureNonNegativePoints($points)
getSolutionValues($active_id, $pass=null, $authorized=true)
Loads solutions of a given user from the database an returns it.
Class ilUnitConfigurationRepository.
getSolutionMaxPass($active_id)
Returns the maximum pass a users question solution.
static _div($left_operand, $right_operand, $scale=50)
Class for single choice questions assFormulaQuestion is a class for single choice questions...
setEstimatedWorkingTime($hour=0, $min=0, $sec=0)
Sets the estimated working time of a question from given hour, minute and second. ...
getAnswerTableName()
Returns the name of the answer table in the database.
$index
Definition: metadata.php:60
getRTETextWithMediaObjects()
Collects all text in the question which could contain media objects which were created with the Rich ...
getUserQuestionResult($active_id, $pass)
Get the user solution for a question by active_id and the test pass.
setAdditionalContentEditingMode($additinalContentEditingMode)
setter for additional content editing mode for this 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...
getOperators($expression)
Get all available operations for a specific question.
getObjId()
Get the object id of the container object.
__construct( $title="", $comment="", $author="", $owner=-1, $question="")
assFormulaQuestion constructor The constructor takes possible arguments an creates an instance of the...
static _getLogLanguage()
retrieve the log language for assessment logging
setAuthor($author="")
Sets the authors name of the assQuestion object.
static _enabledAssessmentLogging()
check wether assessment logging is enabled or not
Class ilUserQuestionResult.
saveCurrentSolution($active_id, $pass, $value1, $value2, $authorized=true, $tstamp=null)
static getImagePath($img, $module_path="", $mode="output", $offline=false)
get image path (for images located in a template directory)
getBestSolution($solutions)
Returns the best solution for a given pass of a participant.
deleteAnswers($question_id)
Deletes datasets from answers tables.
hasRequiredVariableSolutionValues(array $userSolution)
__get($value)
Object getter.
special template class to simplify handling of ITX/PEAR
saveWorkingData($active_id, $pass=null, $authorized=true)
Saves the learners input of the question to the database.
$text
Definition: errorreport.php:18
loadFromDb($question_id)
Loads a assFormulaQuestion object from a database.
getQuestion()
Gets the question string of the question object.
calculateReachedPoints($active_id, $pass=null, $authorizedSolution=true, $returndetails=false)
Returns the points, a learner has reached answering the question The points are calculated from the g...
isValidSolutionResultValue($submittedValue)
$query
canUseAdvancedRating($result)
Check if advanced rating can be used for a result.
createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle="")
copyObject($target_questionpool_id, $title="")
Copies an assFormulaQuestion object public.
static sendFailure($a_info="", $a_keep=false)
Send Failure Message to Screen.
$row
deductHintPointsFromReachedPoints(ilAssQuestionPreviewSession $previewSession, $reachedPoints)
setPoints($a_points)
Sets the maximum available points for the question.
saveQuestionDataToDb($original_id="")
getQuestionType()
Returns the question type of the question.
setQuestion($question="")
Sets the question string of the question object.
isComplete()
Returns true, if the question is complete for use.
global $ilDB
setOriginalId($original_id)
calculateReachedPointsFromPreviewSession(ilAssQuestionPreviewSession $previewSession)
$i
Definition: disco.tpl.php:19
hasResultUnit($result, $unit_id)
getExpressionTypes()
Get all available expression types for a specific question.
removeExistingSolutions($activeId, $pass)
Remove an existing solution without removing the variables.
setTitle($title="")
Sets the title string of the assQuestion object.
setObjId($obj_id=0)
Set the object id of the container object.
setUnitrepository($unitrepository)
$key
Definition: croninfo.php:18
setComment($comment="")
Sets the comment string of the assQuestion object.
$_POST["username"]
static convertDecimalToCoprimeFraction($decimal_value, $tolerance=1.e-9)
getMaximumPoints()
Returns the maximum points, a learner can reach answering the question.
setOwner($owner="")
Sets the creator/owner ID of the assQuestion object.
savePreviewData(ilAssQuestionPreviewSession $previewSession)
$data
Definition: bench.php:6