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
4include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
5include_once "./Modules/TestQuestionPool/classes/class.assFormulaQuestionResult.php";
6include_once "./Modules/TestQuestionPool/classes/class.assFormulaQuestionVariable.php";
7include_once "./Modules/TestQuestionPool/classes/class.ilUnitConfigurationRepository.php";
8include_once "./Modules/Test/classes/inc.AssessmentConstants.php";
9include_once "./Modules/TestQuestionPool/interfaces/interface.iQuestionCondition.php";
10require_once './Modules/TestQuestionPool/classes/class.ilUserQuestionResult.php';
11
20{
21 private $variables;
22 private $results;
23 private $resultunits;
24
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
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
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 }
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}
sprintf('%.4f', $callTime)
$worksheet
$result
$_POST["username"]
An exception for terminatinating execution or to throw for unit testing.
static convertDecimalToCoprimeFraction($decimal_value, $tolerance=1.e-9)
Class for single choice questions assFormulaQuestion is a class for single choice questions.
getBestSolution($solutions)
Returns the best solution for a given pass of a participant.
getQuestionType()
Returns the question type of the question.
getAvailableAnswerOptions($index=null)
If index is null, the function returns an array with all anwser options Else it returns the specific ...
setUnitrepository($unitrepository)
removeExistingSolutions($activeId, $pass)
Remove an existing solution without removing the variables.
setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
{Creates an Excel worksheet for the detailed cumulated results of this question.object}
canUseAdvancedRating($result)
Check if advanced rating can be used for a result.
hasResultUnit($result, $unit_id)
isValidSolutionResultValue($submittedValue)
addResultUnits($result, $unit_ids)
saveWorkingData($active_id, $pass=NULL, $authorized=true)
Saves the learners input of the question to the database.
substituteVariables(array $userdata, $graphicalOutput=FALSE, $forsolution=FALSE, $result_output=FALSE)
setId($id=-1)
Sets the id of the assQuestion object.
getExpressionTypes()
Get all available expression types for a specific question.
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...
__get($value)
Object getter.
savePreviewData(ilAssQuestionPreviewSession $previewSession)
getOperators($expression)
Get all available operations for a specific question.
calculateReachedPointsFromPreviewSession(ilAssQuestionPreviewSession $previewSession)
copyObject($target_questionpool_id, $title="")
Copies an assFormulaQuestion object @access public.
getRTETextWithMediaObjects()
Collects all text in the question which could contain media objects which were created with the Rich ...
lookupForExistingSolutions($activeId, $pass)
Lookup if an authorized or intermediate solution exists.
loadFromDb($question_id)
Loads a assFormulaQuestion object from a database.
createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle="")
duplicate($for_test=true, $title="", $author="", $owner="", $testObjId=null)
Duplicates an assFormulaQuestion @access public.
getAdditionalTableName()
Returns the name of the additional question data table in the database.
getMaximumPoints()
Returns the maximum points, a learner can reach answering the question.
saveToDb($original_id="")
Saves a assFormulaQuestion object to a database @access public.
hasRequiredVariableSolutionValues(array $userSolution)
__construct( $title="", $comment="", $author="", $owner=-1, $question="")
assFormulaQuestion constructor The constructor takes possible arguments an creates an instance of the...
reworkWorkingData($active_id, $pass, $obligationsAnswered, $authorized)
{Reworks the allready saved working data if neccessary.}
deleteAnswers($question_id)
Deletes datasets from answers tables.
getAnswerTableName()
Returns the name of the answer table in the database.
isComplete()
Returns true, if the question is complete for use.
Abstract basic class which is to be extended by the concrete assessment question type classes.
static _getOriginalId($question_id)
Returns the original id of a question.
setOriginalId($original_id)
setObjId($obj_id=0)
Set the object id of the container object.
getSolutionMaxPass($active_id)
Returns the maximum pass a users question solution.
setSuggestedSolution($solution_id="", $subquestion_index=0, $is_import=false)
Sets a suggested solution for the question.
saveQuestionDataToDb($original_id="")
getId()
Gets the id of the assQuestion object.
saveCurrentSolution($active_id, $pass, $value1, $value2, $authorized=true, $tstamp=null)
getObjId()
Get the object id of the container object.
setTitle($title="")
Sets the title string of the assQuestion object.
setOwner($owner="")
Sets the creator/owner ID of the assQuestion object.
setEstimatedWorkingTime($hour=0, $min=0, $sec=0)
Sets the estimated working time of a question from given hour, minute and second.
deductHintPointsFromReachedPoints(ilAssQuestionPreviewSession $previewSession, $reachedPoints)
static logAction($logtext="", $active_id="", $question_id="")
Logs an action into the Test&Assessment log.
setAuthor($author="")
Sets the authors name of the assQuestion object.
getSolutionValues($active_id, $pass=NULL, $authorized=true)
Loads solutions of a given user from the database an returns it.
setPoints($a_points)
Sets the maximum available points for the question.
setComment($comment="")
Sets the comment string of the assQuestion object.
getQuestion()
Gets the question string of the question object.
setAdditionalContentEditingMode($additinalContentEditingMode)
setter for additional content editing mode for this question
setQuestion($question="")
Sets the question string of the question object.
ensureNonNegativePoints($points)
static _div($left_operand, $right_operand, $scale=50)
static _getLogLanguage()
retrieve the log language for assessment logging
static _enabledAssessmentLogging()
check wether assessment logging is enabled or not
static _getPass($active_id)
Retrieves the actual pass of a given user for a given test.
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...
special template class to simplify handling of ITX/PEAR
Class ilUnitConfigurationRepository.
Class ilUserQuestionResult.
static sendFailure($a_info="", $a_keep=false)
Send Failure Message to Screen.
static getImagePath($img, $module_path="", $mode="output", $offline=false)
get image path (for images located in a template directory)
static prepareFormOutput($a_str, $a_strip=false)
prepares string output for html forms @access public
$text
Class iQuestionCondition.
getUserQuestionResult($active_id, $pass)
Get the user solution for a question by active_id and the test pass.
global $ilDB