ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
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  function __construct(
42  $title = "",
43  $comment = "",
44  $author = "",
45  $owner = -1,
46  $question = ""
47  )
48  {
49  parent::__construct($title, $comment, $author, $owner, $question);
50  $this->variables = array();
51  $this->results = array();
52  $this->resultunits = array();
53  $this->unitrepository = new ilUnitConfigurationRepository(0);
54 
55  }
56 
57  public function clearVariables()
58  {
59  $this->variables = array();
60  }
61 
62  public function getVariables()
63  {
64  return $this->variables;
65  }
66 
67  public function getVariable($variable)
68  {
69  if(array_key_exists($variable, $this->variables))
70  {
71  return $this->variables[$variable];
72  }
73  return null;
74  }
75 
76  public function addVariable($variable)
77  {
78  $this->variables[$variable->getVariable()] = $variable;
79  }
80 
81  public function clearResults()
82  {
83  $this->results = array();
84  }
85 
86  public function getResults()
87  {
88  return $this->results;
89  }
90 
91  public function getResult($result)
92  {
93  if(array_key_exists($result, $this->results))
94  {
95  return $this->results[$result];
96  }
97  return null;
98  }
99 
100  public function addResult($result)
101  {
102  $this->results[$result->getResult()] = $result;
103  }
104 
105  public function addResultUnits($result, $unit_ids)
106  {
107  $this->resultunits[$result->getResult()] = array();
108  if((!is_object($result)) || (!is_array($unit_ids))) return;
109  foreach($unit_ids as $id)
110  {
111  if(is_numeric($id) && ($id > 0)) $this->resultunits[$result->getResult()][$id] = $this->getUnitrepository()->getUnit($id);
112  }
113  }
114 
115  public function addResultUnit($result, $unit)
116  {
117  if(is_object($result) && is_object($unit))
118  {
119  if(!is_array($this->resultunits[$result->getResult()]))
120  {
121  $this->resultunits[$result->getResult()] = array();
122  }
123  $this->resultunits[$result->getResult()][$unit->getId()] = $unit;
124 
125  }
126  }
127 
128  public function getResultUnits($result)
129  {
130  if(array_key_exists($result->getResult(), $this->resultunits))
131  {
132  return $this->resultunits[$result->getResult()];
133  }
134  else
135  {
136  return array();
137  }
138  }
139 
140  public function hasResultUnit($result, $unit_id)
141  {
142  if(array_key_exists($result->getResult(), $this->resultunits))
143  {
144  if(array_key_exists($unit_id, $this->resultunits[$result->getResult()]))
145  {
146  return TRUE;
147  }
148  }
149 
150  return FALSE;
151  }
152 
153  public function parseQuestionText()
154  {
155  $this->clearResults();
156  $this->clearVariables();
157  if(preg_match_all("/(\\\$v\\d+)/ims", $this->getQuestion(), $matches))
158  {
159  foreach($matches[1] as $variable)
160  {
161  $varObj = new assFormulaQuestionVariable($variable, 0, 0, null, 0);
162  $this->addVariable($varObj);
163  }
164  }
165 
166  if(preg_match_all("/(\\\$r\\d+)/ims", $this->getQuestion(), $rmatches))
167  {
168  foreach($rmatches[1] as $result)
169  {
170  $resObj = new assFormulaQuestionResult($result, NULL, NULL, 0, -1, NULL, 1, 1, TRUE);
171  $this->addResult($resObj);
172  }
173  }
174  }
175 
176  public function checkForDuplicateVariables()
177  {
178  if(preg_match_all("/(\\\$v\\d+)/ims", $this->getQuestion(), $matches))
179  {
180  if((count(array_unique($matches[1]))) != count($matches[1])) return false;
181  }
182  return true;
183  }
184 
185  public function checkForDuplicateResults()
186  {
187  if(preg_match_all("/(\\\$r\\d+)/ims", $this->getQuestion(), $rmatches))
188  {
189  if((count(array_unique($rmatches[1]))) != count($rmatches[1])) return false;
190  }
191  return true;
192  }
193 
198  public function fetchAllResults($questionText)
199  {
200  $resObjects = array();
201  $matches = null;
202 
203  if(preg_match_all("/(\\\$r\\d+)/ims", $questionText, $matches))
204  {
205  foreach($matches[1] as $resultKey)
206  {
207  $resObjects[] = $this->getResult($resultKey);
208  }
209  }
210 
211  return $resObjects;
212  }
213 
218  public function fetchAllVariables($questionText)
219  {
220  $varObjects = array();
221  $matches = null;
222 
223  if(preg_match_all("/(\\\$v\\d+)/ims", $questionText, $matches))
224  {
225  foreach($matches[1] as $variableKey)
226  {
227  $varObjects[] = $this->getVariable($variableKey);
228  }
229  }
230 
231  return $varObjects;
232  }
233 
238  public function hasRequiredVariableSolutionValues(array $userSolution)
239  {
240  foreach($this->fetchAllVariables($this->getQuestion()) as $varObj)
241  {
242  if( !isset($userSolution[$varObj->getVariable()]) )
243  {
244  return false;
245  }
246 
247  if( !strlen($userSolution[$varObj->getVariable()]) )
248  {
249  return false;
250  }
251  }
252 
253  return true;
254  }
255 
260  {
261  foreach($this->fetchAllResults($this->getQuestion()) as $resObj)
262  {
263  $resObj->findValidRandomVariables($this->getVariables(), $this->getResults());
264  }
265 
266  $variableSolutionValues = array();
267 
268  foreach($this->fetchAllVariables($this->getQuestion()) as $varObj)
269  {
270  $variableSolutionValues[$varObj->getVariable()] = $varObj->getValue();
271  }
272 
273  return $variableSolutionValues;
274  }
275 
284  public function substituteVariables(array $userdata, $graphicalOutput = FALSE, $forsolution = FALSE, $result_output = FALSE)
285  {
286  if((count($this->results) == 0) && (count($this->variables) == 0))
287  return false;
288 
289  $text = $this->getQuestion();
290 
291  foreach($this->fetchAllVariables($this->getQuestion()) as $varObj)
292  {
293  if( isset($userdata[$varObj->getVariable()]) && strlen($userdata[$varObj->getVariable()]) )
294  {
295  $varObj->setValue( $userdata[$varObj->getVariable()] );
296  }
297 
298  $unit = (is_object($varObj->getUnit())) ? $varObj->getUnit()->getUnit() : "";
299  $val = (strlen($varObj->getValue()) > 8) ? strtoupper(sprintf("%e", $varObj->getValue())) : $varObj->getValue();
300 
301  $text = preg_replace("/\\$" . substr($varObj->getVariable(), 1) . "(?![0-9]+)/", $val . " " . $unit . "\\1", $text);
302  }
303 
304  if(preg_match_all("/(\\\$r\\d+)/ims", $this->getQuestion(), $rmatches))
305  {
306  foreach($rmatches[1] as $result)
307  {
308  $resObj = $this->getResult($result);
309  $value = "";
310  $frac_helper = '';
311  $user_data[$result]['result_type'] = $resObj->getResultType();
312 
313  if(
314  $resObj->getResultType() == assFormulaQuestionResult::RESULT_FRAC ||
315  $resObj->getResultType() == assFormulaQuestionResult::RESULT_CO_FRAC
316  )
317  {
318  $is_frac = true;
319  }
320  if(is_array($userdata))
321  {
322  if(is_array($userdata[$result]))
323  {
324  if($forsolution && $result_output)
325  {
326  $value_org = $resObj->calculateFormula($this->getVariables(), $this->getResults(), parent::getId());
327  $value = sprintf("%." . $resObj->getPrecision() . "f", $value_org);
328  if($is_frac)
329  {
331  if(is_array($value))
332  {
333  $frac_helper = $value[1];
334  $value = $value[0];
335  }
336  }
337  }
338  else
339  {
340  if($forsolution)
341  {
342  $value = $userdata[$result]["value"];
343  }
344  else
345  {
346  $value = ' value="' . $userdata[$result]["value"] . '"';
347  }
348  }
349  }
350  }
351  else
352  {
353  if($forsolution)
354  {
355  $value = $resObj->calculateFormula($this->getVariables(), $this->getResults(), parent::getId());
356  $value = sprintf("%." . $resObj->getPrecision() . "f", $value);
357 
358  if($is_frac)
359  {
361  if(is_array($value))
362  {
363  $frac_helper = $value[1];
364  $value = $value[0];
365  }
366  $value = ' value="' . $value . '"';
367  }
368  }
369  else
370  {
371  // Precision fix for Preview by tjoussen
372  // If all default values are set, this function is called in getPreview
373  $use_precision = !($userdata == null && $graphicalOutput == FALSE && $forsolution == FALSE && $result_output == FALSE);
374 
375  $val = $resObj->calculateFormula($this->getVariables(), $this->getResults(), parent::getId(), $use_precision);
376 
377  if($resObj->getResultType() == assFormulaQuestionResult::RESULT_FRAC
378  ||$resObj->getResultType() == assFormulaQuestionResult::RESULT_CO_FRAC)
379  {
380  $val = $resObj->convertDecimalToCoprimeFraction($val);
381  if(is_array($val))
382  {
383  $frac_helper = $val[1];
384  $val = $val[0];
385  }
386  }
387  else
388  {
389  $val = sprintf("%." . $resObj->getPrecision() . "f", $val);
390  $val = (strlen($val) > 8) ? strtoupper(sprintf("%e", $val)) : $val;
391  }
392  $value = ' value="' . $val . '"';
393  }
394  }
395 
396  if($forsolution)
397  {
398  $input = '<span class="ilc_qinput_TextInput solutionbox">' . ilUtil::prepareFormOutput($value) . '</span>';
399  }
400  else
401  {
402  $input = '<input class="ilc_qinput_TextInput" type="text" spellcheck="false" autocomplete="off" autocorrect="off" autocapitalize="off" name="result_' . $result . '"' . $value . ' />';
403  }
404 
405  $units = "";
406  if(count($this->getResultUnits($resObj)) > 0)
407  {
408  if($forsolution)
409  {
410  if(is_array($userdata))
411  {
412  foreach($this->getResultUnits($resObj) as $unit)
413  {
414  if($userdata[$result]["unit"] == $unit->getId())
415  {
416  $units = $unit->getUnit();
417  }
418  }
419  }
420  else
421  {
422  if($resObj->getUnit())
423  {
424  $units = $resObj->getUnit()->getUnit();
425  }
426  }
427  }
428  else
429  {
430  $units = '<select name="result_' . $result . '_unit">';
431  $units .= '<option value="-1">' . $this->lng->txt("select_unit") . '</option>';
432  foreach($this->getResultUnits($resObj) as $unit)
433  {
434  $units .= '<option value="' . $unit->getId() . '"';
435  if((is_array($userdata[$result])) && (strlen($userdata[$result]["unit"])))
436  {
437  if($userdata[$result]["unit"] == $unit->getId())
438  {
439  $units .= ' selected="selected"';
440  }
441  }
442  $units .= '>' . $unit->getUnit() . '</option>';
443  }
444  $units .= '</select>';
445  }
446  }
447  else
448  {
449  $units = "";
450  }
451  switch($resObj->getResultType())
452  {
454  $units .= ' ' . $this->lng->txt('expected_result_type') . ': ' . $this->lng->txt('result_dec');
455  break;
457  if(strlen($frac_helper))
458  {
459  $units .= ' &asymp; ' . $frac_helper . ', ';
460  }
461  elseif (is_array($userdata) && isset($userdata[$result]) && strlen($userdata[$result]["frac_helper"]))
462  {
463  if(!preg_match('-/-', $value))
464  {
465  $units .= ' &asymp; ' . $userdata[$result]["frac_helper"] . ', ';
466  }
467  }
468  $units .= ' ' . $this->lng->txt('expected_result_type') . ': ' . $this->lng->txt('result_frac');
469  break;
471  if(strlen($frac_helper))
472  {
473  $units .= ' &asymp; ' . $frac_helper . ', ';
474  }
475  elseif (is_array($userdata) && isset($userdata[$result]) && strlen($userdata[$result]["frac_helper"]))
476  {
477  if(!preg_match('-/-', $value))
478  {
479  $units .= ' &asymp; ' . $userdata[$result]["frac_helper"] . ', ';
480  }
481  }
482  $units .= ' ' . $this->lng->txt('expected_result_type') . ': ' . $this->lng->txt('result_co_frac');
483  break;
485  break;
486  }
487  $checkSign = "";
488  if($graphicalOutput)
489  {
490  $resunit = null;
491  $user_value = '';
492  if(is_array($userdata) && is_array($userdata[$result]))
493  {
494  if($userdata[$result]["unit"] > 0)
495  {
496  $resunit = $this->getUnitrepository()->getUnit($userdata[$result]["unit"]);
497  }
498 
499  if(isset($userdata[$result]["value"]))
500  {
501  $user_value = $userdata[$result]["value"];
502  }
503  }
504 
505  $template = new ilTemplate("tpl.il_as_qpl_formulaquestion_output_solution_image.html", true, true, 'Modules/TestQuestionPool');
506 
507  if($resObj->isCorrect($this->getVariables(), $this->getResults(), $user_value, $resunit))
508  {
509  $template->setCurrentBlock("icon_ok");
510  $template->setVariable("ICON_OK", ilUtil::getImagePath("icon_ok.svg"));
511  $template->setVariable("TEXT_OK", $this->lng->txt("answer_is_right"));
512  $template->parseCurrentBlock();
513  }
514  else
515  {
516  $template->setCurrentBlock("icon_not_ok");
517  $template->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_not_ok.svg"));
518  $template->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_wrong"));
519  $template->parseCurrentBlock();
520  }
521  $checkSign = $template->get();
522  }
523  $resultOutput = "";
524  if($result_output)
525  {
526  $template = new ilTemplate("tpl.il_as_qpl_formulaquestion_output_solution_result.html", true, true, 'Modules/TestQuestionPool');
527 
528  if(is_array($userdata))
529  {
530  $found = $resObj->getResultInfo($this->getVariables(), $this->getResults(), $userdata[$resObj->getResult()]["value"], $userdata[$resObj->getResult()]["unit"], $this->getUnitrepository()->getUnits());
531  }
532  else
533  {
534  $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());
535  }
536  $resulttext = "(";
537  if($resObj->getRatingSimple())
538  {
539  if($frac_helper)
540  {
541  $resulttext .="n/a";
542  }
543  else
544  {
545  $resulttext .= $found['points'] . " " . (($found['points'] == 1) ? $this->lng->txt('point') : $this->lng->txt('points'));
546  }
547  }
548  else
549  {
550  $resulttext .= $this->lng->txt("rated_sign") . " " . (($found['sign']) ? $found['sign'] : 0) . " " . (($found['sign'] == 1) ? $this->lng->txt('point') : $this->lng->txt('points')) . ", ";
551  $resulttext .= $this->lng->txt("rated_value") . " " . (($found['value']) ? $found['value'] : 0) . " " . (($found['value'] == 1) ? $this->lng->txt('point') : $this->lng->txt('points')) . ", ";
552  $resulttext .= $this->lng->txt("rated_unit") . " " . (($found['unit']) ? $found['unit'] : 0) . " " . (($found['unit'] == 1) ? $this->lng->txt('point') : $this->lng->txt('points'));
553  }
554 
555  $resulttext .= ")";
556  $template->setVariable("RESULT_OUTPUT", $resulttext);
557 
558  $resultOutput = $template->get();
559  }
560  $text = preg_replace("/\\\$" . substr($result, 1) . "(?![0-9]+)/", $input . " " . $units . " " . $checkSign . " " . $resultOutput . " " . "\\1", $text);
561  }
562  }
563  return $text;
564  }
565 
572  public function canUseAdvancedRating($result)
573  {
574  $result_units = $this->getResultUnits($result);
575  $resultunit = $result->getUnit();
576  $similar_units = 0;
577  foreach($result_units as $unit)
578  {
579  if(is_object($resultunit))
580  {
581  if($resultunit->getId() != $unit->getId())
582  {
583  if($resultunit->getBaseUnit() && $unit->getBaseUnit())
584  {
585  if($resultunit->getBaseUnit() == $unit->getBaseUnit()) return false;
586  }
587  if($resultunit->getBaseUnit())
588  {
589  if($resultunit->getBaseUnit() == $unit->getId()) return false;
590  }
591  if($unit->getBaseUnit())
592  {
593  if($unit->getBaseUnit() == $resultunit->getId()) return false;
594  }
595  }
596  }
597  }
598  return true;
599  }
600 
605  public function isComplete()
606  {
607  if(($this->title) and ($this->author) and ($this->question) and ($this->getMaximumPoints() > 0))
608  {
609  return true;
610  }
611  else
612  {
613  return false;
614  }
615  }
616 
621  function saveToDb($original_id = "")
622  {
623  global $ilDB;
624 
626  // save variables
627  $affectedRows = $ilDB->manipulateF("
628  DELETE FROM il_qpl_qst_fq_var
629  WHERE question_fi = %s",
630  array("integer"),
631  array($this->getId())
632  );
633 
634  foreach($this->variables as $variable)
635  {
636  $next_id = $ilDB->nextId('il_qpl_qst_fq_var');
637  $ilDB->insert('il_qpl_qst_fq_var',
638  array(
639  'variable_id' => array('integer', $next_id),
640  'question_fi' => array('integer', $this->getId()),
641  'variable' => array('text', $variable->getVariable()),
642  'range_min' => array('float', ((strlen($variable->getRangeMin())) ? $variable->getRangeMin() : 0.0)),
643  'range_max' => array('float', ((strlen($variable->getRangeMax())) ? $variable->getRangeMax() : 0.0)),
644  'unit_fi' => array('integer', (is_object($variable->getUnit()) ? (int)$variable->getUnit()->getId() : 0)),
645  'varprecision' => array('integer', (int)$variable->getPrecision()),
646  'intprecision' => array('integer', (int)$variable->getIntprecision()),
647  'range_min_txt' => array('text', $variable->getRangeMinTxt()),
648  'range_max_txt' => array('text', $variable->getRangeMaxTxt())
649  ));
650 
651  }
652  // save results
653  $affectedRows = $ilDB->manipulateF("DELETE FROM il_qpl_qst_fq_res WHERE question_fi = %s",
654  array("integer"),
655  array($this->getId())
656  );
657 
658  foreach($this->results as $result)
659  {
660  $next_id = $ilDB->nextId('il_qpl_qst_fq_res');
661  if( is_object($result->getUnit()))
662  {
663  $tmp_result_unit = $result->getUnit()->getId();
664  }
665  else
666  {
667  $tmp_result_unit = NULL;
668  }
669 
670  $formula = str_replace(",", ".", $result->getFormula());
671 
672  $ilDB->insert("il_qpl_qst_fq_res", array(
673  "result_id" => array("integer", $next_id),
674  "question_fi" => array("integer", $this->getId()),
675  "result" => array("text", $result->getResult()),
676  "range_min" => array("float", ((strlen($result->getRangeMin())) ? $result->getRangeMin() : 0)),
677  "range_max" => array("float", ((strlen($result->getRangeMax())) ? $result->getRangeMax() : 0)),
678  "tolerance" => array("float", ((strlen($result->getTolerance())) ? $result->getTolerance() : 0)),
679  "unit_fi" => array("integer", (int)$tmp_result_unit),
680  "formula" => array("clob", $formula),
681  "resprecision" => array("integer", $result->getPrecision()),
682  "rating_simple" => array("integer", ($result->getRatingSimple()) ? 1 : 0),
683  "rating_sign" => array("float", ($result->getRatingSimple()) ? 0 : $result->getRatingSign()),
684  "rating_value" => array("float", ($result->getRatingSimple()) ? 0 : $result->getRatingValue()),
685  "rating_unit" => array("float", ($result->getRatingSimple()) ? 0 : $result->getRatingUnit()),
686  "points" => array("float", $result->getPoints()),
687  "result_type" => array('integer', (int)$result->getResultType()),
688  "range_min_txt" => array("text", $result->getRangeMinTxt()),
689  "range_max_txt" => array("text", $result->getRangeMaxTxt())
690 
691  ));
692  }
693  // save result units
694  $affectedRows = $ilDB->manipulateF("DELETE FROM il_qpl_qst_fq_res_unit WHERE question_fi = %s",
695  array("integer"),
696  array($this->getId())
697  );
698  foreach($this->results as $result)
699  {
700  foreach($this->getResultUnits($result) as $unit)
701  {
702  $next_id = $ilDB->nextId('il_qpl_qst_fq_res_unit');
703  $affectedRows = $ilDB->manipulateF("INSERT INTO il_qpl_qst_fq_res_unit (result_unit_id, question_fi, result, unit_fi) VALUES (%s, %s, %s, %s)",
704  array('integer', 'integer', 'text', 'integer'),
705  array(
706  $next_id,
707  $this->getId(),
708  $result->getResult(),
709  $unit->getId()
710  )
711  );
712  }
713  }
714 
715  parent::saveToDb();
716  }
717 
722  public function loadFromDb($question_id)
723  {
724  global $ilDB;
725 
726  $result = $ilDB->queryF("SELECT qpl_questions.* FROM qpl_questions WHERE question_id = %s",
727  array('integer'),
728  array($question_id)
729  );
730  if($result->numRows() == 1)
731  {
732  $data = $ilDB->fetchAssoc($result);
733  $this->setId($question_id);
734  $this->setTitle($data["title"]);
735  $this->setComment($data["description"]);
736  $this->setSuggestedSolution($data["solution_hint"]);
737  $this->setPoints($data['points']);
738  $this->setOriginalId($data["original_id"]);
739  $this->setObjId($data["obj_fi"]);
740  $this->setAuthor($data["author"]);
741  $this->setOwner($data["owner"]);
742 
743  try
744  {
745  $this->setAdditionalContentEditingMode($data['add_cont_edit_mode']);
746  }
748  {
749  }
750 
751  $this->unitrepository = new ilUnitConfigurationRepository($question_id);
752 
753  include_once("./Services/RTE/classes/class.ilRTE.php");
754  $this->setQuestion(ilRTE::_replaceMediaObjectImageSrc($data["question_text"], 1));
755  $this->setEstimatedWorkingTime(substr($data["working_time"], 0, 2), substr($data["working_time"], 3, 2), substr($data["working_time"], 6, 2));
756 
757  // load variables
758  $result = $ilDB->queryF("SELECT * FROM il_qpl_qst_fq_var WHERE question_fi = %s",
759  array('integer'),
760  array($question_id)
761  );
762  if($result->numRows() > 0)
763  {
764  while($data = $ilDB->fetchAssoc($result))
765  {
766  $varObj = new assFormulaQuestionVariable($data["variable"], $data["range_min"], $data["range_max"], $this->getUnitrepository()->getUnit($data["unit_fi"]), $data["varprecision"], $data["intprecision"]);
767  $varObj->setRangeMinTxt($data['range_min_txt']);
768  $varObj->setRangeMaxTxt($data['range_max_txt']);
769  $this->addVariable($varObj);
770  }
771  }
772  // load results
773  $result = $ilDB->queryF("SELECT * FROM il_qpl_qst_fq_res WHERE question_fi = %s",
774  array('integer'),
775  array($question_id)
776  );
777  if($result->numRows() > 0)
778  {
779  while($data = $ilDB->fetchAssoc($result))
780  {
781  $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"]);
782  $resObj->setResultType($data['result_type']);
783  $resObj->setRangeMinTxt($data['range_min_txt']);
784  $resObj->setRangeMaxTxt($data['range_max_txt']);
785  $this->addResult($resObj);
786  }
787  }
788 
789  // load result units
790  $result = $ilDB->queryF("SELECT * FROM il_qpl_qst_fq_res_unit WHERE question_fi = %s",
791  array('integer'),
792  array($question_id)
793  );
794  if($result->numRows() > 0)
795  {
796  while($data = $ilDB->fetchAssoc($result))
797  {
798  $unit = $this->getUnitrepository()->getUnit($data["unit_fi"]);
799  $resObj = $this->getResult($data["result"]);
800  $this->addResultUnit($resObj, $unit);
801  }
802  }
803  }
804  parent::loadFromDb($question_id);
805  }
806 
811  function duplicate($for_test = true, $title = "", $author = "", $owner = "", $testObjId = null)
812  {
813  if ($this->id <= 0)
814  {
815  // The question has not been saved. It cannot be duplicated
816  return;
817  }
818  // duplicate the question in database
819  $this_id = $this->getId();
820  $thisObjId = $this->getObjId();
821 
822  $clone = $this;
823  include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
825  $clone->id = -1;
826 
827  if( (int)$testObjId > 0 )
828  {
829  $clone->setObjId($testObjId);
830  }
831 
832  if ($title)
833  {
834  $clone->setTitle($title);
835  }
836 
837  if ($author)
838  {
839  $clone->setAuthor($author);
840  }
841  if ($owner)
842  {
843  $clone->setOwner($owner);
844  }
845 
846  if ($for_test)
847  {
848  $clone->saveToDb($original_id);
849  }
850  else
851  {
852  $clone->saveToDb();
853  }
854 
855  $clone->unitrepository->cloneUnits($this_id, $clone->getId());
856 
857  // copy question page content
858  $clone->copyPageOfQuestion($this_id);
859  // copy XHTML media objects
860  $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
861  $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
862 
863  return $clone->id;
864  }
865 
870  function copyObject($target_questionpool_id, $title = "")
871  {
872  if ($this->id <= 0)
873  {
874  // The question has not been saved. It cannot be duplicated
875  return;
876  }
877  // duplicate the question in database
878  $clone = $this;
879  include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
881  $clone->id = -1;
882  $source_questionpool_id = $this->getObjId();
883  $clone->setObjId($target_questionpool_id);
884  if ($title)
885  {
886  $clone->setTitle($title);
887  }
888  $clone->saveToDb();
889 
890  $clone->unitrepository->cloneUnits($original_id, $clone->getId());
891 
892  // copy question page content
893  $clone->copyPageOfQuestion($original_id);
894  // copy XHTML media objects
895  $clone->copyXHTMLMediaObjectsOfQuestion($original_id);
896 
897  $clone->onCopy($source_questionpool_id, $original_id, $clone->getObjId(), $clone->getId());
898 
899  return $clone->id;
900  }
901 
902  public function createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle = "")
903  {
904  if ($this->id <= 0)
905  {
906  // The question has not been saved. It cannot be duplicated
907  return;
908  }
909 
910  include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
911 
912  $sourceQuestionId = $this->id;
913  $sourceParentId = $this->getObjId();
914 
915  // duplicate the question in database
916  $clone = $this;
917  $clone->id = -1;
918 
919  $clone->setObjId($targetParentId);
920 
921  if ($targetQuestionTitle)
922  {
923  $clone->setTitle($targetQuestionTitle);
924  }
925 
926  $clone->saveToDb();
927  // copy question page content
928  $clone->copyPageOfQuestion($sourceQuestionId);
929  // copy XHTML media objects
930  $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
931 
932  $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
933 
934  return $clone->id;
935  }
936 
941  public function getMaximumPoints()
942  {
943  $points = 0;
944  foreach($this->results as $result)
945  {
946  $points += $result->getPoints();
947  }
948  return $points;
949  }
950 
959  function calculateReachedPoints($active_id, $pass = NULL, $authorizedSolution = true, $returndetails = false)
960  {
961  if(is_null($pass))
962  {
963  $pass = $this->getSolutionMaxPass($active_id);
964  }
965  $solutions =& $this->getSolutionValues($active_id, $pass, $authorizedSolution);
966  $user_solution = array();
967  foreach($solutions as $idx => $solution_value)
968  {
969  if(preg_match("/^(\\\$v\\d+)$/", $solution_value["value1"], $matches))
970  {
971  $user_solution[$matches[1]] = $solution_value["value2"];
972  $varObj = $this->getVariable($solution_value["value1"]);
973  $varObj->setValue($solution_value["value2"]);
974  }
975  else if(preg_match("/^(\\\$r\\d+)$/", $solution_value["value1"], $matches))
976  {
977  if(!array_key_exists($matches[1], $user_solution)) $user_solution[$matches[1]] = array();
978  $user_solution[$matches[1]]["value"] = $solution_value["value2"];
979  }
980  else if(preg_match("/^(\\\$r\\d+)_unit$/", $solution_value["value1"], $matches))
981  {
982  if(!array_key_exists($matches[1], $user_solution)) $user_solution[$matches[1]] = array();
983  $user_solution[$matches[1]]["unit"] = $solution_value["value2"];
984  }
985  }
986  //vd($this->getResults());
987  $points = 0;
988  foreach($this->getResults() as $result)
989  {
990  //vd($user_solution[$result->getResult()]["value"]);
991  $points += $result->getReachedPoints($this->getVariables(), $this->getResults(), $user_solution[$result->getResult()]["value"], $user_solution[$result->getResult()]["unit"], $this->unitrepository->getUnits());
992  }
993 
994  return $points;
995  }
996 
998  {
999  $user_solution = $previewSession->getParticipantsSolution();
1000 
1001  $points = 0;
1002  foreach($this->getResults() as $result)
1003  {
1004  $v = isset($user_solution[$result->getResult()]) ? $user_solution[$result->getResult()] : null;
1005  $u = isset($user_solution[$result->getResult().'_unit']) ? $user_solution[$result->getResult().'_unit'] : null;
1006 
1007  $points += $result->getReachedPoints(
1008  $this->getVariables(),
1009  $this->getResults(),
1010  $v,
1011  $u,
1012  $this->unitrepository->getUnits());
1013  }
1014 
1015  $reachedPoints = $this->deductHintPointsFromReachedPoints($previewSession, $points);
1016 
1017  return $this->ensureNonNegativePoints($reachedPoints);
1018  }
1019 
1020  protected function isValidSolutionResultValue($submittedValue)
1021  {
1022  $submittedValue = str_replace(',', '.', $submittedValue);
1023 
1024  if( is_numeric($submittedValue) )
1025  {
1026  return true;
1027  }
1028 
1029  if( preg_match('/^[-+]{0,1}\d+\/\d+$/', $submittedValue) )
1030  {
1031  return true;
1032  }
1033 
1034  return false;
1035  }
1036 
1044  function saveWorkingData($active_id, $pass = NULL, $authorized = true)
1045  {
1046  global $ilDB;
1047 
1048  if(is_null($pass))
1049  {
1050  include_once "./Modules/Test/classes/class.ilObjTest.php";
1051  $pass = ilObjTest::_getPass($active_id);
1052  }
1053 
1054  $entered_values = false;
1055 
1056  $this->getProcessLocker()->executeUserSolutionUpdateLockOperation(function() use (&$entered_values, $ilDB, $active_id, $pass, $authorized) {
1057 
1058  $solutionSubmit = $this->getSolutionSubmit();
1059  foreach($solutionSubmit as $key => $value)
1060  {
1061  $matches = null;
1062  if(preg_match("/^result_(\\\$r\\d+)$/", $key, $matches))
1063  {
1064  if(strlen($value))
1065  {
1066  $entered_values = TRUE;
1067  }
1068 
1069  $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]);
1070 
1071  if( $this->getStep() !== NULL )
1072  {
1073  $queryResult .= " AND step = " . $ilDB->quote((int)$this->getStep(), 'integer') . " ";
1074  }
1075 
1076  $result = $ilDB->queryF(
1077  $queryResult,
1078  array('integer', 'integer', 'integer', 'integer'),
1079  array($active_id, $pass, $this->getId(), (int)$authorized)
1080  );
1081  if($result->numRows())
1082  {
1083  while($row = $ilDB->fetchAssoc($result))
1084  {
1085  $ilDB->manipulateF("DELETE FROM tst_solutions WHERE solution_id = %s AND authorized = %s",
1086  array('integer', 'integer'),
1087  array($row['solution_id'], (int)$authorized)
1088  );
1089  }
1090  }
1091 
1092  $this->saveCurrentSolution($active_id,$pass,$matches[1],str_replace(",", ".", $value), $authorized);
1093  }
1094  else if(preg_match("/^result_(\\\$r\\d+)_unit$/", $key, $matches))
1095  {
1096  $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");
1097 
1098  if( $this->getStep() !== NULL )
1099  {
1100  $queryResultUnit .= " AND step = " . $ilDB->quote((int)$this->getStep(), 'integer') . " ";
1101  }
1102 
1103  $result = $ilDB->queryF(
1104  $queryResultUnit,
1105  array('integer', 'integer', 'integer', 'integer'),
1106  array($active_id, $pass, $this->getId(), (int)$authorized)
1107  );
1108  if($result->numRows())
1109  {
1110  while($row = $ilDB->fetchAssoc($result))
1111  {
1112  $ilDB->manipulateF("DELETE FROM tst_solutions WHERE solution_id = %s AND authorized = %s",
1113  array('integer', 'integer'),
1114  array($row['solution_id'], (int)$authorized)
1115  );
1116  }
1117  }
1118 
1119  $this->saveCurrentSolution($active_id,$pass,$matches[1] . "_unit",$value, $authorized);
1120  }
1121  }
1122 
1123  });
1124 
1125  if($entered_values)
1126  {
1127  include_once ("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
1129  {
1130  assQuestion::logAction($this->lng->txtlng("assessment", "log_user_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
1131  }
1132  }
1133  else
1134  {
1135  include_once ("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
1137  {
1138  assQuestion::logAction($this->lng->txtlng("assessment", "log_user_not_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
1139  }
1140  }
1141 
1142  return true;
1143  }
1144 
1145 // fau: testNav - overridden function lookupForExistingSolutions (specific for formula question: don't lookup variables)
1152  public function lookupForExistingSolutions($activeId, $pass)
1153  {
1154  global $ilDB;
1155 
1156  $return = array(
1157  'authorized' => false,
1158  'intermediate' => false
1159  );
1160 
1161  $query = "
1162  SELECT authorized, COUNT(*) cnt
1163  FROM tst_solutions
1164  WHERE active_fi = " . $ilDB->quote($activeId, 'integer') ."
1165  AND question_fi = ". $ilDB->quote($this->getId(), 'integer') ."
1166  AND pass = " .$ilDB->quote($pass, 'integer') ."
1167  AND value1 like '\$r%'
1168  AND value2 is not null
1169  AND value2 <> ''
1170  ";
1171 
1172  if( $this->getStep() !== NULL )
1173  {
1174  $query .= " AND step = " . $ilDB->quote((int)$this->getStep(), 'integer') . " ";
1175  }
1176 
1177  $query .= "
1178  GROUP BY authorized
1179  ";
1180 
1181  $result = $ilDB->query($query);
1182 
1183  while ($row = $ilDB->fetchAssoc($result))
1184  {
1185  if ($row['authorized']) {
1186  $return['authorized'] = $row['cnt'] > 0;
1187  }
1188  else
1189  {
1190  $return['intermediate'] = $row['cnt'] > 0;
1191  }
1192  }
1193  return $return;
1194  }
1195 // fau.
1196 
1197 // fau: testNav - Remove an existing solution (specific for formula question: don't delete variables)
1204  public function removeExistingSolutions($activeId, $pass)
1205  {
1206  global $ilDB;
1207 
1208  $query = "
1209  DELETE FROM tst_solutions
1210  WHERE active_fi = " . $ilDB->quote($activeId, 'integer') ."
1211  AND question_fi = ". $ilDB->quote($this->getId(), 'integer') ."
1212  AND pass = " .$ilDB->quote($pass, 'integer') ."
1213  AND value1 like '\$r%'
1214  ";
1215 
1216  if( $this->getStep() !== NULL )
1217  {
1218  $query .= " AND step = " . $ilDB->quote((int)$this->getStep(), 'integer') . " ";
1219  }
1220 
1221  return $ilDB->manipulate($query);
1222  }
1223 // fau.
1224 
1225  protected function savePreviewData(ilAssQuestionPreviewSession $previewSession)
1226  {
1227  $userSolution = $previewSession->getParticipantsSolution();
1228 
1229  foreach($this->getSolutionSubmit() as $key => $val)
1230  {
1231  $matches = null;
1232 
1233  if(preg_match("/^result_(\\\$r\\d+)$/", $key, $matches))
1234  {
1235  $userSolution[$matches[1]] = $val;
1236  }
1237  else if(preg_match("/^result_(\\\$r\\d+)_unit$/", $key, $matches))
1238  {
1239  $userSolution[$matches[1] . "_unit"] = $val;
1240  }
1241  }
1242 
1243  $previewSession->setParticipantsSolution($userSolution);
1244  }
1245 
1249  protected function reworkWorkingData($active_id, $pass, $obligationsAnswered, $authorized)
1250  {
1251  // nothing to rework!
1252  }
1253 
1258  public function getQuestionType()
1259  {
1260  return "assFormulaQuestion";
1261  }
1262 
1267  public function getAdditionalTableName()
1268  {
1269  return "";
1270  }
1271 
1276  public function getAnswerTableName()
1277  {
1278  return "";
1279  }
1280 
1286  function deleteAnswers($question_id)
1287  {
1288  global $ilDB;
1289 
1290  $affectedRows = $ilDB->manipulateF("DELETE FROM il_qpl_qst_fq_var WHERE question_fi = %s",
1291  array('integer'),
1292  array($question_id)
1293  );
1294 
1295  $affectedRows = $ilDB->manipulateF("DELETE FROM il_qpl_qst_fq_res WHERE question_fi = %s",
1296  array('integer'),
1297  array($question_id)
1298  );
1299 
1300  $affectedRows = $ilDB->manipulateF("DELETE FROM il_qpl_qst_fq_res_unit WHERE question_fi = %s",
1301  array('integer'),
1302  array($question_id)
1303  );
1304 
1305  $affectedRows = $ilDB->manipulateF("DELETE FROM il_qpl_qst_fq_ucat WHERE question_fi = %s",
1306  array('integer'),
1307  array($question_id)
1308  );
1309 
1310  $affectedRows = $ilDB->manipulateF("DELETE FROM il_qpl_qst_fq_unit WHERE question_fi = %s",
1311  array('integer'),
1312  array($question_id)
1313  );
1314  }
1315 
1321  {
1322  $text = parent::getRTETextWithMediaObjects();
1323  return $text;
1324  }
1325 
1329  public function setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
1330  {
1331  parent::setExportDetailsXLS($worksheet, $startrow, $active_id, $pass);
1332 
1333  $solution = $this->getSolutionValues($active_id, $pass);
1334 
1335  $i = 1;
1336  foreach($solution as $solutionvalue)
1337  {
1338  $worksheet->setCell($startrow + $i, 0,$solutionvalue["value1"]);
1339  $worksheet->setBold($worksheet->getColumnCoord(0) . ($startrow + $i));
1340  if(strpos($solutionvalue["value1"], "_unit"))
1341  {
1342  $unit = $this->getUnitrepository()->getUnit($solutionvalue["value2"]);
1343  if(is_object($unit))
1344  {
1345  $worksheet->setCell($startrow + $i, 1, $unit->getUnit());
1346  }
1347  }
1348  else
1349  {
1350  $worksheet->setCell($startrow + $i, 1, $solutionvalue["value2"]);
1351  }
1352  if(preg_match("/(\\\$v\\d+)/", $solutionvalue["value1"], $matches))
1353  {
1354  $var = $this->getVariable($solutionvalue["value1"]);
1355  if(is_object($var) && (is_object($var->getUnit())))
1356  {
1357  $worksheet->setCell($startrow + $i, 2, $var->getUnit()->getUnit());
1358  }
1359  }
1360  $i++;
1361  }
1362 
1363  return $startrow + $i + 1;
1364  }
1365 
1371  public function getBestSolution($solutions)
1372  {
1373  $user_solution = array();
1374 
1375  foreach($solutions as $idx => $solution_value)
1376  {
1377  if(preg_match("/^(\\\$v\\d+)$/", $solution_value["value1"], $matches))
1378  {
1379  $user_solution[$matches[1]] = $solution_value["value2"];
1380  $varObj = $this->getVariable($matches[1]);
1381  $varObj->setValue($solution_value["value2"]);
1382  }
1383  else if(preg_match("/^(\\\$r\\d+)$/", $solution_value["value1"], $matches))
1384  {
1385  if(!array_key_exists($matches[1], $user_solution)) $user_solution[$matches[1]] = array();
1386  $user_solution[$matches[1]]["value"] = $solution_value["value2"];
1387  }
1388  else if(preg_match("/^(\\\$r\\d+)_unit$/", $solution_value["value1"], $matches))
1389  {
1390  if(!array_key_exists($matches[1], $user_solution)) $user_solution[$matches[1]] = array();
1391  $user_solution[$matches[1]]["unit"] = $solution_value["value2"];
1392  }
1393  }
1394  foreach($this->getResults() as $result)
1395  {
1396  $resVal = $result->calculateFormula($this->getVariables(), $this->getResults(), parent::getId(), false);
1397 
1398  if(is_object($result->getUnit()))
1399  {
1400  $user_solution[$result->getResult()]["unit"] = $result->getUnit()->getId();
1401  $user_solution[$result->getResult()]["value"] = $resVal;
1402  }
1403  else if($result->getUnit() == NULL)
1404  {
1405  $unit_factor = 1;
1406  // there is no fix result_unit, any "available unit" is accepted
1407 
1408  $available_units = $result->getAvailableResultUnits(parent::getId());
1409  $result_name = $result->getResult();
1410 
1411  if($available_units[$result_name] != NULL)
1412  {
1413  $check_unit = in_array($user_solution[$result_name]['unit'], $available_units[$result_name]);
1414  }
1415 
1416  if($check_unit == true)
1417  {
1418  //get unit-factor
1419  $unit_factor = assFormulaQuestionUnit::lookupUnitFactor($user_solution[$result_name]['unit']);
1420  }
1421 
1422  $user_solution[$result->getResult()]["value"] = round(ilMath::_div($resVal, $unit_factor), 55);
1423  }
1424  if($result->getResultType() == assFormulaQuestionResult::RESULT_CO_FRAC
1425  || $result->getResultType() == assFormulaQuestionResult::RESULT_FRAC)
1426  {
1428  if(is_array($value))
1429  {
1430  $user_solution[$result->getResult()]["value"] = $value[0];
1431  $user_solution[$result->getResult()]["frac_helper"] = $value[1];
1432  }
1433  else
1434  {
1435  $user_solution[$result->getResult()]["value"] = $value;
1436  $user_solution[$result->getResult()]["frac_helper"] = null;
1437  }
1438  }
1439  elseif($result->getPrecision() > 0)
1440  {
1441  $user_solution[$result->getResult()]["value"] = round(
1442  $user_solution[$result->getResult()]["value"], $result->getPrecision()
1443  );
1444  }
1445  else
1446  {
1447  $user_solution[$result->getResult()]["value"] = round(
1448  $user_solution[$result->getResult()]["value"]
1449  );
1450  }
1451  }
1452  return $user_solution;
1453  }
1454 
1455  public function setId($id = -1)
1456  {
1457  parent::setId($id);
1458  $this->unitrepository->setConsumerId($this->getId());
1459  }
1460 
1464  public function __get($value)
1465  {
1466  switch($value)
1467  {
1468  case "resultunits":
1469  return $this->resultunits;
1470  break;
1471  default:
1472  return parent::__get($value);
1473  break;
1474  }
1475  }
1476 
1481  {
1482  $this->unitrepository = $unitrepository;
1483  }
1484 
1488  public function getUnitrepository()
1489  {
1490  return $this->unitrepository;
1491  }
1492 
1496  protected function getSolutionSubmit()
1497  {
1498  $solutionSubmit = array();
1499  foreach($_POST as $k => $v)
1500  {
1501  if(preg_match("/^result_(\\\$r\\d+)$/", $k))
1502  {
1503  $solutionSubmit[$k] = $v;
1504  }
1505  elseif(preg_match("/^result_(\\\$r\\d+)_unit$/", $k))
1506  {
1507  $solutionSubmit[$k] = $v;
1508  }
1509  }
1510  return $solutionSubmit;
1511  }
1512 
1513  public function validateSolutionSubmit()
1514  {
1515  foreach($this->getSolutionSubmit() as $key => $value)
1516  {
1517  if(preg_match("/^result_(\\\$r\\d+)$/", $key))
1518  {
1519  if( strlen($value) && !$this->isValidSolutionResultValue($value) )
1520  {
1521  ilUtil::sendFailure($this->lng->txt("err_no_numeric_value"), true);
1522  return false;
1523  }
1524  }
1525  elseif(preg_match("/^result_(\\\$r\\d+)_unit$/", $key))
1526  {
1527  continue;
1528  }
1529  }
1530 
1531  return true;
1532  }
1533 
1542  public function getOperators($expression)
1543  {
1544  require_once "./Modules/TestQuestionPool/classes/class.ilOperatorsExpressionMapping.php";
1546  }
1547 
1552  public function getExpressionTypes()
1553  {
1554  return array(
1558  );
1559  }
1560 
1569  public function getUserQuestionResult($active_id, $pass)
1570  {
1572  global $ilDB;
1573  $result = new ilUserQuestionResult($this, $active_id, $pass);
1574 
1575  $maxStep = $this->lookupMaxStep($active_id, $pass);
1576 
1577  if( $maxStep !== null )
1578  {
1579  $data = $ilDB->queryF(
1580  "SELECT value1, value2 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s AND step = %s",
1581  array("integer", "integer", "integer",'integer'),
1582  array($active_id, $pass, $this->getId(), $maxStep)
1583  );
1584  }
1585  else
1586  {
1587  $data = $ilDB->queryF(
1588  "SELECT value1, value2 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s",
1589  array("integer", "integer", "integer"),
1590  array($active_id, $pass, $this->getId())
1591  );
1592  }
1593 
1594  while($row = $ilDB->fetchAssoc($data))
1595  {
1596  if(strstr($row["value1"], '$r') && $row["value2"] != null)
1597  {
1598  $result->addKeyValue(str_replace('$r', "", $row["value1"]), $row["value2"]);
1599  }
1600  }
1601 
1602  $points = $this->calculateReachedPoints($active_id, $pass);
1603  $max_points = $this->getMaximumPoints();
1604 
1605  $result->setReachedPercentage(($points/$max_points) * 100);
1606 
1607  return $result;
1608  }
1609 
1618  public function getAvailableAnswerOptions($index = null)
1619  {
1620  if($index !== null)
1621  {
1622  return $this->getResult('$r'.($index+1));
1623  }
1624  else
1625  {
1626  return $this->getResults();
1627  }
1628  }
1629 }
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.
substituteVariables(array $userdata, $graphicalOutput=FALSE, $forsolution=FALSE, $result_output=FALSE)
$worksheet
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
saveToDb($original_id="")
Saves a assFormulaQuestion object to a database public.
duplicate($for_test=true, $title="", $author="", $owner="", $testObjId=null)
Duplicates an assFormulaQuestion public.
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)
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.
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
saveWorkingData($active_id, $pass=NULL, $authorized=true)
Saves the learners input of the question to the database.
setAuthor($author="")
Sets the authors name of the assQuestion object.
static _enabledAssessmentLogging()
check wether assessment logging is enabled or not
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...
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
loadFromDb($question_id)
Loads a assFormulaQuestion object from a database.
getQuestion()
Gets the question string of the question object.
isValidSolutionResultValue($submittedValue)
canUseAdvancedRating($result)
Check if advanced rating can be used for a result.
createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle="")
Create styles array
The data for the language used.
copyObject($target_questionpool_id, $title="")
Copies an assFormulaQuestion object public.
static sendFailure($a_info="", $a_keep=false)
Send Failure Message to Screen.
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)
$text
getSolutionValues($active_id, $pass=NULL, $authorized=true)
Loads solutions of a given user from the database an returns it.
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.
reworkWorkingData($active_id, $pass, $obligationsAnswered, $authorized)
{}
setObjId($obj_id=0)
Set the object id of the container object.
setUnitrepository($unitrepository)
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)