ILIAS  release_7 Revision v7.30-3-g800a261c036
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 $text = $this->purifyAndPrepareTextAreaOutput($text);
284
285 if (preg_match_all("/(\\\$r\\d+)/ims", $this->getQuestion(), $rmatches)) {
286 foreach ($rmatches[1] as $result) {
287 $resObj = $this->getResult($result);
288 $value = "";
289 $frac_helper = '';
290 $user_data[$result]['result_type'] = $resObj->getResultType();
291
292 if (
293 $resObj->getResultType() == assFormulaQuestionResult::RESULT_FRAC ||
294 $resObj->getResultType() == assFormulaQuestionResult::RESULT_CO_FRAC
295 ) {
296 $is_frac = true;
297 }
298 if (is_array($userdata)) {
299 if (is_array($userdata[$result])) {
300 if (false && $forsolution && $result_output) { // fix for mantis #25956
301 $value_org = $resObj->calculateFormula($this->getVariables(), $this->getResults(), parent::getId());
302 $value = sprintf("%." . $resObj->getPrecision() . "f", $value_org);
303 if ($is_frac) {
305 if (is_array($value)) {
306 $frac_helper = $value[1];
307 $value = $value[0];
308 }
309 }
310 } else {
311 if ($forsolution) {
312 $value = $userdata[$result]["value"];
313 } else {
314 $value = ' value="' . $userdata[$result]["value"] . '"';
315 }
316 }
317 }
318 } else {
319 if ($forsolution) {
320 $value = $resObj->calculateFormula($this->getVariables(), $this->getResults(), parent::getId());
321 $value = sprintf("%." . $resObj->getPrecision() . "f", $value);
322
323 if ($is_frac) {
325 if (is_array($value)) {
326 $frac_helper = $value[1];
327 $value = $value[0];
328 }
329 $value = ' value="' . $value . '"';
330 }
331 } else {
332 // Precision fix for Preview by tjoussen
333 // If all default values are set, this function is called in getPreview
334 $use_precision = !($userdata == null && $graphicalOutput == false && $forsolution == false && $result_output == false);
335
336 $val = $resObj->calculateFormula($this->getVariables(), $this->getResults(), parent::getId(), $use_precision);
337
338 if ($resObj->getResultType() == assFormulaQuestionResult::RESULT_FRAC
339 || $resObj->getResultType() == assFormulaQuestionResult::RESULT_CO_FRAC) {
340 $val = $resObj->convertDecimalToCoprimeFraction($val);
341 if (is_array($val)) {
342 $frac_helper = $val[1];
343 $val = $val[0];
344 }
345 } else {
346 $val = sprintf("%." . $resObj->getPrecision() . "f", $val);
347 $val = (strlen($val) > 8) ? strtoupper(sprintf("%e", $val)) : $val;
348 }
349 $value = ' value="' . $val . '"';
350 }
351 }
352
353 if ($forsolution) {
354 $input = '<span class="ilc_qinput_TextInput solutionbox">' . ilUtil::prepareFormOutput($value) . '</span>';
355 } else {
356 $input = '<input class="ilc_qinput_TextInput" type="text" spellcheck="false" autocomplete="off" autocorrect="off" autocapitalize="off" name="result_' . $result . '"' . $value . ' />';
357 }
358
359 $units = "";
360 if (count($this->getResultUnits($resObj)) > 0) {
361 if ($forsolution) {
362 if (is_array($userdata)) {
363 foreach ($this->getResultUnits($resObj) as $unit) {
364 if ($userdata[$result]["unit"] == $unit->getId()) {
365 $units = $unit->getUnit();
366 }
367 }
368 } else {
369 if ($resObj->getUnit()) {
370 $units = $resObj->getUnit()->getUnit();
371 }
372 }
373 } else {
374 $units = '<select name="result_' . $result . '_unit">';
375 $units .= '<option value="-1">' . $this->lng->txt("select_unit") . '</option>';
376 foreach ($this->getResultUnits($resObj) as $unit) {
377 $units .= '<option value="' . $unit->getId() . '"';
378 if ((is_array($userdata[$result])) && (strlen($userdata[$result]["unit"]))) {
379 if ($userdata[$result]["unit"] == $unit->getId()) {
380 $units .= ' selected="selected"';
381 }
382 }
383 $units .= '>' . $unit->getUnit() . '</option>';
384 }
385 $units .= '</select>';
386 }
387 } else {
388 $units = "";
389 }
390 switch ($resObj->getResultType()) {
392 $units .= ' ' . $this->lng->txt('expected_result_type') . ': ' . $this->lng->txt('result_dec');
393 break;
395 if (strlen($frac_helper)) {
396 $units .= ' &asymp; ' . $frac_helper . ', ';
397 } elseif (is_array($userdata) && isset($userdata[$result]) && strlen($userdata[$result]["frac_helper"])) {
398 if (!preg_match('-/-', $value)) {
399 $units .= ' &asymp; ' . $userdata[$result]["frac_helper"] . ', ';
400 }
401 }
402 $units .= ' ' . $this->lng->txt('expected_result_type') . ': ' . $this->lng->txt('result_frac');
403 break;
405 if (strlen($frac_helper)) {
406 $units .= ' &asymp; ' . $frac_helper . ', ';
407 } elseif (is_array($userdata) && isset($userdata[$result]) && strlen($userdata[$result]["frac_helper"])) {
408 if (!preg_match('-/-', $value)) {
409 $units .= ' &asymp; ' . $userdata[$result]["frac_helper"] . ', ';
410 }
411 }
412 $units .= ' ' . $this->lng->txt('expected_result_type') . ': ' . $this->lng->txt('result_co_frac');
413 break;
415 break;
416 }
417 $checkSign = "";
418 if ($graphicalOutput) {
419 $resunit = null;
420 $user_value = '';
421 if (is_array($userdata) && is_array($userdata[$result])) {
422 if ($userdata[$result]["unit"] > 0) {
423 $resunit = $this->getUnitrepository()->getUnit($userdata[$result]["unit"]);
424 }
425
426 if (isset($userdata[$result]["value"])) {
427 $user_value = $userdata[$result]["value"];
428 }
429 }
430
431 $template = new ilTemplate("tpl.il_as_qpl_formulaquestion_output_solution_image.html", true, true, 'Modules/TestQuestionPool');
432
433 if ($resObj->isCorrect($this->getVariables(), $this->getResults(), $user_value, $resunit)) {
434 $template->setCurrentBlock("icon_ok");
435 $template->setVariable("ICON_OK", ilUtil::getImagePath("icon_ok.svg"));
436 $template->setVariable("TEXT_OK", $this->lng->txt("answer_is_right"));
437 $template->parseCurrentBlock();
438 } else {
439 $template->setCurrentBlock("icon_not_ok");
440 $template->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_not_ok.svg"));
441 $template->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_wrong"));
442 $template->parseCurrentBlock();
443 }
444 $checkSign = $template->get();
445 }
446 $resultOutput = "";
447 if ($result_output) {
448 $template = new ilTemplate("tpl.il_as_qpl_formulaquestion_output_solution_result.html", true, true, 'Modules/TestQuestionPool');
449
450 if (is_array($userdata)) {
451 $found = $resObj->getResultInfo($this->getVariables(), $this->getResults(), $userdata[$resObj->getResult()]["value"], $userdata[$resObj->getResult()]["unit"], $this->getUnitrepository()->getUnits());
452 } else {
453 $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());
454 }
455 $resulttext = "(";
456 if ($resObj->getRatingSimple()) {
457 if ($frac_helper) {
458 $resulttext .= "n/a";
459 } else {
460 $resulttext .= $found['points'] . " " . (($found['points'] == 1) ? $this->lng->txt('point') : $this->lng->txt('points'));
461 }
462 } else {
463 $resulttext .= $this->lng->txt("rated_sign") . " " . (($found['sign']) ? $found['sign'] : 0) . " " . (($found['sign'] == 1) ? $this->lng->txt('point') : $this->lng->txt('points')) . ", ";
464 $resulttext .= $this->lng->txt("rated_value") . " " . (($found['value']) ? $found['value'] : 0) . " " . (($found['value'] == 1) ? $this->lng->txt('point') : $this->lng->txt('points')) . ", ";
465 $resulttext .= $this->lng->txt("rated_unit") . " " . (($found['unit']) ? $found['unit'] : 0) . " " . (($found['unit'] == 1) ? $this->lng->txt('point') : $this->lng->txt('points'));
466 }
467
468 $resulttext .= ")";
469 $template->setVariable("RESULT_OUTPUT", $resulttext);
470
471 $resultOutput = $template->get();
472 }
473 $text = preg_replace("/\\\$" . substr($result, 1) . "(?![0-9]+)/", $input . " " . $units . " " . $checkSign . " " . $resultOutput . " " . "\\1", $text);
474 }
475 }
476 return $text;
477 }
478
486 {
487 $result_units = $this->getResultUnits($result);
488 $resultunit = $result->getUnit();
489 $similar_units = 0;
490 foreach ($result_units as $unit) {
491 if (is_object($resultunit)) {
492 if ($resultunit->getId() != $unit->getId()) {
493 if ($resultunit->getBaseUnit() && $unit->getBaseUnit()) {
494 if ($resultunit->getBaseUnit() == $unit->getBaseUnit()) {
495 return false;
496 }
497 }
498 if ($resultunit->getBaseUnit()) {
499 if ($resultunit->getBaseUnit() == $unit->getId()) {
500 return false;
501 }
502 }
503 if ($unit->getBaseUnit()) {
504 if ($unit->getBaseUnit() == $resultunit->getId()) {
505 return false;
506 }
507 }
508 }
509 }
510 }
511 return true;
512 }
513
518 public function isComplete()
519 {
520 if (($this->title) and ($this->author) and ($this->question) and ($this->getMaximumPoints() > 0)) {
521 return true;
522 } else {
523 return false;
524 }
525 }
526
531 public function saveToDb($original_id = "")
532 {
533 global $DIC;
534 $ilDB = $DIC['ilDB'];
535
537 // save variables
538 $affectedRows = $ilDB->manipulateF(
539 "
540 DELETE FROM il_qpl_qst_fq_var
541 WHERE question_fi = %s",
542 array("integer"),
543 array($this->getId())
544 );
545
546 foreach ($this->variables as $variable) {
547 $next_id = $ilDB->nextId('il_qpl_qst_fq_var');
548 $ilDB->insert(
549 'il_qpl_qst_fq_var',
550 array(
551 'variable_id' => array('integer', $next_id),
552 'question_fi' => array('integer', $this->getId()),
553 'variable' => array('text', $variable->getVariable()),
554 'range_min' => array('float', ((strlen($variable->getRangeMin())) ? $variable->getRangeMin() : 0.0)),
555 'range_max' => array('float', ((strlen($variable->getRangeMax())) ? $variable->getRangeMax() : 0.0)),
556 'unit_fi' => array('integer', (is_object($variable->getUnit()) ? (int) $variable->getUnit()->getId() : 0)),
557 'varprecision' => array('integer', (int) $variable->getPrecision()),
558 'intprecision' => array('integer', (int) $variable->getIntprecision()),
559 'range_min_txt' => array('text', $variable->getRangeMinTxt()),
560 'range_max_txt' => array('text', $variable->getRangeMaxTxt())
561 )
562 );
563 }
564 // save results
565 $affectedRows = $ilDB->manipulateF(
566 "DELETE FROM il_qpl_qst_fq_res WHERE question_fi = %s",
567 array("integer"),
568 array($this->getId())
569 );
570
571 foreach ($this->results as $result) {
572 $next_id = $ilDB->nextId('il_qpl_qst_fq_res');
573 if (is_object($result->getUnit())) {
574 $tmp_result_unit = $result->getUnit()->getId();
575 } else {
576 $tmp_result_unit = null;
577 }
578
579 $formula = str_replace(",", ".", $result->getFormula());
580
581 $ilDB->insert("il_qpl_qst_fq_res", array(
582 "result_id" => array("integer", $next_id),
583 "question_fi" => array("integer", $this->getId()),
584 "result" => array("text", $result->getResult()),
585 "range_min" => array("float", ((strlen($result->getRangeMin())) ? $result->getRangeMin() : 0)),
586 "range_max" => array("float", ((strlen($result->getRangeMax())) ? $result->getRangeMax() : 0)),
587 "tolerance" => array("float", ((strlen($result->getTolerance())) ? $result->getTolerance() : 0)),
588 "unit_fi" => array("integer", (int) $tmp_result_unit),
589 "formula" => array("clob", $formula),
590 "resprecision" => array("integer", $result->getPrecision()),
591 "rating_simple" => array("integer", ($result->getRatingSimple()) ? 1 : 0),
592 "rating_sign" => array("float", ($result->getRatingSimple()) ? 0 : $result->getRatingSign()),
593 "rating_value" => array("float", ($result->getRatingSimple()) ? 0 : $result->getRatingValue()),
594 "rating_unit" => array("float", ($result->getRatingSimple()) ? 0 : $result->getRatingUnit()),
595 "points" => array("float", $result->getPoints()),
596 "result_type" => array('integer', (int) $result->getResultType()),
597 "range_min_txt" => array("text", $result->getRangeMinTxt()),
598 "range_max_txt" => array("text", $result->getRangeMaxTxt())
599
600 ));
601 }
602 // save result units
603 $affectedRows = $ilDB->manipulateF(
604 "DELETE FROM il_qpl_qst_fq_res_unit WHERE question_fi = %s",
605 array("integer"),
606 array($this->getId())
607 );
608 foreach ($this->results as $result) {
609 foreach ($this->getResultUnits($result) as $unit) {
610 $next_id = $ilDB->nextId('il_qpl_qst_fq_res_unit');
611 $affectedRows = $ilDB->manipulateF(
612 "INSERT INTO il_qpl_qst_fq_res_unit (result_unit_id, question_fi, result, unit_fi) VALUES (%s, %s, %s, %s)",
613 array('integer', 'integer', 'text', 'integer'),
614 array(
615 $next_id,
616 $this->getId(),
617 $result->getResult(),
618 $unit->getId()
619 )
620 );
621 }
622 }
623
624 parent::saveToDb();
625 }
626
631 public function loadFromDb($question_id)
632 {
633 global $DIC;
634 $ilDB = $DIC['ilDB'];
635
636 $result = $ilDB->queryF(
637 "SELECT qpl_questions.* FROM qpl_questions WHERE question_id = %s",
638 array('integer'),
639 array($question_id)
640 );
641 if ($result->numRows() == 1) {
642 $data = $ilDB->fetchAssoc($result);
643 $this->setId($question_id);
644 $this->setTitle($data["title"]);
645 $this->setComment($data["description"]);
646 $this->setSuggestedSolution($data["solution_hint"]);
647 $this->setPoints($data['points']);
648 $this->setOriginalId($data["original_id"]);
649 $this->setObjId($data["obj_fi"]);
650 $this->setAuthor($data["author"]);
651 $this->setOwner($data["owner"]);
652
653 try {
657 }
658
659 try {
660 $this->setAdditionalContentEditingMode($data['add_cont_edit_mode']);
662 }
663
664 $this->unitrepository = new ilUnitConfigurationRepository($question_id);
665
666 include_once("./Services/RTE/classes/class.ilRTE.php");
667 $this->setQuestion(ilRTE::_replaceMediaObjectImageSrc($data["question_text"], 1));
668 $this->setEstimatedWorkingTime(substr($data["working_time"], 0, 2), substr($data["working_time"], 3, 2), substr($data["working_time"], 6, 2));
669
670 // load variables
671 $result = $ilDB->queryF(
672 "SELECT * FROM il_qpl_qst_fq_var WHERE question_fi = %s",
673 array('integer'),
674 array($question_id)
675 );
676 if ($result->numRows() > 0) {
677 while ($data = $ilDB->fetchAssoc($result)) {
678 $varObj = new assFormulaQuestionVariable($data["variable"], $data["range_min"], $data["range_max"], $this->getUnitrepository()->getUnit($data["unit_fi"]), $data["varprecision"], $data["intprecision"]);
679 $varObj->setRangeMinTxt($data['range_min_txt']);
680 $varObj->setRangeMaxTxt($data['range_max_txt']);
681 $this->addVariable($varObj);
682 }
683 }
684 // load results
685 $result = $ilDB->queryF(
686 "SELECT * FROM il_qpl_qst_fq_res WHERE question_fi = %s",
687 array('integer'),
688 array($question_id)
689 );
690 if ($result->numRows() > 0) {
691 while ($data = $ilDB->fetchAssoc($result)) {
692 $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"]);
693 $resObj->setResultType($data['result_type']);
694 $resObj->setRangeMinTxt($data['range_min_txt']);
695 $resObj->setRangeMaxTxt($data['range_max_txt']);
696 $this->addResult($resObj);
697 }
698 }
699
700 // load result units
701 $result = $ilDB->queryF(
702 "SELECT * FROM il_qpl_qst_fq_res_unit WHERE question_fi = %s",
703 array('integer'),
704 array($question_id)
705 );
706 if ($result->numRows() > 0) {
707 while ($data = $ilDB->fetchAssoc($result)) {
708 $unit = $this->getUnitrepository()->getUnit($data["unit_fi"]);
709 $resObj = $this->getResult($data["result"]);
710 $this->addResultUnit($resObj, $unit);
711 }
712 }
713 }
714 parent::loadFromDb($question_id);
715 }
716
721 public function duplicate($for_test = true, $title = "", $author = "", $owner = "", $testObjId = null)
722 {
723 if ($this->id <= 0) {
724 // The question has not been saved. It cannot be duplicated
725 return;
726 }
727 // duplicate the question in database
728 $this_id = $this->getId();
729 $thisObjId = $this->getObjId();
730
731 $clone = $this;
732 include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
734 $clone->id = -1;
735
736 if ((int) $testObjId > 0) {
737 $clone->setObjId($testObjId);
738 }
739
740 if ($title) {
741 $clone->setTitle($title);
742 }
743
744 if ($author) {
745 $clone->setAuthor($author);
746 }
747 if ($owner) {
748 $clone->setOwner($owner);
749 }
750
751 if ($for_test) {
752 $clone->saveToDb($original_id);
753 } else {
754 $clone->saveToDb();
755 }
756
757 $clone->unitrepository->cloneUnits($this_id, $clone->getId());
758
759 // copy question page content
760 $clone->copyPageOfQuestion($this_id);
761 // copy XHTML media objects
762 $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
763 $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
764
765 return $clone->id;
766 }
767
772 public function copyObject($target_questionpool_id, $title = "")
773 {
774 if ($this->id <= 0) {
775 // The question has not been saved. It cannot be duplicated
776 return;
777 }
778 // duplicate the question in database
779 $clone = $this;
780 include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
782 $clone->id = -1;
783 $source_questionpool_id = $this->getObjId();
784 $clone->setObjId($target_questionpool_id);
785 if ($title) {
786 $clone->setTitle($title);
787 }
788 $clone->saveToDb();
789
790 $clone->unitrepository->cloneUnits($original_id, $clone->getId());
791
792 // copy question page content
793 $clone->copyPageOfQuestion($original_id);
794 // copy XHTML media objects
795 $clone->copyXHTMLMediaObjectsOfQuestion($original_id);
796
797 $clone->onCopy($source_questionpool_id, $original_id, $clone->getObjId(), $clone->getId());
798
799 return $clone->id;
800 }
801
802 public function createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle = "")
803 {
804 if ($this->id <= 0) {
805 // The question has not been saved. It cannot be duplicated
806 return;
807 }
808
809 include_once("./Modules/TestQuestionPool/classes/class.assQuestion.php");
810
811 $sourceQuestionId = $this->id;
812 $sourceParentId = $this->getObjId();
813
814 // duplicate the question in database
815 $clone = $this;
816 $clone->id = -1;
817
818 $clone->setObjId($targetParentId);
819
820 if ($targetQuestionTitle) {
821 $clone->setTitle($targetQuestionTitle);
822 }
823
824 $clone->saveToDb();
825 // copy question page content
826 $clone->copyPageOfQuestion($sourceQuestionId);
827 // copy XHTML media objects
828 $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
829
830 $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
831
832 return $clone->id;
833 }
834
839 public function getMaximumPoints()
840 {
841 $points = 0;
842 foreach ($this->results as $result) {
843 $points += $result->getPoints();
844 }
845 return $points;
846 }
847
856 public function calculateReachedPoints($active_id, $pass = null, $authorizedSolution = true, $returndetails = false)
857 {
858 if (is_null($pass)) {
859 $pass = $this->getSolutionMaxPass($active_id);
860 }
861 $solutions = &$this->getSolutionValues($active_id, $pass, $authorizedSolution);
862 $user_solution = array();
863 foreach ($solutions as $idx => $solution_value) {
864 if (preg_match("/^(\\\$v\\d+)$/", $solution_value["value1"], $matches)) {
865 $user_solution[$matches[1]] = $solution_value["value2"];
866 $varObj = $this->getVariable($solution_value["value1"]);
867 $varObj->setValue($solution_value["value2"]);
868 } elseif (preg_match("/^(\\\$r\\d+)$/", $solution_value["value1"], $matches)) {
869 if (!array_key_exists($matches[1], $user_solution)) {
870 $user_solution[$matches[1]] = array();
871 }
872 $user_solution[$matches[1]]["value"] = $solution_value["value2"];
873 } elseif (preg_match("/^(\\\$r\\d+)_unit$/", $solution_value["value1"], $matches)) {
874 if (!array_key_exists($matches[1], $user_solution)) {
875 $user_solution[$matches[1]] = array();
876 }
877 $user_solution[$matches[1]]["unit"] = $solution_value["value2"];
878 }
879 }
880 //vd($this->getResults());
881 $points = 0;
882 foreach ($this->getResults() as $result) {
883 //vd($user_solution[$result->getResult()]["value"]);
884 $points += $result->getReachedPoints($this->getVariables(), $this->getResults(), $user_solution[$result->getResult()]["value"], $user_solution[$result->getResult()]["unit"], $this->unitrepository->getUnits());
885 }
886
887 return $points;
888 }
889
891 {
892 $user_solution = $previewSession->getParticipantsSolution();
893
894 $points = 0;
895 foreach ($this->getResults() as $result) {
896 $v = isset($user_solution[$result->getResult()]) ? $user_solution[$result->getResult()] : null;
897 $u = isset($user_solution[$result->getResult() . '_unit']) ? $user_solution[$result->getResult() . '_unit'] : null;
898
899 $points += $result->getReachedPoints(
900 $this->getVariables(),
901 $this->getResults(),
902 $v,
903 $u,
904 $this->unitrepository->getUnits()
905 );
906 }
907
908 $reachedPoints = $this->deductHintPointsFromReachedPoints($previewSession, $points);
909
910 return $this->ensureNonNegativePoints($reachedPoints);
911 }
912
913 protected function isValidSolutionResultValue($submittedValue)
914 {
915 $submittedValue = str_replace(',', '.', $submittedValue);
916
917 if (is_numeric($submittedValue)) {
918 return true;
919 }
920
921 if (preg_match('/^[-+]{0,1}\d+\/\d+$/', $submittedValue)) {
922 return true;
923 }
924
925 return false;
926 }
927
935 public function saveWorkingData($active_id, $pass = null, $authorized = true)
936 {
937 global $DIC;
938 $ilDB = $DIC['ilDB'];
939
940 if (is_null($pass)) {
941 include_once "./Modules/Test/classes/class.ilObjTest.php";
942 $pass = ilObjTest::_getPass($active_id);
943 }
944
945 $entered_values = false;
946
947 $this->getProcessLocker()->executeUserSolutionUpdateLockOperation(function () use (&$entered_values, $ilDB, $active_id, $pass, $authorized) {
948 $solutionSubmit = $this->getSolutionSubmit();
949 foreach ($solutionSubmit as $key => $value) {
950 $matches = null;
951 if (preg_match("/^result_(\\\$r\\d+)$/", $key, $matches)) {
952 if (strlen($value)) {
953 $entered_values = true;
954 }
955
956 $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]);
957
958 if ($this->getStep() !== null) {
959 $queryResult .= " AND step = " . $ilDB->quote((int) $this->getStep(), 'integer') . " ";
960 }
961
962 $result = $ilDB->queryF(
963 $queryResult,
964 array('integer', 'integer', 'integer', 'integer'),
965 array($active_id, $pass, $this->getId(), (int) $authorized)
966 );
967 if ($result->numRows()) {
968 while ($row = $ilDB->fetchAssoc($result)) {
969 $ilDB->manipulateF(
970 "DELETE FROM tst_solutions WHERE solution_id = %s AND authorized = %s",
971 array('integer', 'integer'),
972 array($row['solution_id'], (int) $authorized)
973 );
974 }
975 }
976
977 $this->saveCurrentSolution($active_id, $pass, $matches[1], str_replace(",", ".", $value), $authorized);
978 } elseif (preg_match("/^result_(\\\$r\\d+)_unit$/", $key, $matches)) {
979 $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");
980
981 if ($this->getStep() !== null) {
982 $queryResultUnit .= " AND step = " . $ilDB->quote((int) $this->getStep(), 'integer') . " ";
983 }
984
985 $result = $ilDB->queryF(
986 $queryResultUnit,
987 array('integer', 'integer', 'integer', 'integer'),
988 array($active_id, $pass, $this->getId(), (int) $authorized)
989 );
990 if ($result->numRows()) {
991 while ($row = $ilDB->fetchAssoc($result)) {
992 $ilDB->manipulateF(
993 "DELETE FROM tst_solutions WHERE solution_id = %s AND authorized = %s",
994 array('integer', 'integer'),
995 array($row['solution_id'], (int) $authorized)
996 );
997 }
998 }
999
1000 $this->saveCurrentSolution($active_id, $pass, $matches[1] . "_unit", $value, $authorized);
1001 }
1002 }
1003 });
1004
1005 if ($entered_values) {
1006 include_once("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
1008 assQuestion::logAction($this->lng->txtlng("assessment", "log_user_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
1009 }
1010 } else {
1011 include_once("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
1013 assQuestion::logAction($this->lng->txtlng("assessment", "log_user_not_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
1014 }
1015 }
1016
1017 return true;
1018 }
1019
1020 // fau: testNav - overridden function lookupForExistingSolutions (specific for formula question: don't lookup variables)
1027 public function lookupForExistingSolutions($activeId, $pass)
1028 {
1029 global $DIC;
1030 $ilDB = $DIC['ilDB'];
1031
1032 $return = array(
1033 'authorized' => false,
1034 'intermediate' => false
1035 );
1036
1037 $query = "
1038 SELECT authorized, COUNT(*) cnt
1039 FROM tst_solutions
1040 WHERE active_fi = " . $ilDB->quote($activeId, 'integer') . "
1041 AND question_fi = " . $ilDB->quote($this->getId(), 'integer') . "
1042 AND pass = " . $ilDB->quote($pass, 'integer') . "
1043 AND value1 like '\$r%'
1044 AND value2 is not null
1045 AND value2 <> ''
1046 ";
1047
1048 if ($this->getStep() !== null) {
1049 $query .= " AND step = " . $ilDB->quote((int) $this->getStep(), 'integer') . " ";
1050 }
1051
1052 $query .= "
1053 GROUP BY authorized
1054 ";
1055
1056 $result = $ilDB->query($query);
1057
1058 while ($row = $ilDB->fetchAssoc($result)) {
1059 if ($row['authorized']) {
1060 $return['authorized'] = $row['cnt'] > 0;
1061 } else {
1062 $return['intermediate'] = $row['cnt'] > 0;
1063 }
1064 }
1065 return $return;
1066 }
1067 // fau.
1068
1069 // fau: testNav - Remove an existing solution (specific for formula question: don't delete variables)
1076 public function removeExistingSolutions($activeId, $pass)
1077 {
1078 global $DIC;
1079 $ilDB = $DIC['ilDB'];
1080
1081 $query = "
1082 DELETE FROM tst_solutions
1083 WHERE active_fi = " . $ilDB->quote($activeId, 'integer') . "
1084 AND question_fi = " . $ilDB->quote($this->getId(), 'integer') . "
1085 AND pass = " . $ilDB->quote($pass, 'integer') . "
1086 AND value1 like '\$r%'
1087 ";
1088
1089 if ($this->getStep() !== null) {
1090 $query .= " AND step = " . $ilDB->quote((int) $this->getStep(), 'integer') . " ";
1091 }
1092
1093 return $ilDB->manipulate($query);
1094 }
1095 // fau.
1096
1097 protected function savePreviewData(ilAssQuestionPreviewSession $previewSession)
1098 {
1099 $userSolution = $previewSession->getParticipantsSolution();
1100
1101 foreach ($this->getSolutionSubmit() as $key => $val) {
1102 $matches = null;
1103
1104 if (preg_match("/^result_(\\\$r\\d+)$/", $key, $matches)) {
1105 $userSolution[$matches[1]] = $val;
1106 } elseif (preg_match("/^result_(\\\$r\\d+)_unit$/", $key, $matches)) {
1107 $userSolution[$matches[1] . "_unit"] = $val;
1108 }
1109 }
1110
1111 $previewSession->setParticipantsSolution($userSolution);
1112 }
1113
1118 public function getQuestionType()
1119 {
1120 return "assFormulaQuestion";
1121 }
1122
1127 public function getAdditionalTableName()
1128 {
1129 return "";
1130 }
1131
1136 public function getAnswerTableName()
1137 {
1138 return "";
1139 }
1140
1146 public function deleteAnswers($question_id)
1147 {
1148 global $DIC;
1149 $ilDB = $DIC['ilDB'];
1150
1151 $affectedRows = $ilDB->manipulateF(
1152 "DELETE FROM il_qpl_qst_fq_var WHERE question_fi = %s",
1153 array('integer'),
1154 array($question_id)
1155 );
1156
1157 $affectedRows = $ilDB->manipulateF(
1158 "DELETE FROM il_qpl_qst_fq_res WHERE question_fi = %s",
1159 array('integer'),
1160 array($question_id)
1161 );
1162
1163 $affectedRows = $ilDB->manipulateF(
1164 "DELETE FROM il_qpl_qst_fq_res_unit WHERE question_fi = %s",
1165 array('integer'),
1166 array($question_id)
1167 );
1168
1169 $affectedRows = $ilDB->manipulateF(
1170 "DELETE FROM il_qpl_qst_fq_ucat WHERE question_fi = %s",
1171 array('integer'),
1172 array($question_id)
1173 );
1174
1175 $affectedRows = $ilDB->manipulateF(
1176 "DELETE FROM il_qpl_qst_fq_unit WHERE question_fi = %s",
1177 array('integer'),
1178 array($question_id)
1179 );
1180 }
1181
1187 {
1188 $text = parent::getRTETextWithMediaObjects();
1189 return $text;
1190 }
1191
1195 public function setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
1196 {
1197 parent::setExportDetailsXLS($worksheet, $startrow, $active_id, $pass);
1198
1199 $solution = $this->getSolutionValues($active_id, $pass);
1200
1201 $i = 1;
1202 foreach ($solution as $solutionvalue) {
1203 $worksheet->setCell($startrow + $i, 0, $solutionvalue["value1"]);
1204 $worksheet->setBold($worksheet->getColumnCoord(0) . ($startrow + $i));
1205 if (strpos($solutionvalue["value1"], "_unit")) {
1206 $unit = $this->getUnitrepository()->getUnit($solutionvalue["value2"]);
1207 if (is_object($unit)) {
1208 $worksheet->setCell($startrow + $i, 2, $unit->getUnit());
1209 }
1210 } else {
1211 $worksheet->setCell($startrow + $i, 2, $solutionvalue["value2"]);
1212 }
1213 if (preg_match("/(\\\$v\\d+)/", $solutionvalue["value1"], $matches)) {
1214 $var = $this->getVariable($solutionvalue["value1"]);
1215 if (is_object($var) && (is_object($var->getUnit()))) {
1216 $worksheet->setCell($startrow + $i, 3, $var->getUnit()->getUnit());
1217 }
1218 }
1219 $i++;
1220 }
1221
1222 return $startrow + $i + 1;
1223 }
1224
1230 public function getBestSolution($solutions)
1231 {
1232 $user_solution = array();
1233
1234 foreach ($solutions as $idx => $solution_value) {
1235 if (preg_match("/^(\\\$v\\d+)$/", $solution_value["value1"], $matches)) {
1236 $user_solution[$matches[1]] = $solution_value["value2"];
1237 $varObj = $this->getVariable($matches[1]);
1238 $varObj->setValue($solution_value["value2"]);
1239 } elseif (preg_match("/^(\\\$r\\d+)$/", $solution_value["value1"], $matches)) {
1240 if (!array_key_exists($matches[1], $user_solution)) {
1241 $user_solution[$matches[1]] = array();
1242 }
1243 $user_solution[$matches[1]]["value"] = $solution_value["value2"];
1244 } elseif (preg_match("/^(\\\$r\\d+)_unit$/", $solution_value["value1"], $matches)) {
1245 if (!array_key_exists($matches[1], $user_solution)) {
1246 $user_solution[$matches[1]] = array();
1247 }
1248 $user_solution[$matches[1]]["unit"] = $solution_value["value2"];
1249 }
1250 }
1251 foreach ($this->getResults() as $result) {
1252 $resVal = $result->calculateFormula($this->getVariables(), $this->getResults(), parent::getId(), false);
1253
1254 if (is_object($result->getUnit())) {
1255 $user_solution[$result->getResult()]["unit"] = $result->getUnit()->getId();
1256 $user_solution[$result->getResult()]["value"] = $resVal;
1257 } elseif ($result->getUnit() == null) {
1258 $unit_factor = 1;
1259 // there is no fix result_unit, any "available unit" is accepted
1260
1261 $available_units = $result->getAvailableResultUnits(parent::getId());
1262 $result_name = $result->getResult();
1263
1264 if ($available_units[$result_name] != null) {
1265 $check_unit = in_array($user_solution[$result_name]['unit'], $available_units[$result_name]);
1266 }
1267
1268 if ($check_unit == true) {
1269 //get unit-factor
1270 $unit_factor = assFormulaQuestionUnit::lookupUnitFactor($user_solution[$result_name]['unit']);
1271 }
1272
1273 try {
1274 $user_solution[$result->getResult()]["value"] = ilMath::_div($resVal, $unit_factor, 55);
1275 } catch (ilMathDivisionByZeroException $ex) {
1276 $user_solution[$result->getResult()]["value"] = 0;
1277 }
1278 }
1280 || $result->getResultType() == assFormulaQuestionResult::RESULT_FRAC) {
1282 if (is_array($value)) {
1283 $user_solution[$result->getResult()]["value"] = $value[0];
1284 $user_solution[$result->getResult()]["frac_helper"] = $value[1];
1285 } else {
1286 $user_solution[$result->getResult()]["value"] = $value;
1287 $user_solution[$result->getResult()]["frac_helper"] = null;
1288 }
1289 } else {
1290 $user_solution[$result->getResult()]["value"] = round($user_solution[$result->getResult()]["value"], $result->getPrecision());
1291 /*
1292 $user_solution[$result->getResult()]["value"] = ilMath::_div(
1293 $user_solution[$result->getResult()]["value"],
1294 1,
1295 $result->getPrecision()
1296 );
1297 */
1298 }
1299 }
1300 return $user_solution;
1301 }
1302
1303 public function setId($id = -1)
1304 {
1305 parent::setId($id);
1306 $this->unitrepository->setConsumerId($this->getId());
1307 }
1308
1312 public function __get($value)
1313 {
1314 switch ($value) {
1315 case "resultunits":
1316 return $this->resultunits;
1317 break;
1318 default:
1319 return parent::__get($value);
1320 break;
1321 }
1322 }
1323
1328 {
1329 $this->unitrepository = $unitrepository;
1330 }
1331
1335 public function getUnitrepository()
1336 {
1337 return $this->unitrepository;
1338 }
1339
1343 protected function getSolutionSubmit()
1344 {
1345 $solutionSubmit = array();
1346 foreach ($_POST as $k => $v) {
1347 if (preg_match("/^result_(\\\$r\\d+)$/", $k)) {
1348 $solutionSubmit[$k] = $v;
1349 } elseif (preg_match("/^result_(\\\$r\\d+)_unit$/", $k)) {
1350 $solutionSubmit[$k] = $v;
1351 }
1352 }
1353 return $solutionSubmit;
1354 }
1355
1356 public function validateSolutionSubmit()
1357 {
1358 foreach ($this->getSolutionSubmit() as $key => $value) {
1359 if (preg_match("/^result_(\\\$r\\d+)$/", $key)) {
1360 if (strlen($value) && !$this->isValidSolutionResultValue($value)) {
1361 ilUtil::sendFailure($this->lng->txt("err_no_numeric_value"), true);
1362 return false;
1363 }
1364 } elseif (preg_match("/^result_(\\\$r\\d+)_unit$/", $key)) {
1365 continue;
1366 }
1367 }
1368
1369 return true;
1370 }
1371
1380 public function getOperators($expression)
1381 {
1382 require_once "./Modules/TestQuestionPool/classes/class.ilOperatorsExpressionMapping.php";
1384 }
1385
1390 public function getExpressionTypes()
1391 {
1392 return array(
1396 );
1397 }
1398
1407 public function getUserQuestionResult($active_id, $pass)
1408 {
1410 global $DIC;
1411 $ilDB = $DIC['ilDB'];
1412 $result = new ilUserQuestionResult($this, $active_id, $pass);
1413
1414 $maxStep = $this->lookupMaxStep($active_id, $pass);
1415
1416 if ($maxStep !== null) {
1417 $data = $ilDB->queryF(
1418 "SELECT value1, value2 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s AND step = %s",
1419 array("integer", "integer", "integer",'integer'),
1420 array($active_id, $pass, $this->getId(), $maxStep)
1421 );
1422 } else {
1423 $data = $ilDB->queryF(
1424 "SELECT value1, value2 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s",
1425 array("integer", "integer", "integer"),
1426 array($active_id, $pass, $this->getId())
1427 );
1428 }
1429
1430 while ($row = $ilDB->fetchAssoc($data)) {
1431 if (strstr($row["value1"], '$r') && $row["value2"] != null) {
1432 $result->addKeyValue(str_replace('$r', "", $row["value1"]), $row["value2"]);
1433 }
1434 }
1435
1436 $points = $this->calculateReachedPoints($active_id, $pass);
1437 $max_points = $this->getMaximumPoints();
1438
1439 $result->setReachedPercentage(($points / $max_points) * 100);
1440
1441 return $result;
1442 }
1443
1452 public function getAvailableAnswerOptions($index = null)
1453 {
1454 if ($index !== null) {
1455 return $this->getResult('$r' . ($index + 1));
1456 } else {
1457 return $this->getResults();
1458 }
1459 }
1460}
$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.
purifyAndPrepareTextAreaOutput(string $content)
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
global $DIC
Definition: goto.php:24
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