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