4 require_once
'./Modules/TestQuestionPool/classes/class.assQuestion.php';
5 require_once
'./Modules/Test/classes/inc.AssessmentConstants.php';
6 require_once
'./Modules/TestQuestionPool/interfaces/interface.ilObjQuestionScoringAdjustable.php';
7 require_once
'./Modules/TestQuestionPool/interfaces/interface.ilObjAnswerScoringAdjustable.php';
8 require_once
'./Modules/TestQuestionPool/interfaces/interface.iQuestionCondition.php';
9 require_once
'./Modules/TestQuestionPool/classes/class.ilUserQuestionResult.php';
50 $this->errortext =
'';
51 $this->textsize = 100.0;
52 $this->errordata = array();
62 if (strlen($this->title)
90 $ilDB->manipulateF(
"DELETE FROM qpl_a_errortext WHERE question_fi = %s",
92 array( $this->
getId() )
96 foreach ($this->errordata as $object)
98 $next_id = $ilDB->nextId(
'qpl_a_errortext' );
99 $ilDB->manipulateF(
"INSERT INTO qpl_a_errortext (answer_id, question_fi, text_wrong, text_correct, points, sequence) VALUES (%s, %s, %s, %s, %s, %s)",
100 array(
'integer',
'integer',
'text',
'text',
'float',
'integer' ),
105 $object->text_correct,
124 array( $this->
getId() )
127 $ilDB->manipulateF(
"INSERT INTO " . $this->
getAdditionalTableName() .
" (question_fi, errortext, textsize, points_wrong) VALUES (%s, %s, %s, %s)",
128 array(
"integer",
"text",
"float",
"float"),
155 $this->
setId($question_id);
164 include_once(
"./Services/RTE/classes/class.ilRTE.php");
180 $result = $ilDB->queryF(
"SELECT * FROM qpl_a_errortext WHERE question_fi = %s ORDER BY sequence ASC",
184 include_once
"./Modules/TestQuestionPool/classes/class.assAnswerErrorText.php";
193 parent::loadFromDb($question_id);
207 $this_id = $this->
getId();
211 include_once (
"./Modules/TestQuestionPool/classes/class.assQuestion.php");
215 if( (
int)$testObjId > 0 )
217 $clone->setObjId($testObjId);
243 $clone->copyPageOfQuestion($this_id);
245 $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
247 $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
263 $thisId = $this->
getId();
267 include_once (
"./Modules/TestQuestionPool/classes/class.assQuestion.php");
270 $clone->setObjId($target_questionpool_id);
282 $clone->onCopy($thisObjId, $thisId, $clone->getObjId(), $clone->getId());
295 include_once (
"./Modules/TestQuestionPool/classes/class.assQuestion.php");
298 $sourceParentId = $this->
getObjId();
304 $clone->setObjId($targetParentId);
306 if ($targetQuestionTitle)
308 $clone->setTitle($targetQuestionTitle);
313 $clone->copyPageOfQuestion($sourceQuestionId);
315 $clone->copyXHTMLMediaObjectsOfQuestion($sourceQuestionId);
317 $clone->onCopy($sourceParentId, $sourceQuestionId, $clone->getObjId(), $clone->getId());
330 foreach ($this->errordata as $object)
332 if ($object->points > 0) $maxpoints += $object->points;
351 throw new ilTestException(
'return details not implemented for '.__METHOD__);
357 $positions = array();
358 if (is_null(
$pass)) {
364 array_push($positions,
$row[
'value1']);
390 include_once
"./Modules/Test/classes/class.ilObjTest.php";
398 $entered_values =
false;
401 $selected = split(
",",
$_POST[
"qst_" . $this->
getId()]);
402 foreach ($selected as $position)
406 $entered_values =
true;
413 include_once (
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
421 include_once (
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
435 $selection = explode(
',',
$_POST[
"qst_{$this->getId()}"]);
439 $selection = array();
465 return "assErrorText";
475 return "qpl_qst_errortext";
485 return "qpl_a_errortext";
494 $text = parent::getRTETextWithMediaObjects();
511 include_once (
"./Services/Excel/classes/class.ilExcelUtils.php");
516 $selections = array();
518 if (is_array($solutions))
520 foreach ($solutions as $solution)
522 array_push($selections, $solution[
'value1']);
524 $errortext_value = join(
",", $selections);
530 return $startrow + $i + 1;
545 public function fromXML(&$item, &$questionpool_id, &$tst_id, &$tst_object, &$question_counter, &$import_mapping)
547 include_once
"./Modules/TestQuestionPool/classes/import/qti12/class.assErrorTextImport.php";
549 $import->fromXML($item, $questionpool_id, $tst_id, $tst_object, $question_counter, $import_mapping);
558 public function toXML($a_include_header =
true, $a_include_binary =
true, $a_shuffle =
false, $test_output =
false, $force_image_references =
false)
560 include_once
"./Modules/TestQuestionPool/classes/export/qti12/class.assErrorTextExport.php";
562 return $export->toXML($a_include_header, $a_include_binary, $a_shuffle, $test_output, $force_image_references);
572 $user_solution = array();
573 return $user_solution;
578 if (strlen($a_text) == 0)
584 $a_text = str_replace(array(
"((",
"))"), array(
"~",
"~"), $a_text);
588 $r_passage =
"/(~([^~]+)~|#([^\s]+))/";
590 preg_match_all($r_passage, $a_text, $matches);
592 if (is_array($matches[0]) && !empty($matches[0])) {
597 $matches = array_intersect_key($matches, array(2 =>
'', 3 =>
''));
600 $matches[2] = array_diff($matches[2], array(
''));
601 $matches[3] = array_diff($matches[3], array(
''));
604 "passages" => $matches[2],
605 "words" => $matches[3],);
613 include_once
"./Modules/TestQuestionPool/classes/class.assAnswerErrorText.php";
615 $this->errordata = array();
616 foreach ($a_data as $err_type =>
$errors) {
619 foreach (
$errors as $idx => $error) {
623 foreach ($temp as $object) {
624 if (strcmp($object->text_wrong, $error) == 0) {
625 $text_correct = $object->text_correct;
633 ksort($this->errordata);
636 public function createErrorTextOutput($selections = null, $graphicalOutput =
false, $correct_solution =
false, $use_link_tags =
true)
640 include_once
"./Services/Utilities/classes/class.ilStr.php";
641 if (!is_array($selections)) $selections = array();
642 $textarray = preg_split(
"/[\n\r]+/", $this->
getErrorText());
644 foreach ($textarray as $textidx =>
$text)
647 $passage_end =
false;
648 $items = preg_split(
"/\s+/",
$text);
649 foreach ($items as $idx => $item)
654 ($posHash = strpos($item,
'#')) === 0 ||
655 ($posOpeningBrackets = strpos($item,
'((')) === 0 ||
656 ($posClosingBrackets = strpos($item,
'))')) !==
false 661 if($posHash !==
false)
663 $item = ilStr::substr($item, 1, ilStr::strlen($item) - 1);
664 $passage_end =
false;
666 else if($posOpeningBrackets !==
false)
669 $passage_start_idx = $counter;
670 $items_in_passage = array();
671 $passage_end =
false;
672 $item = ilStr::substr($item, 2, ilStr::strlen($item) - 2);
676 if(strpos($item,
'))') !==
false)
678 $item = str_replace(
"))",
"", $item);
685 $item = str_replace(
"))",
"", $item);
688 if($correct_solution && !$in_passage)
690 $errorobject = $this->errordata[$errorcounter];
691 if (is_object($errorobject) )
693 $item = strlen($errorobject->text_correct) ? $errorobject->text_correct :
' ';
699 if($in_passage && !$passage_end)
701 $items_in_passage[$idx] = $item;
707 if($in_passage && $passage_end)
710 $passage_end =
false;
711 if($correct_solution)
714 "ilc_qetitem_ErrorTextSelected" :
"ilc_qetitem_ErrorTextItem" 717 $errorobject = $this->errordata[$errorcounter];
718 if (is_object($errorobject) )
720 $item = strlen($errorobject->text_correct) ? $errorobject->text_correct :
' ';
728 $group_selected =
true;
731 $start_idx = $passage_start_idx;
732 foreach($items_in_passage as $tmp_idx => $tmp_item)
736 $group_selected =
false;
746 $group_selected =
false;
751 $item_stack = array();
752 $start_idx = $passage_start_idx;
753 foreach($items_in_passage as $tmp_idx => $tmp_item)
756 "ilc_qetitem_ErrorTextSelected" :
"ilc_qetitem_ErrorTextItem" 762 "ilc_qetitem_ErrorTextSelected" :
"ilc_qetitem_ErrorTextItem" 768 $img =
' <img src="' .
ilUtil::getImagePath(
"icon_ok.svg") .
'" alt="' . $this->lng->txt(
"answer_is_right") .
'" title="' . $this->lng->txt(
"answer_is_right") .
'" /> ';
772 $img =
' <img src="' .
ilUtil::getImagePath(
"icon_not_ok.svg") .
'" alt="' . $this->lng->txt(
"answer_is_wrong") .
'" title="' . $this->lng->txt(
"answer_is_wrong") .
'" /> ';
777 $item_stack = trim(implode(
" ", $item_stack));
778 $item_stack = strlen($item_stack) ? $item_stack :
' ';
782 $items[$idx] =
'<span class="selGroup">'.$item_stack.
'</span>';
786 $items[$idx] = $item_stack;
794 $class =
'ilc_qetitem_ErrorTextItem';
798 $class =
"ilc_qetitem_ErrorTextSelected";
803 $img =
' <img src="' .
ilUtil::getImagePath(
"icon_ok.svg") .
'" alt="' . $this->lng->txt(
"answer_is_right") .
'" title="' . $this->lng->txt(
"answer_is_right") .
'" /> ';
807 $img =
' <img src="' .
ilUtil::getImagePath(
"icon_not_ok.svg") .
'" alt="' . $this->lng->txt(
"answer_is_wrong") .
'" title="' . $this->lng->txt(
"answer_is_wrong") .
'" /> ';
815 $textarray[$textidx] =
'<p>' . implode(
" ", $items) .
'</p>';
818 return implode(
"\n", $textarray);
823 foreach($selection as
$data)
825 if( !is_array($data) )
827 if($counter == $data)
832 elseif( in_array($counter, $data) )
845 include_once
"./Services/Utilities/classes/class.ilStr.php";
846 if (!is_array($selections)) $selections = array();
847 $textarray = preg_split(
"/[\n\r]+/", $this->
getErrorText());
848 foreach ($textarray as $textidx =>
$text)
850 $items = preg_split(
"/\s+/",
$text);
851 foreach ($items as $idx => $item)
853 if (($posHash = strpos($item,
'#')) === 0
854 || ($posOpeningBrackets = strpos($item,
'((')) === 0
855 || ($posClosingBrackets = strpos($item,
'))')) !==
false) {
858 if ($posHash !==
false)
859 $item = ilStr::substr($item, 1, ilStr::strlen($item) - 1);
860 elseif ($posOpeningBrackets !==
false) {
861 $item = ilStr::substr($item, 2, ilStr::strlen($item) - 2);
865 if (strpos($item,
'))') !==
false)
866 $item = ilStr::substr($item, 0, ilStr::strlen($item) - 2);
870 if ($item{$posClosingBrackets+2} ==
',')
873 $item = ilStr::substr($item, 0, $posClosingBrackets) . $appendComma;
878 if (in_array($counter, $selections))
883 if (in_array($counter, $selections))
887 $items[$idx] = $word;
890 $textarray[$textidx] = join($items,
" ");
892 return join($textarray,
"\n");
901 $textarray = preg_split(
"/[\n\r]+/", $this->
getErrorText());
902 foreach ($textarray as $textidx =>
$text)
904 $items = preg_split(
"/\s+/",
$text);
906 foreach ($items as $word)
909 $isErrorItem =
false;
910 if (strpos($word,
'#') === 0)
913 $errorobject = $this->errordata[$errorcounter];
914 if (is_object($errorobject))
916 $points = $errorobject->points;
921 elseif (($posOpeningBracket = strpos($word,
'((')) === 0
922 || ($posClosingBracket = strpos($word,
'))')) !==
false 927 if ($posOpeningBracket !==
false)
929 $passages[] = array(
'begin_pos' => $counter,
'cnt_words' => 0);
932 elseif ($posClosingBracket !==
false)
935 $cur_pidx = count($passages) - 1;
936 $passages[$cur_pidx][
'end_pos'] = $counter;
938 $errorobject = $this->errordata[$errorcounter];
939 if (is_object($errorobject))
941 $passages[$cur_pidx][
'score'] = $errorobject->points;
942 $passages[$cur_pidx][
'isError'] =
true;
948 $cur_pidx = count($passages) - 1;
949 $passages[$cur_pidx][
'cnt_words']++;
953 $words[$counter] = array(
"word" => $word,
"points" =>
$points,
"isError" => $isErrorItem);
958 $selections = array();
959 foreach ($passages as $cnt => $pdata)
961 if (!$withPositivePointsOnly && $pdata[
'isError'] || $withPositivePointsOnly && $pdata[
'score'] > 0)
963 $indexes = range($pdata[
'begin_pos'], $pdata[
'end_pos']);
964 $selections[$pdata[
'begin_pos']] = $indexes;
968 foreach ($words as $idx => $word)
970 if (!$withPositivePointsOnly && $word[
'isError'] || $withPositivePointsOnly && $word[
'points'] > 0)
972 $selections[$idx] = array($idx);
978 $selections = array_values($selections);
989 $textarray = preg_split(
"/[\n\r]+/", $this->
getErrorText());
990 foreach ($textarray as $textidx =>
$text)
992 $items = preg_split(
"/\s+/",
$text);
994 foreach ($items as $word)
997 if (strpos($word,
'#') === 0)
1000 $errorobject = $this->errordata[$errorcounter];
1001 if (is_object($errorobject))
1003 $points = $errorobject->points;
1007 elseif (($posOpeningBracket = strpos($word,
'((')) === 0
1008 || ($posClosingBracket = strpos($word,
'))')) !==
false 1013 if ($posOpeningBracket !==
false)
1015 $passages[] = array(
'begin_pos' => $counter,
'cnt_words' => 0);
1018 elseif ($posClosingBracket !==
false)
1021 $cur_pidx = count($passages) - 1;
1022 $passages[$cur_pidx][
'end_pos'] = $counter;
1024 $errorobject = $this->errordata[$errorcounter];
1025 if (is_object($errorobject))
1027 $passages[$cur_pidx][
'score'] = $errorobject->points;
1032 $cur_pidx = count($passages) - 1;
1033 $passages[$cur_pidx][
'cnt_words']++;
1037 $words[$counter] = array(
"word" => $word,
"points" =>
$points);
1044 foreach ($positions as $position)
1049 $total += $words[$position][
'points'];
1052 foreach ($passages as $cnt => $p_data)
1058 $isSelected = in_array($p_data[
'begin_pos'], $positions);
1060 for ($i = 0; $i < $p_data[
'cnt_words']; $i++)
1062 $current_pos = $p_data[
'begin_pos'] + $i;
1063 $isSelected = $isSelected && in_array($current_pos, $positions);
1066 $total += $isSelected ? $p_data[
'score'] : 0;
1077 $this->errordata = array();
1082 include_once
"./Modules/TestQuestionPool/classes/class.assAnswerErrorText.php";
1113 $this->errortext = $a_value;
1134 if($a_value === null)
1138 $this->textsize = $a_value;
1158 $this->points_wrong = $a_value;
1174 case "points_wrong":
1178 return parent::__get($value);
1196 case "points_wrong":
1200 parent::__set($key, $value);
1211 include_once(
"./Services/RTE/classes/class.ilRTE.php");
1221 'onenotcorrect' => $this->
formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(),
false)),
1222 'allcorrect' => $this->
formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(),
true))
1228 array_push($answers, array(
1229 "answertext_wrong" => (
string) $answer_obj->text_wrong,
1230 "answertext_correct" => (
string) $answer_obj->text_correct,
1231 "points" => (
float)$answer_obj->points,
1232 "order" => (
int)$idx+1
1235 $result[
'correct_answers'] = $answers;
1238 $textarray = preg_split(
"/[\n\r]+/", $this->
getErrorText());
1239 foreach ($textarray as $textidx =>
$text)
1241 $items = preg_split(
"/\s+/", trim(
$text));
1242 foreach ($items as $idx => $item)
1244 if(substr($item, 0, 1) ==
"#")
1246 $item = substr($item, 1);
1249 foreach(
$result[
"correct_answers"] as $aidx => $answer)
1251 if($answer[
"answertext_wrong"] == $item && !$answer[
"pos"])
1253 $result[
"correct_answers"][$aidx][
"pos"] = $this->
getId().
"_".$textidx.
"_".($idx+1);
1258 array_push($answers, array(
1260 "order" => $this->
getId().
"_".$textidx.
"_".($idx+1)
1263 if($textidx !=
sizeof($textarray)-1)
1265 array_push($answers, array(
1266 "answertext" =>
"###",
1267 "order" => $this->
getId().
"_".$textidx.
"_".($idx+2)
1271 $result[
'answers'] = $answers;
1289 require_once
"./Modules/TestQuestionPool/classes/class.ilOperatorsExpressionMapping.php";
1321 $data = $ilDB->queryF(
1322 "SELECT value1+1 as value1 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s AND step = ( 1323 SELECT MAX(step) FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s 1325 array(
"integer",
"integer",
"integer",
"integer",
"integer",
"integer"),
1352 $error_text_array = explode(
' ', $this->errortext);
1356 if(array_key_exists($index, $error_text_array))
1358 return $error_text_array[$index];
1364 return $error_text_array;
getErrorText()
Get error text.
getId()
Gets the id of the assQuestion object.
static prepareFormOutput($a_str, $a_strip=false)
prepares string output for html forms public
getErrorData()
Get error data.
static _getOriginalId($question_id)
Returns the original id of a question.
formatSAQuestion($a_q)
Format self assessment question.
const PercentageResultExpression
Class iQuestionCondition.
setTextSize($a_value)
Set text size in percent.
toJSON()
Returns a JSON representation of the question.
reworkWorkingData($active_id, $pass, $obligationsAnswered)
Reworks the allready saved working data if neccessary.
const NumberOfResultExpression
const ExclusiveResultExpression
getTextSize()
Set text size in percent.
createErrorTextExport($selections=null)
Abstract basic class which is to be extended by the concrete assessment question type classes...
_getPass($active_id)
Retrieves the actual pass of a given user for a given test.
loadFromDb($question_id)
Loads the object from the database.
_convert_text($a_text, $a_target="has been removed")
getRTETextWithMediaObjects()
Collects all text in the question which could contain media objects which were created with the Rich ...
toXML($a_include_header=true, $a_include_binary=true, $a_shuffle=false, $test_output=false, $force_image_references=false)
Returns a QTI xml representation of the question and sets the internal domxml variable with the DOM X...
__get($value)
Object getter.
createErrorTextOutput($selections=null, $graphicalOutput=false, $correct_solution=false, $use_link_tags=true)
saveToDb($original_id="")
Saves a the object to the database.
isTokenSelected($counter, array $selection)
getErrorsFromText($a_text="")
setId($id=-1)
Sets the id of the assQuestion object.
setErrorText($a_value)
Set error text.
getSolutionMaxPass($active_id)
Returns the maximum pass a users question solution.
setEstimatedWorkingTime($hour=0, $min=0, $sec=0)
Sets the estimated working time of a question from given hour, minute and second. ...
copyObject($target_questionpool_id, $title="")
Copies an object.
getQuestionType()
Returns the question type of the question.
saveCurrentSolution($active_id, $pass, $value1, $value2, $authorized=true)
Class for error text answers.
getParticipantsSolution()
getUserQuestionResult($active_id, $pass)
Get the user solution for a question by active_id and the test pass.
setNrOfTries($a_nr_of_tries)
_enabledAssessmentLogging()
check wether assessment logging is enabled or not
fromXML(&$item, &$questionpool_id, &$tst_id, &$tst_object, &$question_counter, &$import_mapping)
Creates a question from a QTI file.
setAdditionalContentEditingMode($additinalContentEditingMode)
setter for additional content editing mode for this question
Class for error text question exports.
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...
__construct( $title='', $comment='', $author='', $owner=-1, $question='')
assErorText constructor
getObjId()
Get the object id of the container object.
getShuffle()
Gets the shuffle flag.
Base Exception for all Exceptions relating to Modules/Test.
setParticipantsSolution($participantSolution)
getPointsWrong()
Get wrong points.
isComplete()
Returns true, if a single choice question is complete for use.
setAuthor($author="")
Sets the authors name of the assQuestion object.
getPointsForSelectedPositions($positions)
Class ilUserQuestionResult.
removeCurrentSolution($active_id, $pass, $authorized=true, $ignoredSolutionIds=array())
setExportDetailsXLS(&$worksheet, $startrow, $active_id, $pass, &$format_title, &$format_bold)
Creates an Excel worksheet for the detailed cumulated results of this question.
static getImagePath($img, $module_path="", $mode="output", $offline=false)
get image path (for images located in a template directory)
getBestSolution($active_id, $pass)
Returns the best solution for a given pass of a participant.
setPointsWrong($a_value)
Set wrong points.
saveWorkingData($active_id, $pass=NULL, $authorized=true)
Saves the learners input of the question to the database.
getOperators($expression)
Get all available operations for a specific question.
calculateReachedPointsFromPreviewSession(ilAssQuestionPreviewSession $previewSession)
Class for error text questions.
Interface ilObjAnswerScoringAdjustable.
duplicate($for_test=true, $title="", $author="", $owner="", $testObjId=null)
Duplicates the object.
saveAnswerSpecificDataToDb()
Saves the answer specific records into a question types answer table.
getQuestion()
Gets the question string of the question object.
getExpressionTypes()
Get all available expression types for a specific question.
savePreviewData(ilAssQuestionPreviewSession $previewSession)
getAdditionalTableName()
Returns the name of the additional question data table in the database.
_getLogLanguage()
retrieve the log language for assessment logging
static getOperatorsByExpression($expression)
getMaximumPoints()
Returns the maximum points, a learner can reach answering the question.
setPoints($a_points)
Sets the maximum available points for the question.
saveQuestionDataToDb($original_id="")
createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle="")
setQuestion($question="")
Sets the question string of the question object.
Interface ilObjQuestionScoringAdjustable.
getBestSelection($withPositivePointsOnly=true)
setOriginalId($original_id)
getCurrentSolutionResultSet($active_id, $pass, $authorized=true)
Get a restulset for the current user solution for a this question by active_id and pass...
__set($key, $value)
Object setter.
getSolutionValues($active_id, $pass=NULL, $authorized=true)
Loads solutions of a given user from the database an returns it.
logAction($logtext="", $active_id="", $question_id="")
Logs an action into the Test&Assessment log.
getTitle()
Gets the title string of the assQuestion object.
calculateReachedPoints($active_id, $pass=NULL, $authorizedSolution=true, $returndetails=FALSE)
Returns the points, a learner has reached answering the question.
saveAdditionalQuestionDataToDb()
Saves the data for the additional data table.
addErrorData($text_wrong, $text_correct, $points)
getAvailableAnswerOptions($index=null)
If index is null, the function returns an array with all anwser options Else it returns the specific ...
setTitle($title="")
Sets the title string of the assQuestion object.
setObjId($obj_id=0)
Set the object id of the container object.
flushErrorData()
Flush error data.
setComment($comment="")
Sets the comment string of the assQuestion object.
getAnswerTableName()
Returns the name of the answer table in the database.
getErrorTokenHtml($item, $class, $useLinkTags)
Class for error text question imports.
setOwner($owner="")
Sets the creator/owner ID of the assQuestion object.
const EmptyAnswerExpression