|
|
|
@ -10,13 +10,13 @@ |
|
|
|
**/ |
|
|
|
**/ |
|
|
|
class FillBlanks extends Question |
|
|
|
class FillBlanks extends Question |
|
|
|
{ |
|
|
|
{ |
|
|
|
public static $typePicture = 'fill_in_blanks.png'; |
|
|
|
|
|
|
|
public static $explanationLangVar = 'FillBlanks'; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const FILL_THE_BLANK_STANDARD = 0; |
|
|
|
const FILL_THE_BLANK_STANDARD = 0; |
|
|
|
const FILL_THE_BLANK_MENU = 1; |
|
|
|
const FILL_THE_BLANK_MENU = 1; |
|
|
|
const FILL_THE_BLANK_SEVERAL_ANSWER = 2; |
|
|
|
const FILL_THE_BLANK_SEVERAL_ANSWER = 2; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static $typePicture = 'fill_in_blanks.png'; |
|
|
|
|
|
|
|
public static $explanationLangVar = 'FillBlanks'; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Constructor |
|
|
|
* Constructor |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
@ -32,7 +32,7 @@ class FillBlanks extends Question |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public function createAnswersForm($form) |
|
|
|
public function createAnswersForm($form) |
|
|
|
{ |
|
|
|
{ |
|
|
|
$defaults = array(); |
|
|
|
$defaults = []; |
|
|
|
if (!empty($this->id)) { |
|
|
|
if (!empty($this->id)) { |
|
|
|
$objectAnswer = new Answer($this->id); |
|
|
|
$objectAnswer = new Answer($this->id); |
|
|
|
$answer = $objectAnswer->selectAnswer(1); |
|
|
|
$answer = $objectAnswer->selectAnswer(1); |
|
|
|
@ -42,10 +42,10 @@ class FillBlanks extends Question |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
$defaults['multiple_answer'] = 0; |
|
|
|
$defaults['multiple_answer'] = 0; |
|
|
|
} |
|
|
|
} |
|
|
|
//take the complete string except after the last '::' |
|
|
|
// Take the complete string except after the last '::' |
|
|
|
$defaults['answer'] = $listAnswersInfo['text']; |
|
|
|
$defaults['answer'] = $listAnswersInfo['text']; |
|
|
|
$defaults['select_separator'] = $listAnswersInfo['blankseparatornumber']; |
|
|
|
$defaults['select_separator'] = $listAnswersInfo['blank_separator_number']; |
|
|
|
$blankSeparatorNumber = $listAnswersInfo['blankseparatornumber']; |
|
|
|
$blankSeparatorNumber = $listAnswersInfo['blank_separator_number']; |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
$defaults['answer'] = get_lang('DefaultTextInBlanks'); |
|
|
|
$defaults['answer'] = get_lang('DefaultTextInBlanks'); |
|
|
|
$defaults['select_separator'] = 0; |
|
|
|
$defaults['select_separator'] = 0; |
|
|
|
@ -54,20 +54,18 @@ class FillBlanks extends Question |
|
|
|
|
|
|
|
|
|
|
|
$blankSeparatorStart = self::getStartSeparator($blankSeparatorNumber); |
|
|
|
$blankSeparatorStart = self::getStartSeparator($blankSeparatorNumber); |
|
|
|
$blankSeparatorEnd = self::getEndSeparator($blankSeparatorNumber); |
|
|
|
$blankSeparatorEnd = self::getEndSeparator($blankSeparatorNumber); |
|
|
|
|
|
|
|
|
|
|
|
$setWeightAndSize = ''; |
|
|
|
$setWeightAndSize = ''; |
|
|
|
if (isset($listAnswersInfo) && count($listAnswersInfo['tabweighting']) > 0) { |
|
|
|
if (isset($listAnswersInfo) && count($listAnswersInfo['weighting']) > 0) { |
|
|
|
foreach ($listAnswersInfo['tabweighting'] as $i => $weighting) { |
|
|
|
foreach ($listAnswersInfo['weighting'] as $i => $weighting) { |
|
|
|
$setWeightAndSize .= 'document.getElementById("weighting['.$i.']").value = "'.$weighting.'";'; |
|
|
|
$setWeightAndSize .= 'document.getElementById("weighting['.$i.']").value = "'.$weighting.'";'; |
|
|
|
} |
|
|
|
} |
|
|
|
foreach ($listAnswersInfo['tabinputsize'] as $i => $sizeOfInput) { |
|
|
|
foreach ($listAnswersInfo['input_size'] as $i => $sizeOfInput) { |
|
|
|
$setWeightAndSize .= 'document.getElementById("sizeofinput['.$i.']").value = "'.$sizeOfInput.'";'; |
|
|
|
$setWeightAndSize .= 'document.getElementById("sizeofinput['.$i.']").value = "'.$sizeOfInput.'";'; |
|
|
|
$setWeightAndSize .= 'document.getElementById("samplesize['.$i.']").style.width = "'.$sizeOfInput.'px";'; |
|
|
|
$setWeightAndSize .= 'document.getElementById("samplesize['.$i.']").style.width = "'.$sizeOfInput.'px";'; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
echo '<script> |
|
|
|
echo '<script> |
|
|
|
|
|
|
|
|
|
|
|
var firstTime = true; |
|
|
|
var firstTime = true; |
|
|
|
var originalOrder = new Array(); |
|
|
|
var originalOrder = new Array(); |
|
|
|
var blankSeparatorStart = "'.$blankSeparatorStart.'"; |
|
|
|
var blankSeparatorStart = "'.$blankSeparatorStart.'"; |
|
|
|
@ -97,13 +95,16 @@ class FillBlanks extends Question |
|
|
|
|
|
|
|
|
|
|
|
// disable the save button, if not blanks have been created |
|
|
|
// disable the save button, if not blanks have been created |
|
|
|
$("button").attr("disabled", "disabled"); |
|
|
|
$("button").attr("disabled", "disabled"); |
|
|
|
$("#defineoneblank").show(); |
|
|
|
$("#defineoneblank").show(); |
|
|
|
|
|
|
|
|
|
|
|
var blanks = answer.match(eval(blanksRegexp)); |
|
|
|
var blanks = answer.match(eval(blanksRegexp)); |
|
|
|
var fields = "<div class=\"form-group \">"; |
|
|
|
var fields = "<div class=\"form-group \">"; |
|
|
|
fields += "<label class=\"col-sm-2 control-label\">'.get_lang('Weighting').'</label>"; |
|
|
|
fields += "<label class=\"col-sm-2 control-label\"></label>"; |
|
|
|
fields += "<div class=\"col-sm-8\">"; |
|
|
|
fields += "<div class=\"col-sm-8\">"; |
|
|
|
fields += "<table>"; |
|
|
|
fields += "<table class=\"data_table\">"; |
|
|
|
fields += "<tr><th style=\"padding:0 20px\">'.get_lang("WordTofind").'</th><th style=\"padding:0 20px\">'.get_lang("QuestionWeighting").'</th><th style=\"padding:0 20px\">'.get_lang("BlankInputSize").'</th></tr>"; |
|
|
|
fields += "<tr><th style=\"width:220px\">'.get_lang("WordTofind").'</th>"; |
|
|
|
|
|
|
|
fields += "<th style=\"width:50px\">'.get_lang("QuestionWeighting").'</th>"; |
|
|
|
|
|
|
|
fields += "<th>'.get_lang("BlankInputSize").'</th></tr>"; |
|
|
|
|
|
|
|
|
|
|
|
if (blanks != null) { |
|
|
|
if (blanks != null) { |
|
|
|
for (var i=0; i < blanks.length; i++) { |
|
|
|
for (var i=0; i < blanks.length; i++) { |
|
|
|
@ -133,15 +134,16 @@ class FillBlanks extends Question |
|
|
|
var value = document.getElementById("weighting["+i+"]").value; |
|
|
|
var value = document.getElementById("weighting["+i+"]").value; |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
var value = "1"; |
|
|
|
var value = "1"; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
var blanksWithColor = trimBlanksBetweenSeparator(blanks[i], blankSeparatorStart, blankSeparatorEnd, 1); |
|
|
|
|
|
|
|
|
|
|
|
fields += "<tr>"; |
|
|
|
fields += "<tr>"; |
|
|
|
fields += "<td>"+blanks[i]+"</td>"; |
|
|
|
fields += "<td>"+blanksWithColor+"</td>"; |
|
|
|
fields += "<td><input style=\"width:35px\" value=\""+value+"\" type=\"text\" id=\"weighting["+i+"]\" name=\"weighting["+i+"]\" /></td>"; |
|
|
|
fields += "<td><input class=\"form-control\" style=\"width:60px\" value=\""+value+"\" type=\"text\" id=\"weighting["+i+"]\" name=\"weighting["+i+"]\" /></td>"; |
|
|
|
fields += "<td>"; |
|
|
|
fields += "<td>"; |
|
|
|
fields += "<input class=\"btn btn-default\" type=\"button\" value=\"-\" onclick=\"changeInputSize(-1, "+i+")\"> "; |
|
|
|
fields += "<input class=\"btn btn-default\" type=\"button\" value=\"-\" onclick=\"changeInputSize(-1, "+i+")\"> "; |
|
|
|
fields += "<input class=\"btn btn-default\" type=\"button\" value=\"+\" onclick=\"changeInputSize(1, "+i+")\"> "; |
|
|
|
fields += "<input class=\"btn btn-default\" type=\"button\" value=\"+\" onclick=\"changeInputSize(1, "+i+")\"> "; |
|
|
|
fields += "<input class=\"sample\" id=\"samplesize["+i+"]\" data-btoa=\""+btoaValue+"\" type=\"text\" value=\""+textValue+"\" style=\"width:"+inputSize+"px\" disabled=disabled />"; |
|
|
|
fields += " <input class=\"sample\" id=\"samplesize["+i+"]\" data-btoa=\""+btoaValue+"\" type=\"text\" value=\""+textValue+"\" style=\"width:"+inputSize+"px\" disabled=disabled />"; |
|
|
|
fields += "<input id=\"sizeofinput["+i+"]\" type=\"hidden\" value=\""+inputSize+"\" name=\"sizeofinput["+i+"]\" />"; |
|
|
|
fields += "<input id=\"sizeofinput["+i+"]\" type=\"hidden\" value=\""+inputSize+"\" name=\"sizeofinput["+i+"]\" />"; |
|
|
|
fields += "</td>"; |
|
|
|
fields += "</td>"; |
|
|
|
fields += "</tr>"; |
|
|
|
fields += "</tr>"; |
|
|
|
@ -152,7 +154,8 @@ class FillBlanks extends Question |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
document.getElementById("blanks_weighting").innerHTML = fields + "</table></div></div>"; |
|
|
|
document.getElementById("blanks_weighting").innerHTML = fields + "</table></div></div>"; |
|
|
|
|
|
|
|
|
|
|
|
$(originalOrder).each(function(i, data) { |
|
|
|
$(originalOrder).each(function(i, data) { |
|
|
|
if (firstTime == false) { |
|
|
|
if (firstTime == false) { |
|
|
|
value = data.value; |
|
|
|
value = data.value; |
|
|
|
@ -235,7 +238,7 @@ class FillBlanks extends Question |
|
|
|
$("#samplesize\\\["+inIdNum+"\\\]").outerWidth(newWidth); |
|
|
|
$("#samplesize\\\["+inIdNum+"\\\]").outerWidth(newWidth); |
|
|
|
$("#sizeofinput\\\["+inIdNum+"\\\]").attr("value", newWidth); |
|
|
|
$("#sizeofinput\\\["+inIdNum+"\\\]").attr("value", newWidth); |
|
|
|
|
|
|
|
|
|
|
|
updateOrder(blanks); |
|
|
|
updateOrder(blanks); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function removeForbiddenChars(inTxt) |
|
|
|
function removeForbiddenChars(inTxt) |
|
|
|
@ -279,27 +282,44 @@ class FillBlanks extends Question |
|
|
|
|
|
|
|
|
|
|
|
// this function is the same than the PHP one |
|
|
|
// this function is the same than the PHP one |
|
|
|
// if modify it modify the php one getAllowedSeparator |
|
|
|
// if modify it modify the php one getAllowedSeparator |
|
|
|
function getSeparatorFromNumber(innumber) |
|
|
|
function getSeparatorFromNumber(number) |
|
|
|
{ |
|
|
|
{ |
|
|
|
tabSeparator = new Array(); |
|
|
|
var separator = new Array(); |
|
|
|
tabSeparator[0] = new Array("[", "]"); |
|
|
|
separator[0] = new Array("[", "]"); |
|
|
|
tabSeparator[1] = new Array("{", "}"); |
|
|
|
separator[1] = new Array("{", "}"); |
|
|
|
tabSeparator[2] = new Array("(", ")"); |
|
|
|
separator[2] = new Array("(", ")"); |
|
|
|
tabSeparator[3] = new Array("*", "*"); |
|
|
|
separator[3] = new Array("*", "*"); |
|
|
|
tabSeparator[4] = new Array("#", "#"); |
|
|
|
separator[4] = new Array("#", "#"); |
|
|
|
tabSeparator[5] = new Array("%", "%"); |
|
|
|
separator[5] = new Array("%", "%"); |
|
|
|
tabSeparator[6] = new Array("$", "$"); |
|
|
|
separator[6] = new Array("$", "$"); |
|
|
|
return tabSeparator[innumber]; |
|
|
|
return separator[number]; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function trimBlanksBetweenSeparator(inTxt, inSeparatorStart, inSeparatorEnd) |
|
|
|
function trimBlanksBetweenSeparator(inTxt, inSeparatorStart, inSeparatorEnd, addColor) |
|
|
|
{ |
|
|
|
{ |
|
|
|
var result = inTxt |
|
|
|
var result = inTxt |
|
|
|
result = result.replace(inSeparatorStart, ""); |
|
|
|
result = result.replace(inSeparatorStart, ""); |
|
|
|
result = result.replace(inSeparatorEnd, ""); |
|
|
|
result = result.replace(inSeparatorEnd, ""); |
|
|
|
result = result.trim(); |
|
|
|
result = result.trim(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (addColor == 1) { |
|
|
|
|
|
|
|
var resultParts = result.split("|"); |
|
|
|
|
|
|
|
var partsToString = ""; |
|
|
|
|
|
|
|
resultParts.forEach(function(item, index) { |
|
|
|
|
|
|
|
if (index == 0) { |
|
|
|
|
|
|
|
item = "<b><font style=\"color:green\"> " + item +"</font></b>"; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (index < resultParts.length - 1) { |
|
|
|
|
|
|
|
item = item + " | "; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
partsToString += item; |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
result = partsToString; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return inSeparatorStart+result+inSeparatorEnd; |
|
|
|
return inSeparatorStart+result+inSeparatorEnd; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
</script>'; |
|
|
|
</script>'; |
|
|
|
|
|
|
|
|
|
|
|
// answer |
|
|
|
// answer |
|
|
|
@ -321,14 +341,15 @@ class FillBlanks extends Question |
|
|
|
$form->addElement( |
|
|
|
$form->addElement( |
|
|
|
'select', |
|
|
|
'select', |
|
|
|
'select_separator', |
|
|
|
'select_separator', |
|
|
|
get_lang("SelectFillTheBlankSeparator"), |
|
|
|
get_lang('SelectFillTheBlankSeparator'), |
|
|
|
self::getAllowedSeparatorForSelect(), |
|
|
|
self::getAllowedSeparatorForSelect(), |
|
|
|
' id="select_separator" style="width:150px" onchange="changeBlankSeparator()" ' |
|
|
|
' id="select_separator" style="width:150px" class="selectpicker" onchange="changeBlankSeparator()" ' |
|
|
|
); |
|
|
|
); |
|
|
|
$form->addLabel( |
|
|
|
$form->addLabel( |
|
|
|
null, |
|
|
|
null, |
|
|
|
'<input type="button" onclick="updateBlanks()" value="'.get_lang('RefreshBlanks').'" class="btn btn-default" />' |
|
|
|
'<input type="button" onclick="updateBlanks()" value="'.get_lang('RefreshBlanks').'" class="btn btn-default" />' |
|
|
|
); |
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
$form->addHtml('<div id="blanks_weighting"></div>'); |
|
|
|
$form->addHtml('<div id="blanks_weighting"></div>'); |
|
|
|
|
|
|
|
|
|
|
|
global $text; |
|
|
|
global $text; |
|
|
|
@ -424,7 +445,7 @@ class FillBlanks extends Question |
|
|
|
$answer .= ","; |
|
|
|
$answer .= ","; |
|
|
|
} |
|
|
|
} |
|
|
|
// calculate the global weighting for the question |
|
|
|
// calculate the global weighting for the question |
|
|
|
$this -> weighting += $form->getSubmitValue('weighting['.$i.']'); |
|
|
|
$this->weighting += (float) $form->getSubmitValue('weighting['.$i.']'); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// input width |
|
|
|
// input width |
|
|
|
@ -497,8 +518,9 @@ class FillBlanks extends Question |
|
|
|
$displayForStudent, |
|
|
|
$displayForStudent, |
|
|
|
$inBlankNumber |
|
|
|
$inBlankNumber |
|
|
|
) { |
|
|
|
) { |
|
|
|
$inTabTeacherSolution = $listAnswersInfo['tabwords']; |
|
|
|
$inTabTeacherSolution = $listAnswersInfo['words']; |
|
|
|
$inTeacherSolution = $inTabTeacherSolution[$inBlankNumber]; |
|
|
|
$inTeacherSolution = $inTabTeacherSolution[$inBlankNumber]; |
|
|
|
|
|
|
|
|
|
|
|
switch (self::getFillTheBlankAnswerType($inTeacherSolution)) { |
|
|
|
switch (self::getFillTheBlankAnswerType($inTeacherSolution)) { |
|
|
|
case self::FILL_THE_BLANK_MENU: |
|
|
|
case self::FILL_THE_BLANK_MENU: |
|
|
|
$selected = ''; |
|
|
|
$selected = ''; |
|
|
|
@ -512,19 +534,14 @@ class FillBlanks extends Question |
|
|
|
|
|
|
|
|
|
|
|
$resultOptions = ['' => '--']; |
|
|
|
$resultOptions = ['' => '--']; |
|
|
|
foreach ($listMenu as $item) { |
|
|
|
foreach ($listMenu as $item) { |
|
|
|
$item = self::trimOption($item); |
|
|
|
$resultOptions[sha1($item)] = $item; |
|
|
|
$resultOptions[$item] = $item; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for ($k = 0; $k < count($listMenu); $k++) { |
|
|
|
//var_dump($resultOptions, $correctItem); |
|
|
|
if ($correctItem == $listMenu[$k]) { |
|
|
|
|
|
|
|
$selected = $k; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
break; |
|
|
|
foreach ($resultOptions as $key => $value) { |
|
|
|
} |
|
|
|
if ($correctItem == $value) { |
|
|
|
// if in teacher view, display the first item by default, which is the right answer |
|
|
|
$selected = $key; |
|
|
|
if ($k == 0 && !$displayForStudent) { |
|
|
|
|
|
|
|
$selected = $k; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
@ -555,12 +572,17 @@ class FillBlanks extends Question |
|
|
|
return $result; |
|
|
|
return $result; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Removes double spaces between words |
|
|
|
|
|
|
|
* @param string $text |
|
|
|
|
|
|
|
* @return string |
|
|
|
|
|
|
|
*/ |
|
|
|
private static function trimOption($text) |
|
|
|
private static function trimOption($text) |
|
|
|
{ |
|
|
|
{ |
|
|
|
$converted = strtr($text, array_flip(get_html_translation_table(HTML_ENTITIES, ENT_QUOTES))); |
|
|
|
$text = trim($text); |
|
|
|
$trimmed = trim($converted, chr(0xC2).chr(0xA0).' '); |
|
|
|
$text = preg_replace("/\s+/", " ", $text); |
|
|
|
|
|
|
|
|
|
|
|
return $trimmed; |
|
|
|
return $text; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
@ -574,8 +596,13 @@ class FillBlanks extends Question |
|
|
|
public static function getFillTheBlankMenuAnswers($correctAnswer, $displayForStudent) |
|
|
|
public static function getFillTheBlankMenuAnswers($correctAnswer, $displayForStudent) |
|
|
|
{ |
|
|
|
{ |
|
|
|
$list = api_preg_split("/\|/", $correctAnswer); |
|
|
|
$list = api_preg_split("/\|/", $correctAnswer); |
|
|
|
|
|
|
|
foreach ($list as &$item) { |
|
|
|
|
|
|
|
$item = self::trimOption($item); |
|
|
|
|
|
|
|
$item = api_html_entity_decode($item); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// The list is always in the same order, there's no option to allow or disable shuffle options. |
|
|
|
if ($displayForStudent) { |
|
|
|
if ($displayForStudent) { |
|
|
|
shuffle($list); |
|
|
|
shuffle_assoc($list); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return $list; |
|
|
|
return $list; |
|
|
|
@ -620,33 +647,49 @@ class FillBlanks extends Question |
|
|
|
* Return true if student answer is right according to the correctAnswer |
|
|
|
* Return true if student answer is right according to the correctAnswer |
|
|
|
* it is not as simple as equality, because of the type of Fill The Blank question |
|
|
|
* it is not as simple as equality, because of the type of Fill The Blank question |
|
|
|
* eg : studentAnswer = 'Un' and correctAnswer = 'Un||1||un' |
|
|
|
* eg : studentAnswer = 'Un' and correctAnswer = 'Un||1||un' |
|
|
|
* @param string $studentAnswer [studentanswer] of the info array of the answer field |
|
|
|
* @param string $studentAnswer [student_answer] of the info array of the answer field |
|
|
|
* @param string $correctAnswer [tabwords] of the info array of the answer field |
|
|
|
* @param string $correctAnswer [words] of the info array of the answer field |
|
|
|
* |
|
|
|
* @param bool $fromDatabase |
|
|
|
* @return bool |
|
|
|
* @return bool |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public static function isGoodStudentAnswer($studentAnswer, $correctAnswer) |
|
|
|
public static function isStudentAnswerGood($studentAnswer, $correctAnswer, $fromDatabase = false) |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
$result = false; |
|
|
|
switch (self::getFillTheBlankAnswerType($correctAnswer)) { |
|
|
|
switch (self::getFillTheBlankAnswerType($correctAnswer)) { |
|
|
|
case self::FILL_THE_BLANK_MENU: |
|
|
|
case self::FILL_THE_BLANK_MENU: |
|
|
|
$listMenu = self::getFillTheBlankMenuAnswers($correctAnswer, false); |
|
|
|
$listMenu = self::getFillTheBlankMenuAnswers($correctAnswer, false); |
|
|
|
$result = self::trimOption($listMenu[0]) == $studentAnswer; |
|
|
|
if ($studentAnswer != '' && isset($listMenu[0])) { |
|
|
|
|
|
|
|
// First item is always the correct one. |
|
|
|
|
|
|
|
$item = $listMenu[0]; |
|
|
|
|
|
|
|
if (!$fromDatabase) { |
|
|
|
|
|
|
|
$item = sha1($item); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if ($item === $studentAnswer) { |
|
|
|
|
|
|
|
$result = true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
break; |
|
|
|
break; |
|
|
|
case self::FILL_THE_BLANK_SEVERAL_ANSWER: |
|
|
|
case self::FILL_THE_BLANK_SEVERAL_ANSWER: |
|
|
|
// the answer must be one of the choice made |
|
|
|
// the answer must be one of the choice made |
|
|
|
$listSeveral = self::getFillTheBlankSeveralAnswers($correctAnswer); |
|
|
|
$listSeveral = self::getFillTheBlankSeveralAnswers($correctAnswer); |
|
|
|
|
|
|
|
$listSeveral = array_map( |
|
|
|
$listSeveral = array_map(function($item) { |
|
|
|
function ($item) { |
|
|
|
return self::trimOption($item); |
|
|
|
return self::trimOption($item); |
|
|
|
}, $listSeveral); |
|
|
|
}, |
|
|
|
|
|
|
|
$listSeveral |
|
|
|
|
|
|
|
); |
|
|
|
$result = in_array($studentAnswer, $listSeveral); |
|
|
|
$result = in_array($studentAnswer, $listSeveral); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case self::FILL_THE_BLANK_STANDARD: |
|
|
|
case self::FILL_THE_BLANK_STANDARD: |
|
|
|
default: |
|
|
|
default: |
|
|
|
|
|
|
|
$correctAnswer = api_html_entity_decode($correctAnswer); |
|
|
|
|
|
|
|
$studentAnswer = htmlspecialchars($studentAnswer); |
|
|
|
$result = $studentAnswer == self::trimOption($correctAnswer); |
|
|
|
$result = $studentAnswer == self::trimOption($correctAnswer); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
//var_dump($result); |
|
|
|
|
|
|
|
|
|
|
|
return $result; |
|
|
|
return $result; |
|
|
|
} |
|
|
|
} |
|
|
|
@ -658,9 +701,9 @@ class FillBlanks extends Question |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public static function getFillTheBlankAnswerType($correctAnswer) |
|
|
|
public static function getFillTheBlankAnswerType($correctAnswer) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (api_strpos($correctAnswer, "|") && !api_strpos($correctAnswer, "||")) { |
|
|
|
if (api_strpos($correctAnswer, '|') && !api_strpos($correctAnswer, '||')) { |
|
|
|
return self::FILL_THE_BLANK_MENU; |
|
|
|
return self::FILL_THE_BLANK_MENU; |
|
|
|
} elseif (api_strpos($correctAnswer, "||")) { |
|
|
|
} elseif (api_strpos($correctAnswer, '||')) { |
|
|
|
return self::FILL_THE_BLANK_SEVERAL_ANSWER; |
|
|
|
return self::FILL_THE_BLANK_SEVERAL_ANSWER; |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
return self::FILL_THE_BLANK_STANDARD; |
|
|
|
return self::FILL_THE_BLANK_STANDARD; |
|
|
|
@ -674,20 +717,20 @@ class FillBlanks extends Question |
|
|
|
* |
|
|
|
* |
|
|
|
* @return array of information about the answer |
|
|
|
* @return array of information about the answer |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public static function getAnswerInfo($userAnswer = "", $isStudentAnswer = false) |
|
|
|
public static function getAnswerInfo($userAnswer = '', $isStudentAnswer = false) |
|
|
|
{ |
|
|
|
{ |
|
|
|
$listAnswerResults = array(); |
|
|
|
$listAnswerResults = []; |
|
|
|
$listAnswerResults['text'] = ''; |
|
|
|
$listAnswerResults['text'] = ''; |
|
|
|
$listAnswerResults['wordsCount'] = 0; |
|
|
|
$listAnswerResults['words_count'] = 0; |
|
|
|
$listAnswerResults['tabwordsbracket'] = array(); |
|
|
|
$listAnswerResults['words_with_bracket'] = []; |
|
|
|
$listAnswerResults['tabwords'] = array(); |
|
|
|
$listAnswerResults['words'] = []; |
|
|
|
$listAnswerResults['tabweighting'] = array(); |
|
|
|
$listAnswerResults['weighting'] = []; |
|
|
|
$listAnswerResults['tabinputsize'] = array(); |
|
|
|
$listAnswerResults['input_size'] = []; |
|
|
|
$listAnswerResults['switchable'] = ''; |
|
|
|
$listAnswerResults['switchable'] = ''; |
|
|
|
$listAnswerResults['studentanswer'] = array(); |
|
|
|
$listAnswerResults['student_answer'] = []; |
|
|
|
$listAnswerResults['studentscore'] = array(); |
|
|
|
$listAnswerResults['student_score'] = []; |
|
|
|
$listAnswerResults['blankseparatornumber'] = 0; |
|
|
|
$listAnswerResults['blank_separator_number'] = 0; |
|
|
|
$listDoubleColon = array(); |
|
|
|
$listDoubleColon = []; |
|
|
|
|
|
|
|
|
|
|
|
api_preg_match("/(.*)::(.*)$/s", $userAnswer, $listResult); |
|
|
|
api_preg_match("/(.*)::(.*)$/s", $userAnswer, $listResult); |
|
|
|
|
|
|
|
|
|
|
|
@ -699,22 +742,22 @@ class FillBlanks extends Question |
|
|
|
$listDoubleColon[] = $listResult[2]; |
|
|
|
$listDoubleColon[] = $listResult[2]; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
$listAnswerResults['systemstring'] = $listDoubleColon[1]; |
|
|
|
$listAnswerResults['system_string'] = $listDoubleColon[1]; |
|
|
|
|
|
|
|
|
|
|
|
// make sure we only take the last bit to find special marks |
|
|
|
// Make sure we only take the last bit to find special marks |
|
|
|
$listArobaseSplit = explode('@', $listDoubleColon[1]); |
|
|
|
$listArobaseSplit = explode('@', $listDoubleColon[1]); |
|
|
|
|
|
|
|
|
|
|
|
if (count($listArobaseSplit) < 2) { |
|
|
|
if (count($listArobaseSplit) < 2) { |
|
|
|
$listArobaseSplit[1] = ''; |
|
|
|
$listArobaseSplit[1] = ''; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// take the complete string except after the last '::' |
|
|
|
// Take the complete string except after the last '::' |
|
|
|
$listDetails = explode(":", $listArobaseSplit[0]); |
|
|
|
$listDetails = explode(":", $listArobaseSplit[0]); |
|
|
|
|
|
|
|
|
|
|
|
// < number of item after the ::[score]:[size]:[separator_id]@ , here there are 3 |
|
|
|
// < number of item after the ::[score]:[size]:[separator_id]@ , here there are 3 |
|
|
|
if (count($listDetails) < 3) { |
|
|
|
if (count($listDetails) < 3) { |
|
|
|
$listWeightings = explode(',', $listDetails[0]); |
|
|
|
$listWeightings = explode(',', $listDetails[0]); |
|
|
|
$listSizeOfInput = array(); |
|
|
|
$listSizeOfInput = []; |
|
|
|
for ($i = 0; $i < count($listWeightings); $i++) { |
|
|
|
for ($i = 0; $i < count($listWeightings); $i++) { |
|
|
|
$listSizeOfInput[] = 200; |
|
|
|
$listSizeOfInput[] = 200; |
|
|
|
} |
|
|
|
} |
|
|
|
@ -726,27 +769,27 @@ class FillBlanks extends Question |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
$listAnswerResults['text'] = $listDoubleColon[0]; |
|
|
|
$listAnswerResults['text'] = $listDoubleColon[0]; |
|
|
|
$listAnswerResults['tabweighting'] = $listWeightings; |
|
|
|
$listAnswerResults['weighting'] = $listWeightings; |
|
|
|
$listAnswerResults['tabinputsize'] = $listSizeOfInput; |
|
|
|
$listAnswerResults['input_size'] = $listSizeOfInput; |
|
|
|
$listAnswerResults['switchable'] = $listArobaseSplit[1]; |
|
|
|
$listAnswerResults['switchable'] = $listArobaseSplit[1]; |
|
|
|
$listAnswerResults['blankseparatorstart'] = self::getStartSeparator($blankSeparatorNumber); |
|
|
|
$listAnswerResults['blank_separator_start'] = self::getStartSeparator($blankSeparatorNumber); |
|
|
|
$listAnswerResults['blankseparatorend'] = self::getEndSeparator($blankSeparatorNumber); |
|
|
|
$listAnswerResults['blank_separator_end'] = self::getEndSeparator($blankSeparatorNumber); |
|
|
|
$listAnswerResults['blankseparatornumber'] = $blankSeparatorNumber; |
|
|
|
$listAnswerResults['blank_separator_number'] = $blankSeparatorNumber; |
|
|
|
|
|
|
|
|
|
|
|
$blankCharStart = self::getStartSeparator($blankSeparatorNumber); |
|
|
|
$blankCharStart = self::getStartSeparator($blankSeparatorNumber); |
|
|
|
$blankCharEnd = self::getEndSeparator($blankSeparatorNumber); |
|
|
|
$blankCharEnd = self::getEndSeparator($blankSeparatorNumber); |
|
|
|
$blankCharStartForRegexp = self::escapeForRegexp($blankCharStart); |
|
|
|
$blankCharStartForRegexp = self::escapeForRegexp($blankCharStart); |
|
|
|
$blankCharEndForRegexp = self::escapeForRegexp($blankCharEnd); |
|
|
|
$blankCharEndForRegexp = self::escapeForRegexp($blankCharEnd); |
|
|
|
|
|
|
|
|
|
|
|
// get all blanks words |
|
|
|
// Get all blanks words |
|
|
|
$listAnswerResults['wordsCount'] = api_preg_match_all( |
|
|
|
$listAnswerResults['words_count'] = api_preg_match_all( |
|
|
|
'/'.$blankCharStartForRegexp.'[^'.$blankCharEndForRegexp.']*'.$blankCharEndForRegexp.'/', |
|
|
|
'/'.$blankCharStartForRegexp.'[^'.$blankCharEndForRegexp.']*'.$blankCharEndForRegexp.'/', |
|
|
|
$listDoubleColon[0], |
|
|
|
$listDoubleColon[0], |
|
|
|
$listWords |
|
|
|
$listWords |
|
|
|
); |
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
if ($listAnswerResults['wordsCount'] > 0) { |
|
|
|
if ($listAnswerResults['words_count'] > 0) { |
|
|
|
$listAnswerResults['tabwordsbracket'] = $listWords[0]; |
|
|
|
$listAnswerResults['words_with_bracket'] = $listWords[0]; |
|
|
|
// remove [ and ] in string |
|
|
|
// remove [ and ] in string |
|
|
|
array_walk( |
|
|
|
array_walk( |
|
|
|
$listWords[0], |
|
|
|
$listWords[0], |
|
|
|
@ -759,10 +802,10 @@ class FillBlanks extends Question |
|
|
|
}, |
|
|
|
}, |
|
|
|
array($blankCharStart, $blankCharEnd) |
|
|
|
array($blankCharStart, $blankCharEnd) |
|
|
|
); |
|
|
|
); |
|
|
|
$listAnswerResults['tabwords'] = $listWords[0]; |
|
|
|
$listAnswerResults['words'] = $listWords[0]; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// get all common words |
|
|
|
// Get all common words |
|
|
|
$commonWords = api_preg_replace( |
|
|
|
$commonWords = api_preg_replace( |
|
|
|
'/'.$blankCharStartForRegexp.'[^'.$blankCharEndForRegexp.']*'.$blankCharEndForRegexp.'/', |
|
|
|
'/'.$blankCharStartForRegexp.'[^'.$blankCharEndForRegexp.']*'.$blankCharEndForRegexp.'/', |
|
|
|
"::", |
|
|
|
"::", |
|
|
|
@ -771,32 +814,31 @@ class FillBlanks extends Question |
|
|
|
|
|
|
|
|
|
|
|
// if student answer, the second [] is the student answer, |
|
|
|
// if student answer, the second [] is the student answer, |
|
|
|
// the third is if student scored or not |
|
|
|
// the third is if student scored or not |
|
|
|
$listBrackets = array(); |
|
|
|
$listBrackets = []; |
|
|
|
$listWords = array(); |
|
|
|
$listWords = []; |
|
|
|
|
|
|
|
|
|
|
|
if ($isStudentAnswer) { |
|
|
|
if ($isStudentAnswer) { |
|
|
|
for ($i = 0; $i < count($listAnswerResults['tabwords']); $i++) { |
|
|
|
for ($i = 0; $i < count($listAnswerResults['words']); $i++) { |
|
|
|
$listBrackets[] = $listAnswerResults['tabwordsbracket'][$i]; |
|
|
|
$listBrackets[] = $listAnswerResults['words_with_bracket'][$i]; |
|
|
|
$listWords[] = $listAnswerResults['tabwords'][$i]; |
|
|
|
$listWords[] = $listAnswerResults['words'][$i]; |
|
|
|
if ($i + 1 < count($listAnswerResults['tabwords'])) { |
|
|
|
if ($i + 1 < count($listAnswerResults['words'])) { |
|
|
|
// should always be |
|
|
|
// should always be |
|
|
|
$i++; |
|
|
|
$i++; |
|
|
|
} |
|
|
|
} |
|
|
|
$listAnswerResults['studentanswer'][] = $listAnswerResults['tabwords'][$i]; |
|
|
|
$listAnswerResults['student_answer'][] = $listAnswerResults['words'][$i]; |
|
|
|
if ($i + 1 < count($listAnswerResults['tabwords'])) { |
|
|
|
if ($i + 1 < count($listAnswerResults['words'])) { |
|
|
|
// should always be |
|
|
|
// should always be |
|
|
|
$i++; |
|
|
|
$i++; |
|
|
|
} |
|
|
|
} |
|
|
|
$listAnswerResults['studentscore'][] = $listAnswerResults['tabwords'][$i]; |
|
|
|
$listAnswerResults['student_score'][] = $listAnswerResults['words'][$i]; |
|
|
|
} |
|
|
|
} |
|
|
|
$listAnswerResults['tabwords'] = $listWords; |
|
|
|
$listAnswerResults['words'] = $listWords; |
|
|
|
$listAnswerResults['tabwordsbracket'] = $listBrackets; |
|
|
|
$listAnswerResults['words_with_bracket'] = $listBrackets; |
|
|
|
|
|
|
|
|
|
|
|
// if we are in student view, we've got 3 times :::::: for common words |
|
|
|
// if we are in student view, we've got 3 times :::::: for common words |
|
|
|
$commonWords = api_preg_replace("/::::::/", "::", $commonWords); |
|
|
|
$commonWords = api_preg_replace("/::::::/", "::", $commonWords); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
$listAnswerResults['commonwords'] = explode("::", $commonWords); |
|
|
|
$listAnswerResults['common_words'] = explode("::", $commonWords); |
|
|
|
|
|
|
|
|
|
|
|
return $listAnswerResults; |
|
|
|
return $listAnswerResults; |
|
|
|
} |
|
|
|
} |
|
|
|
@ -838,7 +880,7 @@ class FillBlanks extends Question |
|
|
|
$courseId = api_get_course_int_id(); |
|
|
|
$courseId = api_get_course_int_id(); |
|
|
|
// If no user has answered questions, no need to go further. Return empty array. |
|
|
|
// If no user has answered questions, no need to go further. Return empty array. |
|
|
|
if (empty($studentsIdList)) { |
|
|
|
if (empty($studentsIdList)) { |
|
|
|
return array(); |
|
|
|
return []; |
|
|
|
} |
|
|
|
} |
|
|
|
// request to have all the answers of student for this question |
|
|
|
// request to have all the answers of student for this question |
|
|
|
// student may have doing it several time |
|
|
|
// student may have doing it several time |
|
|
|
@ -860,29 +902,29 @@ class FillBlanks extends Question |
|
|
|
'; |
|
|
|
'; |
|
|
|
|
|
|
|
|
|
|
|
$res = Database::query($sql); |
|
|
|
$res = Database::query($sql); |
|
|
|
$tabUserResult = array(); |
|
|
|
$tabUserResult = []; |
|
|
|
// foreach attempts for all students starting with his older attempt |
|
|
|
// foreach attempts for all students starting with his older attempt |
|
|
|
while ($data = Database::fetch_array($res)) { |
|
|
|
while ($data = Database::fetch_array($res)) { |
|
|
|
$tabAnswer = self::getAnswerInfo($data['answer'], true); |
|
|
|
$tabAnswer = self::getAnswerInfo($data['answer'], true); |
|
|
|
|
|
|
|
|
|
|
|
// for each bracket to find in this question |
|
|
|
// for each bracket to find in this question |
|
|
|
foreach ($tabAnswer['studentanswer'] as $bracketNumber => $studentAnswer) { |
|
|
|
foreach ($tabAnswer['student_answer'] as $bracketNumber => $studentAnswer) { |
|
|
|
if ($tabAnswer['studentanswer'][$bracketNumber] != '') { |
|
|
|
if ($tabAnswer['student_answer'][$bracketNumber] != '') { |
|
|
|
// student has answered this bracket, cool |
|
|
|
// student has answered this bracket, cool |
|
|
|
switch (self::getFillTheBlankAnswerType($tabAnswer['tabwords'][$bracketNumber])) { |
|
|
|
switch (self::getFillTheBlankAnswerType($tabAnswer['words'][$bracketNumber])) { |
|
|
|
case self::FILL_THE_BLANK_MENU: |
|
|
|
case self::FILL_THE_BLANK_MENU: |
|
|
|
// get the indice of the choosen answer in the menu |
|
|
|
// get the indice of the choosen answer in the menu |
|
|
|
// we know that the right answer is the first entry of the menu, ie 0 |
|
|
|
// we know that the right answer is the first entry of the menu, ie 0 |
|
|
|
// (remember, menu entries are shuffled when taking the test) |
|
|
|
// (remember, menu entries are shuffled when taking the test) |
|
|
|
$tabUserResult[$data['user_id']][$bracketNumber] = self::getFillTheBlankMenuAnswerNum( |
|
|
|
$tabUserResult[$data['user_id']][$bracketNumber] = self::getFillTheBlankMenuAnswerNum( |
|
|
|
$tabAnswer['tabwords'][$bracketNumber], |
|
|
|
$tabAnswer['words'][$bracketNumber], |
|
|
|
$tabAnswer['studentanswer'][$bracketNumber] |
|
|
|
$tabAnswer['student_answer'][$bracketNumber] |
|
|
|
); |
|
|
|
); |
|
|
|
break; |
|
|
|
break; |
|
|
|
default: |
|
|
|
default: |
|
|
|
if (self::isGoodStudentAnswer( |
|
|
|
if (self::isStudentAnswerGood( |
|
|
|
$tabAnswer['studentanswer'][$bracketNumber], |
|
|
|
$tabAnswer['student_answer'][$bracketNumber], |
|
|
|
$tabAnswer['tabwords'][$bracketNumber] |
|
|
|
$tabAnswer['words'][$bracketNumber] |
|
|
|
) |
|
|
|
) |
|
|
|
) { |
|
|
|
) { |
|
|
|
$tabUserResult[$data['user_id']][$bracketNumber] = 0; // right answer |
|
|
|
$tabUserResult[$data['user_id']][$bracketNumber] = 0; // right answer |
|
|
|
@ -939,20 +981,20 @@ class FillBlanks extends Question |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public static function getAnswerInStudentAttempt($listWithStudentAnswer) |
|
|
|
public static function getAnswerInStudentAttempt($listWithStudentAnswer) |
|
|
|
{ |
|
|
|
{ |
|
|
|
$separatorStart = $listWithStudentAnswer['blankseparatorstart']; |
|
|
|
$separatorStart = $listWithStudentAnswer['blank_separator_start']; |
|
|
|
$separatorEnd = $listWithStudentAnswer['blankseparatorend']; |
|
|
|
$separatorEnd = $listWithStudentAnswer['blank_separator_end']; |
|
|
|
// lets rebuild the sentence with [correct answer][student answer][answer is correct] |
|
|
|
// lets rebuild the sentence with [correct answer][student answer][answer is correct] |
|
|
|
$result = ''; |
|
|
|
$result = ''; |
|
|
|
for ($i = 0; $i < count($listWithStudentAnswer['commonwords']) - 1; $i++) { |
|
|
|
for ($i = 0; $i < count($listWithStudentAnswer['common_words']) - 1; $i++) { |
|
|
|
$result .= $listWithStudentAnswer['commonwords'][$i]; |
|
|
|
$result .= $listWithStudentAnswer['common_words'][$i]; |
|
|
|
$result .= $listWithStudentAnswer['tabwordsbracket'][$i]; |
|
|
|
$result .= $listWithStudentAnswer['words_with_bracket'][$i]; |
|
|
|
$result .= $separatorStart.$listWithStudentAnswer['studentanswer'][$i].$separatorEnd; |
|
|
|
$result .= $separatorStart.$listWithStudentAnswer['student_answer'][$i].$separatorEnd; |
|
|
|
$result .= $separatorStart.$listWithStudentAnswer['studentscore'][$i].$separatorEnd; |
|
|
|
$result .= $separatorStart.$listWithStudentAnswer['student_score'][$i].$separatorEnd; |
|
|
|
} |
|
|
|
} |
|
|
|
$result .= $listWithStudentAnswer['commonwords'][$i]; |
|
|
|
$result .= $listWithStudentAnswer['common_words'][$i]; |
|
|
|
$result .= "::"; |
|
|
|
$result .= "::"; |
|
|
|
// add the system string |
|
|
|
// add the system string |
|
|
|
$result .= $listWithStudentAnswer['systemstring']; |
|
|
|
$result .= $listWithStudentAnswer['system_string']; |
|
|
|
|
|
|
|
|
|
|
|
return $result; |
|
|
|
return $result; |
|
|
|
} |
|
|
|
} |
|
|
|
@ -1038,17 +1080,15 @@ class FillBlanks extends Question |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public static function getAllowedSeparator() |
|
|
|
public static function getAllowedSeparator() |
|
|
|
{ |
|
|
|
{ |
|
|
|
$fillBlanksAllowedSeparator = array( |
|
|
|
return [ |
|
|
|
array('[', ']'), |
|
|
|
['[', ']'], |
|
|
|
array('{', '}'), |
|
|
|
['{', '}'], |
|
|
|
array('(', ')'), |
|
|
|
['(', ')'], |
|
|
|
array('*', '*'), |
|
|
|
['*', '*'], |
|
|
|
array('#', '#'), |
|
|
|
['#', '#'], |
|
|
|
array('%', '%'), |
|
|
|
['%', '%'], |
|
|
|
array('$', '$'), |
|
|
|
['$', '$'], |
|
|
|
); |
|
|
|
]; |
|
|
|
|
|
|
|
|
|
|
|
return $fillBlanksAllowedSeparator; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
@ -1084,10 +1124,10 @@ class FillBlanks extends Question |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public static function getAllowedSeparatorForSelect() |
|
|
|
public static function getAllowedSeparatorForSelect() |
|
|
|
{ |
|
|
|
{ |
|
|
|
$listResults = array(); |
|
|
|
$listResults = []; |
|
|
|
$fillBlanksAllowedSeparator = self::getAllowedSeparator(); |
|
|
|
$allowedSeparator = self::getAllowedSeparator(); |
|
|
|
for ($i = 0; $i < count($fillBlanksAllowedSeparator); $i++) { |
|
|
|
foreach ($allowedSeparator as $part) { |
|
|
|
$listResults[] = $fillBlanksAllowedSeparator[$i][0]."...".$fillBlanksAllowedSeparator[$i][1]; |
|
|
|
$listResults[] = $part[0]."...".$part[1]; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return $listResults; |
|
|
|
return $listResults; |
|
|
|
@ -1142,19 +1182,19 @@ class FillBlanks extends Question |
|
|
|
|
|
|
|
|
|
|
|
// rebuild the answer with good HTML style |
|
|
|
// rebuild the answer with good HTML style |
|
|
|
// this is the student answer, right or wrong |
|
|
|
// this is the student answer, right or wrong |
|
|
|
for ($i = 0; $i < count($listStudentAnswerInfo['studentanswer']); $i++) { |
|
|
|
for ($i = 0; $i < count($listStudentAnswerInfo['student_answer']); $i++) { |
|
|
|
if ($listStudentAnswerInfo['studentscore'][$i] == 1) { |
|
|
|
if ($listStudentAnswerInfo['student_score'][$i] == 1) { |
|
|
|
$listStudentAnswerInfo['studentanswer'][$i] = self::getHtmlRightAnswer( |
|
|
|
$listStudentAnswerInfo['student_answer'][$i] = self::getHtmlRightAnswer( |
|
|
|
$listStudentAnswerInfo['studentanswer'][$i], |
|
|
|
$listStudentAnswerInfo['student_answer'][$i], |
|
|
|
$listStudentAnswerInfo['tabwords'][$i], |
|
|
|
$listStudentAnswerInfo['words'][$i], |
|
|
|
$feedbackType, |
|
|
|
$feedbackType, |
|
|
|
$resultsDisabled, |
|
|
|
$resultsDisabled, |
|
|
|
$showTotalScoreAndUserChoices |
|
|
|
$showTotalScoreAndUserChoices |
|
|
|
); |
|
|
|
); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
$listStudentAnswerInfo['studentanswer'][$i] = self::getHtmlWrongAnswer( |
|
|
|
$listStudentAnswerInfo['student_answer'][$i] = self::getHtmlWrongAnswer( |
|
|
|
$listStudentAnswerInfo['studentanswer'][$i], |
|
|
|
$listStudentAnswerInfo['student_answer'][$i], |
|
|
|
$listStudentAnswerInfo['tabwords'][$i], |
|
|
|
$listStudentAnswerInfo['words'][$i], |
|
|
|
$feedbackType, |
|
|
|
$feedbackType, |
|
|
|
$resultsDisabled, |
|
|
|
$resultsDisabled, |
|
|
|
$showTotalScoreAndUserChoices |
|
|
|
$showTotalScoreAndUserChoices |
|
|
|
@ -1163,13 +1203,13 @@ class FillBlanks extends Question |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// rebuild the sentence with student answer inserted |
|
|
|
// rebuild the sentence with student answer inserted |
|
|
|
for ($i = 0; $i < count($listStudentAnswerInfo['commonwords']); $i++) { |
|
|
|
for ($i = 0; $i < count($listStudentAnswerInfo['common_words']); $i++) { |
|
|
|
$result .= isset($listStudentAnswerInfo['commonwords'][$i]) ? $listStudentAnswerInfo['commonwords'][$i] : ''; |
|
|
|
$result .= isset($listStudentAnswerInfo['common_words'][$i]) ? $listStudentAnswerInfo['common_words'][$i] : ''; |
|
|
|
$result .= isset($listStudentAnswerInfo['studentanswer'][$i]) ? $listStudentAnswerInfo['studentanswer'][$i] : ''; |
|
|
|
$result .= isset($listStudentAnswerInfo['student_answer'][$i]) ? $listStudentAnswerInfo['student_answer'][$i] : ''; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// the last common word (should be </p>) |
|
|
|
// the last common word (should be </p>) |
|
|
|
$result .= isset($listStudentAnswerInfo['commonwords'][$i]) ? $listStudentAnswerInfo['commonwords'][$i] : ''; |
|
|
|
$result .= isset($listStudentAnswerInfo['common_words'][$i]) ? $listStudentAnswerInfo['common_words'][$i] : ''; |
|
|
|
|
|
|
|
|
|
|
|
return $result; |
|
|
|
return $result; |
|
|
|
} |
|
|
|
} |
|
|
|
@ -1254,7 +1294,9 @@ class FillBlanks extends Question |
|
|
|
* return HTML code for correct answer |
|
|
|
* return HTML code for correct answer |
|
|
|
* @param string $answer |
|
|
|
* @param string $answer |
|
|
|
* @param string $correct |
|
|
|
* @param string $correct |
|
|
|
* @param bool $resultsDisabled |
|
|
|
* @param string $feedbackType |
|
|
|
|
|
|
|
* @param bool $resultsDisabled |
|
|
|
|
|
|
|
* @param bool $showTotalScoreAndUserChoices |
|
|
|
* |
|
|
|
* |
|
|
|
* @return string |
|
|
|
* @return string |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
@ -1279,6 +1321,7 @@ class FillBlanks extends Question |
|
|
|
* return HTML code for wrong answer |
|
|
|
* return HTML code for wrong answer |
|
|
|
* @param string $answer |
|
|
|
* @param string $answer |
|
|
|
* @param string $correct |
|
|
|
* @param string $correct |
|
|
|
|
|
|
|
* @param string $feedbackType |
|
|
|
* @param bool $resultsDisabled |
|
|
|
* @param bool $resultsDisabled |
|
|
|
* |
|
|
|
* |
|
|
|
* @return string |
|
|
|
* @return string |
|
|
|
@ -1308,13 +1351,13 @@ class FillBlanks extends Question |
|
|
|
public static function isCorrect($answerText) |
|
|
|
public static function isCorrect($answerText) |
|
|
|
{ |
|
|
|
{ |
|
|
|
$answerInfo = self::getAnswerInfo($answerText, true); |
|
|
|
$answerInfo = self::getAnswerInfo($answerText, true); |
|
|
|
$correctAnswerList = $answerInfo['tabwords']; |
|
|
|
$correctAnswerList = $answerInfo['words']; |
|
|
|
$studentAnswer = $answerInfo['studentanswer']; |
|
|
|
$studentAnswer = $answerInfo['student_answer']; |
|
|
|
$isCorrect = true; |
|
|
|
$isCorrect = true; |
|
|
|
|
|
|
|
|
|
|
|
foreach ($correctAnswerList as $i => $correctAnswer) { |
|
|
|
foreach ($correctAnswerList as $i => $correctAnswer) { |
|
|
|
$isGoodStudentAnswer = self::isGoodStudentAnswer($studentAnswer[$i], $correctAnswer); |
|
|
|
$value = self::isStudentAnswerGood($studentAnswer[$i], $correctAnswer); |
|
|
|
$isCorrect = $isCorrect && $isGoodStudentAnswer; |
|
|
|
$isCorrect = $isCorrect && $value; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return $isCorrect; |
|
|
|
return $isCorrect; |
|
|
|
|