Skip to content

Commit

Permalink
MDL-1625 Make multianswer questions more tolerant if one of the subqu…
Browse files Browse the repository at this point in the history
…estions is missing
  • Loading branch information
pichetp committed May 18, 2008
1 parent 239ba4e commit df79079
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 32 deletions.
16 changes: 13 additions & 3 deletions question/type/multianswer/edit_multianswer_form.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,13 @@ function definition_inner(&$mform) {
$this->questiondisplay = "";
}

if ( isset($this->questiondisplay->options->questions) && count($this->questiondisplay->options->questions) > 0 ) {
$countsubquestions = count($this->questiondisplay->options->questions);
if ( isset($this->questiondisplay->options->questions) && is_array($this->questiondisplay->options->questions) ) {
$countsubquestions =0;
foreach($this->questiondisplay->options->questions as $subquestion){
if ($subquestion != ''){
$countsubquestions++;
}
}
} else {
$countsubquestions =0;
}
Expand All @@ -61,6 +66,9 @@ function definition_inner(&$mform) {
$mform->addElement('static', 'sub_'.$sub."_".'defaultgrade', get_string('defaultgrade', 'quiz'));
$mform->setDefault('sub_'.$sub."_".'defaultgrade',$this->questiondisplay->options->questions[$sub]->defaultgrade);

if ($this->questiondisplay->options->questions[$sub]->qtype =='multichoice' ) {
$mform->addElement('checkbox', 'sub_'.$sub."_".'layout', get_string('layout', 'quiz')) ;//, $gradeoptions);
}
foreach ($this->questiondisplay->options->questions[$sub]->answer as $key =>$ans) {

$mform->addElement('static', 'sub_'.$sub."_".'answer['.$key.']', get_string('answer', 'quiz'), array('cols'=>60, 'rows'=>1));
Expand All @@ -84,6 +92,7 @@ function set_data($question) {
if (isset($question->id) and $question->id and $question->qtype and $question->questiontext) {

foreach ($question->options->questions as $key => $wrapped) {
if($wrapped != ''){
// The old way of restoring the definitions is kept to gradually
// update all multianswer questions
if (empty($wrapped->questiontext)) {
Expand Down Expand Up @@ -127,6 +136,7 @@ function set_data($question) {
$question->questiontext = str_replace("{#$key}", $parsableanswerdef, $question->questiontext);
}
}
}

// set default to $questiondisplay questions elements
if (isset($this->questiondisplay->options->questions)) {
Expand Down Expand Up @@ -231,7 +241,7 @@ function validation($data, $files) {
$sub++;
}
} else {
$errors['questiontext']=get_string('questions missing', 'question');
$errors['questiontext']=get_string('questionsmissing', 'qtype_multianswer');
}
}

Expand Down
85 changes: 56 additions & 29 deletions question/type/multianswer/questiontype.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,21 @@ function get_question_options(&$question) {
// We want an array with question ids as index and the positions as values
$sequence = array_flip(explode(',', $sequence));
array_walk($sequence, create_function('&$val', '$val++;'));

foreach ($wrappedquestions as $wrapped) {
if (!$QTYPES[$wrapped->qtype]->get_question_options($wrapped)) {
notify("Unable to get options for questiontype {$wrapped->qtype} (id={$wrapped->id})");
//si une question est manquante l,indice est nul
foreach($sequence as $seq){
$question->options->questions[$seq]= '';
}
if (isset($wrappedquestions) && is_array($wrappedquestions)){
foreach ($wrappedquestions as $wrapped) {
if (!$QTYPES[$wrapped->qtype]->get_question_options($wrapped)) {
notify("Unable to get options for questiontype {$wrapped->qtype} (id={$wrapped->id})");
}
// for wrapped questions the maxgrade is always equal to the defaultgrade,
// there is no entry in the question_instances table for them
$wrapped->maxgrade = $wrapped->defaultgrade;

$question->options->questions[$sequence[$wrapped->id]] = clone($wrapped); // ??? Why do we need a clone here?
}
// for wrapped questions the maxgrade is always equal to the defaultgrade,
// there is no entry in the question_instances table for them
$wrapped->maxgrade = $wrapped->defaultgrade;

$question->options->questions[$sequence[$wrapped->id]] = clone($wrapped); // ??? Why do we need a clone here?
}

return true;
Expand All @@ -67,28 +72,38 @@ function save_question_options($question) {
if (!$oldwrappedids = get_field('question_multianswer', 'sequence', 'question', $question->id)) {
$oldwrappedids = array();
} else {
$oldwrappedids = explode(',', $oldwrappedids);
$oldwrappedids = get_records_list('question', 'id', $oldwrappedids, 'id ASC','id');
}
$sequence = array();
foreach($question->options->questions as $wrapped) {
// if we still have some old wrapped question ids, reuse the next of them
if ($oldwrappedid = array_shift($oldwrappedids)) {
$wrapped->id = $oldwrappedid;
$oldqtype = get_field('question', 'qtype', 'id',$oldwrappedid) ;
if($oldqtype != $wrapped->qtype ) {
switch ($oldqtype) {
case 'multichoice':
delete_records('question_multichoice', 'question', $oldwrappedid);
break;
case 'shortanswer':
delete_records('question_shortanswer', 'question', $oldwrappedid);
break;
case 'numerical':
delete_records('question_numerical', 'question', $oldwrappedid);
break;
default:
print_error("questiontype $wrapped->qtype not recognized");
if ($wrapped != ''){
// if we still have some old wrapped question ids, reuse the next of them
if (is_array($oldwrappedids) && $oldwrappedid = array_shift($oldwrappedids)) {

if( $oldqtype = get_field('question', 'qtype', 'id',$oldwrappedid->id)){
$wrapped->id = $oldwrappedid->id;
if($oldqtype != $wrapped->qtype ) {
switch ($oldqtype) {
case 'multichoice':
delete_records('question_multichoice', 'question', $oldwrappedid);
$wrapped->id = $oldwrappedid;
break;
case 'shortanswer':
delete_records('question_shortanswer', 'question', $oldwrappedid);
$wrapped->id = $oldwrappedid;
break;
case 'numerical':
delete_records('question_numerical', 'question', $oldwrappedid);
$wrapped->id = $oldwrappedid;
break;
default:
error("questiontype $wrapped->qtype not recognized");
$wrapped->id = 0 ;
}
}
}
}else {
$wrapped->id = 0 ;
}
}
$wrapped->name = $question->name;
Expand Down Expand Up @@ -197,6 +212,7 @@ function get_correct_responses(&$question, &$state) {
global $QTYPES;
$responses = array();
foreach($question->options->questions as $key => $wrapped) {
if ($wrapped != ''){
if ($correct = $QTYPES[$wrapped->qtype]->get_correct_responses($wrapped, $state)) {
$responses[$key] = $correct[''];
} else {
Expand All @@ -206,6 +222,7 @@ function get_correct_responses(&$question, &$state) {
return null;
}
}
}
return $responses;
}

Expand Down Expand Up @@ -247,6 +264,7 @@ function print_question_formulation_and_controls(&$question, &$state, $cmoptions
$qtextremaining = $qtextsplits[1];

$positionkey = $regs[1];
if (isset($question->options->questions[$positionkey]) && $question->options->questions[$positionkey] != ''){
$wrapped = &$question->options->questions[$positionkey];
$answers = &$wrapped->options->answers;
$correctanswers = $QTYPES[$wrapped->qtype]->get_correct_responses($wrapped, $state);
Expand Down Expand Up @@ -378,12 +396,19 @@ function print_question_formulation_and_controls(&$question, &$state, $cmoptions
echo $feedbackimg;
break;
default:
print_error("Unable to recognize questiontype ($wrapped->qtype) of
question part $positionkey.");
print_error("Unable to recognize questiontype of question part #$positionkey.");
break;
}
echo "</label>"; // MDL-7497
}
else {
if(! isset($question->options->questions[$positionkey])){
echo $regs[0];
}else {
echo '<div class="error" >'.get_string('questionnotfound','qtype_multianswer',$positionkey).'</div>';
}
}
}

// Print the final piece of question text:
echo $qtextremaining;
Expand All @@ -396,6 +421,7 @@ function grade_responses(&$question, &$state, $cmoptions) {
$teststate = clone($state);
$state->raw_grade = 0;
foreach($question->options->questions as $key => $wrapped) {
if ($wrapped != ''){
$state->responses[$key] = $state->responses[$key];
$teststate->responses = array('' => $state->responses[$key]);
$teststate->raw_grade = 0;
Expand All @@ -405,6 +431,7 @@ function grade_responses(&$question, &$state, $cmoptions) {
}
$state->raw_grade += $teststate->raw_grade;
}
}
$state->raw_grade /= $question->defaultgrade;
$state->raw_grade = min(max((float) $state->raw_grade, 0.0), 1.0)
* $question->maxgrade;
Expand Down

0 comments on commit df79079

Please sign in to comment.