4require_once
'./Modules/TestQuestionPool/classes/class.assQuestion.php';
5require_once
'./Modules/Test/classes/inc.AssessmentConstants.php';
6require_once
'./Modules/TestQuestionPool/interfaces/interface.ilObjQuestionScoringAdjustable.php';
7require_once
'./Modules/TestQuestionPool/interfaces/interface.ilObjAnswerScoringAdjustable.php';
8require_once
'./Modules/TestQuestionPool/interfaces/interface.iQuestionCondition.php';
9require_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']);
392 include_once
"./Modules/Test/classes/class.ilObjTest.php";
396 $entered_values =
false;
398 $this->
getProcessLocker()->executeUserSolutionUpdateLockOperation(
function() use (&$entered_values, $active_id,
$pass, $authorized) {
404 $selected = explode(
",",
$_POST[
"qst_" . $this->
getId()]);
405 foreach ($selected as $position)
409 $entered_values =
true;
416 include_once (
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
424 include_once (
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
438 $selection = explode(
',',
$_POST[
"qst_{$this->getId()}"]);
442 $selection = array();
463 return "assErrorText";
473 return "qpl_qst_errortext";
483 return "qpl_a_errortext";
492 $text = parent::getRTETextWithMediaObjects();
504 $selections = array();
506 if (is_array($solutions))
508 foreach ($solutions as $solution)
510 array_push($selections, $solution[
'value1']);
512 $errortext_value = join(
",", $selections);
519 return $startrow + $i + 1;
534 public function fromXML(&$item, &$questionpool_id, &$tst_id, &$tst_object, &$question_counter, &$import_mapping)
536 include_once
"./Modules/TestQuestionPool/classes/import/qti12/class.assErrorTextImport.php";
538 $import->fromXML($item, $questionpool_id, $tst_id, $tst_object, $question_counter, $import_mapping);
547 public function toXML($a_include_header =
true, $a_include_binary =
true, $a_shuffle =
false, $test_output =
false, $force_image_references =
false)
549 include_once
"./Modules/TestQuestionPool/classes/export/qti12/class.assErrorTextExport.php";
551 return $export->toXML($a_include_header, $a_include_binary, $a_shuffle, $test_output, $force_image_references);
561 $user_solution = array();
562 return $user_solution;
567 if (strlen($a_text) == 0)
573 $a_text = str_replace(array(
"((",
"))"), array(
"~",
"~"), $a_text);
577 $r_passage =
"/(~([^~]+)~|#([^\s]+))/";
579 preg_match_all($r_passage, $a_text, $matches);
581 if (is_array($matches[0]) && !empty($matches[0])) {
586 $matches = array_intersect_key($matches, array(2 =>
'', 3 =>
''));
589 $matches[2] = array_diff($matches[2], array(
''));
590 $matches[3] = array_diff($matches[3], array(
''));
593 "passages" => $matches[2],
594 "words" => $matches[3],);
602 include_once
"./Modules/TestQuestionPool/classes/class.assAnswerErrorText.php";
604 $this->errordata = array();
605 foreach ($a_data as $err_type =>
$errors) {
612 foreach ($temp as $object) {
613 if (strcmp($object->text_wrong,
$error) == 0) {
614 $text_correct = $object->text_correct;
622 ksort($this->errordata);
625 public function createErrorTextOutput($selections =
null, $graphicalOutput =
false, $correct_solution =
false, $use_link_tags =
true)
629 include_once
"./Services/Utilities/classes/class.ilStr.php";
630 if (!is_array($selections)) $selections = array();
631 $textarray = preg_split(
"/[\n\r]+/", $this->
getErrorText());
633 foreach ($textarray as $textidx =>
$text)
636 $passage_end =
false;
637 $items = preg_split(
"/\s+/",
$text);
638 foreach ($items as $idx => $item)
643 ($posHash = strpos($item,
'#')) === 0 ||
644 ($posOpeningBrackets = strpos($item,
'((')) === 0 ||
645 ($posClosingBrackets = strpos($item,
'))')) !==
false
650 if($posHash !==
false)
652 $item = ilStr::substr($item, 1, ilStr::strlen($item) - 1);
653 $passage_end =
false;
655 else if($posOpeningBrackets !==
false)
659 $items_in_passage = array();
660 $passage_end =
false;
661 $item = ilStr::substr($item, 2, ilStr::strlen($item) - 2);
665 if(strpos($item,
'))') !==
false)
667 $item = str_replace(
"))",
"", $item);
674 $item = str_replace(
"))",
"", $item);
677 if($correct_solution && !$in_passage)
679 $errorobject = $this->errordata[$errorcounter];
680 if (is_object($errorobject) )
682 $item = strlen($errorobject->text_correct) ? $errorobject->text_correct :
' ';
688 if($in_passage && !$passage_end)
690 $items_in_passage[$idx] = $item;
696 if($in_passage && $passage_end)
699 $passage_end =
false;
700 if($correct_solution)
703 "ilc_qetitem_ErrorTextSelected" :
"ilc_qetitem_ErrorTextItem"
706 $errorobject = $this->errordata[$errorcounter];
707 if (is_object($errorobject) )
709 $item = strlen($errorobject->text_correct) ? $errorobject->text_correct :
' ';
717 $group_selected =
true;
720 $start_idx = $passage_start_idx;
721 foreach($items_in_passage as $tmp_idx => $tmp_item)
725 $group_selected =
false;
735 $group_selected =
false;
740 $item_stack = array();
741 $start_idx = $passage_start_idx;
742 foreach($items_in_passage as $tmp_idx => $tmp_item)
745 "ilc_qetitem_ErrorTextSelected" :
"ilc_qetitem_ErrorTextItem"
751 "ilc_qetitem_ErrorTextSelected" :
"ilc_qetitem_ErrorTextItem"
757 $img =
' <img src="' .
ilUtil::getImagePath(
"icon_ok.svg") .
'" alt="' . $this->lng->txt(
"answer_is_right") .
'" title="' . $this->lng->txt(
"answer_is_right") .
'" /> ';
761 $img =
' <img src="' .
ilUtil::getImagePath(
"icon_not_ok.svg") .
'" alt="' . $this->lng->txt(
"answer_is_wrong") .
'" title="' . $this->lng->txt(
"answer_is_wrong") .
'" /> ';
766 $item_stack = trim(implode(
" ", $item_stack));
767 $item_stack = strlen($item_stack) ? $item_stack :
' ';
771 $items[$idx] =
'<span class="selGroup">'.$item_stack.
'</span>';
775 $items[$idx] = $item_stack;
783 $class =
'ilc_qetitem_ErrorTextItem';
787 $class =
"ilc_qetitem_ErrorTextSelected";
792 $img =
' <img src="' .
ilUtil::getImagePath(
"icon_ok.svg") .
'" alt="' . $this->lng->txt(
"answer_is_right") .
'" title="' . $this->lng->txt(
"answer_is_right") .
'" /> ';
796 $img =
' <img src="' .
ilUtil::getImagePath(
"icon_not_ok.svg") .
'" alt="' . $this->lng->txt(
"answer_is_wrong") .
'" title="' . $this->lng->txt(
"answer_is_wrong") .
'" /> ';
804 $textarray[$textidx] =
'<p>' . implode(
" ", $items) .
'</p>';
807 return implode(
"\n", $textarray);
812 foreach($selection as
$data)
814 if( !is_array(
$data) )
834 include_once
"./Services/Utilities/classes/class.ilStr.php";
835 if (!is_array($selections)) $selections = array();
836 $textarray = preg_split(
"/[\n\r]+/", $this->
getErrorText());
837 foreach ($textarray as $textidx =>
$text)
839 $items = preg_split(
"/\s+/",
$text);
840 foreach ($items as $idx => $item)
842 if (($posHash = strpos($item,
'#')) === 0
843 || ($posOpeningBrackets = strpos($item,
'((')) === 0
844 || ($posClosingBrackets = strpos($item,
'))')) !==
false) {
847 if ($posHash !==
false)
848 $item = ilStr::substr($item, 1, ilStr::strlen($item) - 1);
849 elseif ($posOpeningBrackets !==
false) {
850 $item = ilStr::substr($item, 2, ilStr::strlen($item) - 2);
854 if (strpos($item,
'))') !==
false)
855 $item = ilStr::substr($item, 0, ilStr::strlen($item) - 2);
859 if ($item{$posClosingBrackets+2} ==
',')
862 $item = ilStr::substr($item, 0, $posClosingBrackets) . $appendComma;
867 if (in_array(
$counter, $selections))
872 if (in_array(
$counter, $selections))
876 $items[$idx] = $word;
879 $textarray[$textidx] = join($items,
" ");
881 return join($textarray,
"\n");
890 $textarray = preg_split(
"/[\n\r]+/", $this->
getErrorText());
891 foreach ($textarray as $textidx =>
$text)
893 $items = preg_split(
"/\s+/",
$text);
895 foreach ($items as $word)
898 $isErrorItem =
false;
899 if (strpos($word,
'#') === 0)
902 $errorobject = $this->errordata[$errorcounter];
903 if (is_object($errorobject))
905 $points = $errorobject->points;
910 elseif (($posOpeningBracket = strpos($word,
'((')) === 0
911 || ($posClosingBracket = strpos($word,
'))')) !==
false
916 if ($posOpeningBracket !==
false)
918 $passages[] = array(
'begin_pos' =>
$counter,
'cnt_words' => 0);
921 elseif ($posClosingBracket !==
false)
924 $cur_pidx = count($passages) - 1;
925 $passages[$cur_pidx][
'end_pos'] =
$counter;
927 $errorobject = $this->errordata[$errorcounter];
928 if (is_object($errorobject))
930 $passages[$cur_pidx][
'score'] = $errorobject->points;
931 $passages[$cur_pidx][
'isError'] =
true;
937 $cur_pidx = count($passages) - 1;
938 $passages[$cur_pidx][
'cnt_words']++;
942 $words[
$counter] = array(
"word" => $word,
"points" =>
$points,
"isError" => $isErrorItem);
947 $selections = array();
948 foreach ($passages as $cnt => $pdata)
950 if (!$withPositivePointsOnly && $pdata[
'isError'] || $withPositivePointsOnly && $pdata[
'score'] > 0)
952 $indexes = range($pdata[
'begin_pos'], $pdata[
'end_pos']);
953 $selections[$pdata[
'begin_pos']] = $indexes;
957 foreach ($words as $idx => $word)
959 if (!$withPositivePointsOnly && $word[
'isError'] || $withPositivePointsOnly && $word[
'points'] > 0)
961 $selections[$idx] = array($idx);
967 $selections = array_values($selections);
978 $textarray = preg_split(
"/[\n\r]+/", $this->
getErrorText());
979 foreach ($textarray as $textidx =>
$text)
981 $items = preg_split(
"/\s+/",
$text);
983 foreach ($items as $word)
986 if (strpos($word,
'#') === 0)
989 $errorobject = $this->errordata[$errorcounter];
990 if (is_object($errorobject))
992 $points = $errorobject->points;
996 elseif (($posOpeningBracket = strpos($word,
'((')) === 0
997 || ($posClosingBracket = strpos($word,
'))')) !==
false
1002 if ($posOpeningBracket !==
false)
1004 $passages[] = array(
'begin_pos' =>
$counter,
'cnt_words' => 0);
1007 elseif ($posClosingBracket !==
false)
1010 $cur_pidx = count($passages) - 1;
1011 $passages[$cur_pidx][
'end_pos'] =
$counter;
1013 $errorobject = $this->errordata[$errorcounter];
1014 if (is_object($errorobject))
1016 $passages[$cur_pidx][
'score'] = $errorobject->points;
1021 $cur_pidx = count($passages) - 1;
1022 $passages[$cur_pidx][
'cnt_words']++;
1033 foreach ($positions as $position)
1038 $total += $words[$position][
'points'];
1041 foreach ($passages as $cnt => $p_data)
1047 $isSelected = in_array($p_data[
'begin_pos'], $positions);
1049 for ($i = 0; $i < $p_data[
'cnt_words']; $i++)
1051 $current_pos = $p_data[
'begin_pos'] + $i;
1052 $isSelected = $isSelected && in_array($current_pos, $positions);
1055 $total += $isSelected ? $p_data[
'score'] : 0;
1066 $this->errordata = array();
1071 include_once
"./Modules/TestQuestionPool/classes/class.assAnswerErrorText.php";
1102 $this->errortext = $a_value;
1123 if($a_value ===
null)
1127 $this->textsize = $a_value;
1147 $this->points_wrong = $a_value;
1163 case "points_wrong":
1167 return parent::__get($value);
1185 case "points_wrong":
1189 parent::__set($key, $value);
1200 include_once(
"./Services/RTE/classes/class.ilRTE.php");
1210 'onenotcorrect' => $this->
formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(),
false)),
1211 'allcorrect' => $this->formatSAQuestion($this->feedbackOBJ->getGenericFeedbackTestPresentation($this->getId(),
true))
1217 array_push($answers, array(
1218 "answertext_wrong" => (
string) $answer_obj->text_wrong,
1219 "answertext_correct" => (
string) $answer_obj->text_correct,
1220 "points" => (
float)$answer_obj->points,
1221 "order" => (
int)$idx+1
1224 $result[
'correct_answers'] = $answers;
1227 $textarray = preg_split(
"/[\n\r]+/", $this->
getErrorText());
1228 foreach ($textarray as $textidx =>
$text)
1230 $items = preg_split(
"/\s+/", trim(
$text));
1231 foreach ($items as $idx => $item)
1233 if(substr($item, 0, 1) ==
"#")
1235 $item = substr($item, 1);
1238 foreach(
$result[
"correct_answers"] as $aidx => $answer)
1240 if($answer[
"answertext_wrong"] == $item && !$answer[
"pos"])
1242 $result[
"correct_answers"][$aidx][
"pos"] = $this->
getId().
"_".$textidx.
"_".($idx+1);
1247 array_push($answers, array(
1249 "order" => $this->
getId().
"_".$textidx.
"_".($idx+1)
1252 if($textidx !=
sizeof($textarray)-1)
1254 array_push($answers, array(
1255 "answertext" =>
"###",
1256 "order" => $this->
getId().
"_".$textidx.
"_".($idx+2)
1260 $result[
'answers'] = $answers;
1278 require_once
"./Modules/TestQuestionPool/classes/class.ilOperatorsExpressionMapping.php";
1311 "SELECT value1+1 as value1 FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s AND step = (
1312 SELECT MAX(step) FROM tst_solutions WHERE active_fi = %s AND pass = %s AND question_fi = %s
1314 array(
"integer",
"integer",
"integer",
"integer",
"integer",
"integer"),
1341 $error_text_array = explode(
' ', $this->errortext);
1345 if(array_key_exists($index, $error_text_array))
1347 return $error_text_array[$index];
1353 return $error_text_array;
An exception for terminatinating execution or to throw for unit testing.
Class for error text answers.
Class for error text question exports.
Class for error text question imports.
Class for error text questions.
getErrorData()
Get error data.
reworkWorkingData($active_id, $pass, $obligationsAnswered, $authorized)
{Reworks the allready saved working data if neccessary.}
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...
flushErrorData()
Flush error data.
saveWorkingData($active_id, $pass=NULL, $authorized=true)
Saves the learners input of the question to the database.
loadFromDb($question_id)
Loads the object from the database.
getTextSize()
Set text size in percent.
getOperators($expression)
Get all available operations for a specific question.
calculateReachedPoints($active_id, $pass=NULL, $authorizedSolution=true, $returndetails=FALSE)
Returns the points, a learner has reached answering the question.
__construct( $title='', $comment='', $author='', $owner=-1, $question='')
assErorText constructor
getAvailableAnswerOptions($index=null)
If index is null, the function returns an array with all anwser options Else it returns the specific ...
getErrorsFromText($a_text="")
__get($value)
Object getter.
createErrorTextExport($selections=null)
duplicate($for_test=true, $title="", $author="", $owner="", $testObjId=null)
Duplicates the object.
savePreviewData(ilAssQuestionPreviewSession $previewSession)
__set($key, $value)
Object setter.
getErrorText()
Get error text.
toJSON()
Returns a JSON representation of the question.
createErrorTextOutput($selections=null, $graphicalOutput=false, $correct_solution=false, $use_link_tags=true)
setTextSize($a_value)
Set text size in percent.
setErrorText($a_value)
Set error text.
getAnswerTableName()
Returns the name of the answer table in the database.
saveToDb($original_id="")
Saves a the object to the database.
setExportDetailsXLS($worksheet, $startrow, $active_id, $pass)
{Creates an Excel worksheet for the detailed cumulated results of this question.object}
saveAnswerSpecificDataToDb()
Saves the answer specific records into a question types answer table.
copyObject($target_questionpool_id, $title="")
Copies an object.
setPointsWrong($a_value)
Set wrong points.
calculateReachedPointsFromPreviewSession(ilAssQuestionPreviewSession $previewSession)
getErrorTokenHtml($item, $class, $useLinkTags)
getBestSelection($withPositivePointsOnly=true)
getMaximumPoints()
Returns the maximum points, a learner can reach answering the question.
getRTETextWithMediaObjects()
Collects all text in the question which could contain media objects which were created with the Rich ...
getPointsForSelectedPositions($positions)
createNewOriginalFromThisDuplicate($targetParentId, $targetQuestionTitle="")
getAdditionalTableName()
Returns the name of the additional question data table in the database.
getPointsWrong()
Get wrong points.
isTokenSelected($counter, array $selection)
isComplete()
Returns true, if a single choice question is complete for use.
getBestSolution($active_id, $pass)
Returns the best solution for a given pass of a participant.
fromXML(&$item, &$questionpool_id, &$tst_id, &$tst_object, &$question_counter, &$import_mapping)
Creates a question from a QTI file.
saveAdditionalQuestionDataToDb()
Saves the data for the additional data table.
addErrorData($text_wrong, $text_correct, $points)
getExpressionTypes()
Get all available expression types for a specific question.
getQuestionType()
Returns the question type of the question.
Abstract basic class which is to be extended by the concrete assessment question type classes.
getCurrentSolutionResultSet($active_id, $pass, $authorized=true)
Get a restulset for the current user solution for a this question by active_id and pass.
static _getOriginalId($question_id)
Returns the original id of a question.
formatSAQuestion($a_q)
Format self assessment question.
setId($id=-1)
Sets the id of the assQuestion object.
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.
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.
removeCurrentSolution($active_id, $pass, $authorized=true)
setAuthor($author="")
Sets the authors name of the assQuestion object.
getSolutionValues($active_id, $pass=NULL, $authorized=true)
Loads solutions of a given user from the database an returns it.
getShuffle()
Gets the shuffle flag.
getTitle()
Gets the title string of the assQuestion object.
setPoints($a_points)
Sets the maximum available points for the question.
setComment($comment="")
Sets the comment string of the assQuestion object.
setNrOfTries($a_nr_of_tries)
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)
getParticipantsSolution()
setParticipantsSolution($participantSolution)
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 getOperatorsByExpression($expression)
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...
Base Exception for all Exceptions relating to Modules/Test.
Class ilUserQuestionResult.
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.
const PercentageResultExpression
getUserQuestionResult($active_id, $pass)
Get the user solution for a question by active_id and the test pass.
const EmptyAnswerExpression
const ExclusiveResultExpression
const NumberOfResultExpression
Interface ilObjAnswerScoringAdjustable.
Interface ilObjQuestionScoringAdjustable.