function print_question_formulation_and_controls(&$question, &$state, $cmoptions, $options)
 {
     global $CFG;
     /// This implementation is also used by question type 'numerical'
     $readonly = empty($options->readonly) ? '' : 'readonly="readonly"';
     $formatoptions = new stdClass();
     $formatoptions->noclean = true;
     $formatoptions->para = false;
     $nameprefix = $question->name_prefix;
     /// Print question text and media
     $questiontext = format_text($question->questiontext, $question->questiontextformat, $formatoptions, $cmoptions->course);
     $image = get_question_image($question);
     $this->compute_feedbackperconditions($question, $state);
     /// Print input controls
     $values = array();
     $params = explode(",", $question->options->parameters);
     foreach ($params as &$param) {
         $param = trim($param);
         $paramparts = explode(" ", $param);
         $paramname = trim($paramparts[0]);
         $paramunity = trim($paramparts[1]);
         if (isset($state->responses[$paramname]) && $state->responses[$paramname] != '') {
             $value[$paramname] = ' value="' . s($state->responses[$paramname], true) . '" ';
         } else {
             $value[$paramname] = ' value="" ';
         }
         $inputname[$paramname] = ' name="' . $nameprefix . $paramname . '" ';
     }
     $feedback = '';
     $class = '';
     $feedbackimg = '';
     $feedbackperconditions = '';
     if ($options->feedback) {
         $class = question_get_feedback_class($state->raw_grade);
         $feedbackimg = question_get_feedback_image($state->raw_grade);
         $feedbackperconditions = $question->options->computedfeedbackperconditions;
     }
     include "{$CFG->dirroot}/question/type/multinumerical/display.html";
 }
Ejemplo n.º 2
0
 /**
  * Prints the score obtained and maximum score available plus any penalty
  * information
  *
  * This function prints a summary of the scoring in the most recently
  * graded state (the question may not have been submitted for marking at
  * the current state). The default implementation should be suitable for most
  * question types.
  * @param object $question The question for which the grading details are
  *                         to be rendered. Question type specific information
  *                         is included. The maximum possible grade is in
  *                         ->maxgrade.
  * @param object $state    The state. In particular the grading information
  *                          is in ->grade, ->raw_grade and ->penalty.
  * @param object $cmoptions
  * @param object $options  An object describing the rendering options.
  */
 function print_question_grading_details(&$question, &$state, $cmoptions, $options)
 {
     /* The default implementation prints the number of marks if no attempt
        has been made. Otherwise it displays the grade obtained out of the
        maximum grade available and a warning if a penalty was applied for the
        attempt and displays the overall grade obtained counting all previous
        responses (and penalties) */
     global $QTYPES;
     // MDL-7496 show correct answer after "Incorrect"
     $correctanswer = '';
     if ($correctanswers = $QTYPES[$question->qtype]->get_correct_responses($question, $state)) {
         if ($options->readonly && $options->correct_responses) {
             $delimiter = '';
             if ($correctanswers) {
                 foreach ($correctanswers as $ca) {
                     $correctanswer .= $delimiter . $ca;
                     $delimiter = ', ';
                 }
             }
         }
     }
     if (QUESTION_EVENTDUPLICATE == $state->event) {
         echo ' ';
         print_string('duplicateresponse', 'quiz');
     }
     if ($question->maxgrade > 0 && $options->scores) {
         if (question_state_is_graded($state->last_graded)) {
             // Display the grading details from the last graded state
             $grade = new stdClass();
             $grade->cur = question_format_grade($cmoptions, $state->last_graded->grade);
             $grade->max = question_format_grade($cmoptions, $question->maxgrade);
             $grade->raw = question_format_grade($cmoptions, $state->last_graded->raw_grade);
             // let student know wether the answer was correct
             $class = question_get_feedback_class($state->last_graded->raw_grade / $question->maxgrade);
             echo '<div class="correctness ' . $class . '">' . get_string($class, 'quiz');
             if ($correctanswer != '' && ($class == 'partiallycorrect' || $class == 'incorrect')) {
                 echo '<div class="correctness">';
                 print_string('correctansweris', 'quiz', s($correctanswer));
                 echo '</div>';
             }
             echo '</div>';
             echo '<div class="gradingdetails">';
             // print grade for this submission
             print_string('gradingdetails', 'quiz', $grade);
             // A unit penalty for numerical was applied so display it
             // a temporary solution for unit rendering in numerical
             // waiting for the new question engine code for a permanent one
             if (isset($state->options->raw_unitpenalty) && $state->options->raw_unitpenalty > 0.0) {
                 echo ' ';
                 print_string('unitappliedpenalty', 'qtype_numerical', question_format_grade($cmoptions, $state->options->raw_unitpenalty));
             }
             if ($cmoptions->penaltyscheme) {
                 // print details of grade adjustment due to penalties
                 if ($state->last_graded->raw_grade > $state->last_graded->grade) {
                     echo ' ';
                     print_string('gradingdetailsadjustment', 'quiz', $grade);
                 }
                 // print info about new penalty
                 // penalty is relevant only if the answer is not correct and further attempts are possible
                 if ($state->last_graded->raw_grade < $question->maxgrade and QUESTION_EVENTCLOSEANDGRADE != $state->event) {
                     if ('' !== $state->last_graded->penalty && (double) $state->last_graded->penalty > 0.0) {
                         echo ' ';
                         print_string('gradingdetailspenalty', 'quiz', question_format_grade($cmoptions, $state->last_graded->penalty));
                     } else {
                         /* No penalty was applied even though the answer was
                            not correct (eg. a syntax error) so tell the student
                            that they were not penalised for the attempt */
                         echo ' ';
                         print_string('gradingdetailszeropenalty', 'quiz');
                     }
                 }
             }
             echo '</div>';
         }
     }
 }
Ejemplo n.º 3
0
 function print_question_formulation_and_controls(&$question, &$state, $cmoptions, $options)
 {
     global $QTYPES, $CFG, $USER;
     $readonly = empty($options->readonly) ? '' : 'readonly="readonly"';
     $disabled = empty($options->readonly) ? '' : 'disabled="disabled"';
     $formatoptions = new stdClass();
     $formatoptions->noclean = true;
     $formatoptions->para = false;
     $nameprefix = $question->name_prefix;
     // adding an icon with alt to warn user this is a fill in the gap question
     // MDL-7497
     if (!empty($USER->screenreader)) {
         echo "<img src=\"{$CFG->wwwroot}/question/type/{$question->qtype}/icon.gif\" " . "class=\"icon\" alt=\"" . get_string('clozeaid', 'qtype_multichoice') . "\" />  ";
     }
     echo '<div class="ablock clearfix">';
     // For this question type, we better print the image on top:
     if ($image = get_question_image($question)) {
         echo '<img class="qimage" src="' . $image . '" alt="" /><br />';
     }
     $qtextremaining = format_text($question->questiontext, $question->questiontextformat, $formatoptions, $cmoptions->course);
     $strfeedback = get_string('feedback', 'quiz');
     // The regex will recognize text snippets of type {#X}
     // where the X can be any text not containg } or white-space characters.
     while (ereg('\\{#([^[:space:]}]*)}', $qtextremaining, $regs)) {
         $qtextsplits = explode($regs[0], $qtextremaining, 2);
         echo "<label>";
         // MDL-7497
         echo $qtextsplits[0];
         $qtextremaining = $qtextsplits[1];
         $positionkey = $regs[1];
         $wrapped =& $question->options->questions[$positionkey];
         $answers =& $wrapped->options->answers;
         $correctanswers = $QTYPES[$wrapped->qtype]->get_correct_responses($wrapped, $state);
         $inputname = $nameprefix . $positionkey;
         if (isset($state->responses[$positionkey])) {
             $response = $state->responses[$positionkey];
         } else {
             $response = null;
         }
         // Determine feedback popup if any
         $popup = '';
         $style = '';
         $feedbackimg = '';
         if ($options->feedback) {
             $chosenanswer = null;
             switch ($wrapped->qtype) {
                 case 'numerical':
                 case 'shortanswer':
                     $testedstate = clone $state;
                     $testedstate->responses[''] = $response;
                     foreach ($answers as $answer) {
                         if ($QTYPES[$wrapped->qtype]->test_response($wrapped, $testedstate, $answer)) {
                             $chosenanswer = clone $answer;
                             break;
                         }
                     }
                     break;
                 case 'multichoice':
                     if (isset($answers[$response])) {
                         $chosenanswer = clone $answers[$response];
                     }
                     break;
                 default:
                     break;
             }
             // Set up a default chosenanswer so that all non-empty wrong
             // answers are highlighted red
             if (empty($chosenanswer) && !empty($response)) {
                 $chosenanswer = new stdClass();
                 $chosenanswer->fraction = 0.0;
             }
             if (!empty($chosenanswer->feedback)) {
                 $feedback = s(str_replace(array("\\", "'"), array("\\\\", "\\'"), $chosenanswer->feedback));
                 $popup = " onmouseover=\"return overlib('{$feedback}', STICKY, MOUSEOFF, CAPTION, '{$strfeedback}', FGCOLOR, '#FFFFFF');\" " . " onmouseout=\"return nd();\" ";
             }
             /// Determine style
             if ($options->feedback && $response != '') {
                 $style = 'class = "' . question_get_feedback_class($chosenanswer->fraction) . '"';
                 $feedbackimg = question_get_feedback_image($chosenanswer->fraction);
             } else {
                 $style = '';
                 $feedbackimg = '';
             }
         }
         // Print the input control
         switch ($wrapped->qtype) {
             case 'shortanswer':
             case 'numerical':
                 echo " <input {$style} {$readonly} {$popup} name=\"{$inputname}\"\n                            type=\"text\" value=\"" . s($response, true) . "\" size=\"12\" /> ";
                 if (!empty($feedback) && !empty($USER->screenreader)) {
                     echo "<img src=\"{$CFG->pixpath}/i/feedback.gif\" alt=\"{$feedback}\" />";
                 }
                 echo $feedbackimg;
                 break;
             case 'multichoice':
                 $outputoptions = '<option></option>';
                 // Default empty option
                 foreach ($answers as $mcanswer) {
                     $selected = '';
                     if ($response == $mcanswer->id) {
                         $selected = ' selected="selected"';
                     }
                     $outputoptions .= "<option value=\"{$mcanswer->id}\"{$selected}>" . s($mcanswer->answer, true) . '</option>';
                 }
                 // In the next line, $readonly is invalid HTML, but it works in
                 // all browsers. $disabled would be valid, but then the JS for
                 // displaying the feedback does not work. Of course, we should
                 // not be relying on JS (for accessibility reasons), but that is
                 // a bigger problem.
                 //
                 // The span is used for safari, which does not allow styling of
                 // selects.
                 echo "<span {$style}><select {$popup} {$readonly} {$style} name=\"{$inputname}\">";
                 echo $outputoptions;
                 echo '</select></span>';
                 if (!empty($feedback) && !empty($USER->screenreader)) {
                     echo "<img src=\"{$CFG->pixpath}/i/feedback.gif\" alt=\"{$feedback}\" />";
                 }
                 echo $feedbackimg;
                 break;
             default:
                 error("Unable to recognize questiontype ({$wrapped->qtype}) of\n                           question part {$positionkey}.");
                 break;
         }
         echo "</label>";
         // MDL-7497
     }
     // Print the final piece of question text:
     echo $qtextremaining;
     $this->print_question_submit_buttons($question, $state, $cmoptions, $options);
     echo '</div>';
 }
Ejemplo n.º 4
0
 /**
  * @desc Prints the question. Calls question_webwork_derived, and prints out the html associated with derivedid.
  * @param $question object The question object to print.
  * @param $state object The state of the responses for the question.
  * @param $cmoptions object Options containing course ID.
  * @param $options object
  */
 function print_question_formulation_and_controls(&$question, &$state, $cmoptions, $options)
 {
     global $CFG, $USER;
     $readonly = empty($options->readonly) ? '' : 'disabled="disabled"';
     //Formulate question image and text
     $questiontext = $this->format_text($question->questiontext, $question->questiontextformat, $cmoptions);
     $image = get_question_image($question, $cmoptions->course);
     $derivationid = $state->responses['derivationid'];
     $derivation = get_record('question_webwork_derived', 'id', $derivationid);
     $unparsedhtml = base64_decode($derivation->html);
     //partial answers
     $showPartiallyCorrectAnswers = $question->grading;
     //new array keyed by field
     $fieldhash = $state->responses['answers'];
     $answerfields = array();
     $parser = new HtmlParser($unparsedhtml);
     $currentselect = "";
     while ($parser->parse()) {
         //change some attributes of html tags for moodle compliance
         if ($parser->iNodeType == NODE_TYPE_ELEMENT) {
             $nodename = $parser->iNodeName;
             $name = $parser->iNodeAttributes['name'];
             //handle generic change of node's attribute name
             if ($nodename == "INPUT" || $nodename == "SELECT" || $nodename == "TEXTAREA") {
                 $parser->iNodeAttributes['name'] = 'resp' . $question->id . '_' . $name;
                 if ($state->event == QUESTION_EVENTGRADE && isset($fieldhash[$name])) {
                     if ($showPartiallyCorrectAnswers) {
                         $parser->iNodeAttributes['class'] = $parser->iNodeAttributes['class'] . ' ' . question_get_feedback_class($fieldhash[$name]['score']);
                     }
                 }
                 if (!strstr($name, 'previous')) {
                     $answerfields[$name] = $fieldhash[$name];
                 }
             }
             //handle specific change
             if ($nodename == "INPUT") {
                 //put submitted value into field
                 if (isset($fieldhash[$name])) {
                     $parser->iNodeAttributes['value'] = $fieldhash[$name]['answer'];
                 }
             } else {
                 if ($nodename == "SELECT") {
                     $currentselect = $name;
                 } else {
                     if ($nodename == "OPTION") {
                         if ($parser->iNodeAttributes['value'] == $fieldhash[$currentselect]['answer']) {
                             $parser->iNodeAttributes['selected'] = '1';
                         }
                     } else {
                         if ($nodename == "TEXTAREA") {
                         }
                     }
                 }
             }
         }
         $problemhtml .= $parser->printTag();
     }
     //for the seed form field
     $qid = $question->id;
     $seed = $state->responses['seed'];
     //if the student has answered
     include "{$CFG->dirroot}/question/type/webwork/display.html";
 }
Ejemplo n.º 5
0
    function print_question_formulation_and_controls(&$question, &$state, $cmoptions, $options)
    {
        global $QTYPES, $CFG, $USER;
        $readonly = empty($options->readonly) ? '' : 'readonly="readonly"';
        $disabled = empty($options->readonly) ? '' : 'disabled="disabled"';
        $formatoptions = new stdClass();
        $formatoptions->noclean = true;
        $formatoptions->para = false;
        $nameprefix = $question->name_prefix;
        // adding an icon with alt to warn user this is a fill in the gap question
        // MDL-7497
        if (!empty($USER->screenreader)) {
            echo "<img src=\"{$CFG->wwwroot}/question/type/{$question->qtype}/icon.gif\" " . "class=\"icon\" alt=\"" . get_string('clozeaid', 'qtype_multichoice') . "\" />  ";
        }
        echo '<div class="ablock clearfix">';
        // For this question type, we better print the image on top:
        if ($image = get_question_image($question)) {
            echo '<img class="qimage" src="' . $image . '" alt="" /><br />';
        }
        $qtextremaining = format_text($question->questiontext, $question->questiontextformat, $formatoptions, $cmoptions->course);
        $strfeedback = get_string('feedback', 'quiz');
        // The regex will recognize text snippets of type {#X}
        // where the X can be any text not containg } or white-space characters.
        while (ereg('\\{#([^[:space:]}]*)}', $qtextremaining, $regs)) {
            $qtextsplits = explode($regs[0], $qtextremaining, 2);
            echo $qtextsplits[0];
            echo "<label>";
            // MDL-7497
            $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);
                $inputname = $nameprefix . $positionkey;
                if (isset($state->responses[$positionkey])) {
                    $response = $state->responses[$positionkey];
                } else {
                    $response = null;
                }
                // Determine feedback popup if any
                $popup = '';
                $style = '';
                $feedbackimg = '';
                $feedback = '';
                $correctanswer = '';
                $strfeedbackwrapped = $strfeedback;
                $testedstate = clone $state;
                if ($correctanswers = $QTYPES[$wrapped->qtype]->get_correct_responses($wrapped, $testedstate)) {
                    if ($options->readonly && $options->correct_responses) {
                        $delimiter = '';
                        if ($correctanswers) {
                            foreach ($correctanswers as $ca) {
                                switch ($wrapped->qtype) {
                                    case 'numerical':
                                    case 'shortanswer':
                                        $correctanswer .= $delimiter . $ca;
                                        break;
                                    case 'multichoice':
                                        if (isset($answers[$ca])) {
                                            $correctanswer .= $delimiter . $answers[$ca]->answer;
                                        }
                                        break;
                                }
                                $delimiter = ', ';
                            }
                        }
                    }
                    if ($correctanswer != '') {
                        $feedback = '<div class="correctness">';
                        $feedback .= get_string('correctansweris', 'quiz', s($correctanswer, true));
                        $feedback .= '</div>';
                    }
                }
                if ($options->feedback) {
                    $chosenanswer = null;
                    switch ($wrapped->qtype) {
                        case 'numerical':
                        case 'shortanswer':
                            $testedstate = clone $state;
                            $testedstate->responses[''] = $response;
                            foreach ($answers as $answer) {
                                if ($QTYPES[$wrapped->qtype]->test_response($wrapped, $testedstate, $answer)) {
                                    $chosenanswer = clone $answer;
                                    break;
                                }
                            }
                            break;
                        case 'multichoice':
                            if (isset($answers[$response])) {
                                $chosenanswer = clone $answers[$response];
                            }
                            break;
                        default:
                            break;
                    }
                    // Set up a default chosenanswer so that all non-empty wrong
                    // answers are highlighted red
                    if (empty($chosenanswer) && $response != '') {
                        $chosenanswer = new stdClass();
                        $chosenanswer->fraction = 0.0;
                    }
                    if (!empty($chosenanswer->feedback)) {
                        $feedback = s(str_replace(array("\\", "'"), array("\\\\", "\\'"), $feedback . $chosenanswer->feedback));
                        if ($options->readonly && $options->correct_responses) {
                            $strfeedbackwrapped = get_string('correctanswerandfeedback', 'qtype_multianswer');
                        } else {
                            $strfeedbackwrapped = get_string('feedback', 'quiz');
                        }
                        $popup = " onmouseover=\"return overlib('{$feedback}', STICKY, MOUSEOFF, CAPTION, '{$strfeedbackwrapped}', FGCOLOR, '#FFFFFF');\" " . " onmouseout=\"return nd();\" ";
                    }
                    /// Determine style
                    if ($options->feedback && $response != '') {
                        $style = 'class = "' . question_get_feedback_class($chosenanswer->fraction) . '"';
                        $feedbackimg = question_get_feedback_image($chosenanswer->fraction);
                    } else {
                        $style = '';
                        $feedbackimg = '';
                    }
                }
                if ($feedback != '' && $popup == '') {
                    $strfeedbackwrapped = get_string('correctanswer', 'qtype_multianswer');
                    $feedback = s(str_replace(array("\\", "'"), array("\\\\", "\\'"), $feedback));
                    $popup = " onmouseover=\"return overlib('{$feedback}', STICKY, MOUSEOFF, CAPTION, '{$strfeedbackwrapped}', FGCOLOR, '#FFFFFF');\" " . " onmouseout=\"return nd();\" ";
                }
                // Print the input control
                switch ($wrapped->qtype) {
                    case 'shortanswer':
                    case 'numerical':
                        $size = 1;
                        foreach ($answers as $answer) {
                            if (strlen(trim($answer->answer)) > $size) {
                                $size = strlen(trim($answer->answer));
                            }
                        }
                        if (strlen(trim($response)) > $size) {
                            $size = strlen(trim($response)) + 1;
                        }
                        $size = $size + rand(0, $size * 0.15);
                        $size > 60 ? $size = 60 : ($size = $size);
                        $styleinfo = "size=\"{$size}\"";
                        /**
                         * Uncomment the following lines if you want to limit for small sizes.
                         * Results may vary with browsers see MDL-3274
                         */
                        /*
                        if ($size < 2) {
                            $styleinfo = 'style="width: 1.1em;"';
                        }
                        if ($size == 2) {
                            $styleinfo = 'style="width: 1.9em;"';
                        }
                        if ($size == 3) {
                            $styleinfo = 'style="width: 2.3em;"';
                        }
                        if ($size == 4) {
                            $styleinfo = 'style="width: 2.8em;"';
                        }
                        */
                        echo "<input {$style} {$readonly} {$popup} name=\"{$inputname}\"";
                        echo "  type=\"text\" value=\"" . s($response, true) . "\" " . $styleinfo . " /> ";
                        if (!empty($feedback) && !empty($USER->screenreader)) {
                            echo "<img src=\"{$CFG->pixpath}/i/feedback.gif\" alt=\"{$feedback}\" />";
                        }
                        echo $feedbackimg;
                        break;
                    case 'multichoice':
                        if ($wrapped->options->layout == 0) {
                            $outputoptions = '<option></option>';
                            // Default empty option
                            foreach ($answers as $mcanswer) {
                                $selected = '';
                                if ($response == $mcanswer->id) {
                                    $selected = ' selected="selected"';
                                }
                                $outputoptions .= "<option value=\"{$mcanswer->id}\"{$selected}>" . s($mcanswer->answer, true) . '</option>';
                            }
                            // In the next line, $readonly is invalid HTML, but it works in
                            // all browsers. $disabled would be valid, but then the JS for
                            // displaying the feedback does not work. Of course, we should
                            // not be relying on JS (for accessibility reasons), but that is
                            // a bigger problem.
                            //
                            // The span is used for safari, which does not allow styling of
                            // selects.
                            echo "<span {$style}><select {$popup} {$readonly} {$style} name=\"{$inputname}\">";
                            echo $outputoptions;
                            echo '</select></span>';
                            if (!empty($feedback) && !empty($USER->screenreader)) {
                                echo "<img src=\"{$CFG->pixpath}/i/feedback.gif\" alt=\"{$feedback}\" />";
                            }
                            echo $feedbackimg;
                        } else {
                            if ($wrapped->options->layout == 1 || $wrapped->options->layout == 2) {
                                $ordernumber = 0;
                                $anss = array();
                                foreach ($answers as $mcanswer) {
                                    $ordernumber++;
                                    $checked = '';
                                    $chosen = false;
                                    $type = 'type="radio"';
                                    $name = "name=\"{$inputname}\"";
                                    if ($response == $mcanswer->id) {
                                        $checked = 'checked="checked"';
                                        $chosen = true;
                                    }
                                    $a = new stdClass();
                                    $a->id = $question->name_prefix . $mcanswer->id;
                                    $a->class = '';
                                    $a->feedbackimg = '';
                                    // Print the control
                                    $a->control = "<input {$readonly} id=\"{$a->id}\" {$name} {$checked} {$type} value=\"{$mcanswer->id}\" />";
                                    if ($options->correct_responses && $mcanswer->fraction > 0) {
                                        $a->class = question_get_feedback_class(1);
                                    }
                                    if ($options->feedback && $chosen || $options->correct_responses) {
                                        if ($type == ' type="checkbox" ') {
                                            $a->feedbackimg = question_get_feedback_image($mcanswer->fraction > 0 ? 1 : 0, $chosen && $options->feedback);
                                        } else {
                                            $a->feedbackimg = question_get_feedback_image($mcanswer->fraction, $chosen && $options->feedback);
                                        }
                                    }
                                    // Print the answer text: no automatic numbering
                                    $a->text = format_text($mcanswer->answer, FORMAT_MOODLE, $formatoptions, $cmoptions->course);
                                    // Print feedback if feedback is on
                                    if (($options->feedback || $options->correct_responses) && $checked) {
                                        //|| $options->readonly
                                        $a->feedback = format_text($mcanswer->feedback, true, $formatoptions, $cmoptions->course);
                                    } else {
                                        $a->feedback = '';
                                    }
                                    $anss[] = clone $a;
                                }
                                ?>
            <?php 
                                if ($wrapped->options->layout == 1) {
                                    ?>
                  <table class="answer">
                    <?php 
                                    $row = 1;
                                    foreach ($anss as $answer) {
                                        ?>
                      <tr class="<?php 
                                        echo 'r' . ($row = $row ? 0 : 1);
                                        ?>
">
                        <td class="c0 control">
                          <?php 
                                        echo $answer->control;
                                        ?>
                        </td>
                        <td class="c1 text <?php 
                                        echo $answer->class;
                                        ?>
">
                          <label for="<?php 
                                        echo $answer->id;
                                        ?>
">
                            <?php 
                                        echo $answer->text;
                                        ?>
                            <?php 
                                        echo $answer->feedbackimg;
                                        ?>
                          </label>
                        </td>
                        <td class="c0 feedback">
                          <?php 
                                        echo $answer->feedback;
                                        ?>
                        </td>
                      </tr>
                    <?php 
                                    }
                                    ?>
                  </table>
                  <?php 
                                } else {
                                    if ($wrapped->options->layout == 2) {
                                        ?>
           
                  <table class="answer">
                      <tr class="<?php 
                                        echo 'r' . ($row = $row ? 0 : 1);
                                        ?>
">
                    <?php 
                                        $row = 1;
                                        foreach ($anss as $answer) {
                                            ?>
                        <td class="c0 control">
                          <?php 
                                            echo $answer->control;
                                            ?>
                        </td>
                        <td class="c1 text <?php 
                                            echo $answer->class;
                                            ?>
">
                          <label for="<?php 
                                            echo $answer->id;
                                            ?>
">
                            <?php 
                                            echo $answer->text;
                                            ?>
                            <?php 
                                            echo $answer->feedbackimg;
                                            ?>
                          </label>
                        </td>
                        <td class="c0 feedback">
                          <?php 
                                            echo $answer->feedback;
                                            ?>
                        </td>
                    <?php 
                                        }
                                        ?>
                      </tr>
                  </table>
                  <?php 
                                    }
                                }
                            } else {
                                echo "no valid layout";
                            }
                        }
                        break;
                    default:
                        $a = new stdClass();
                        $a->type = $wrapped->qtype;
                        $a->sub = $positionkey;
                        print_error('unknownquestiontypeofsubquestion', 'qtype_multianswer', '', $a);
                        break;
                }
                echo "</label>";
                // MDL-7497
            } else {
                if (!isset($question->options->questions[$positionkey])) {
                    echo $regs[0] . "</label>";
                } else {
                    echo '</label><div class="error" >' . get_string('questionnotfound', 'qtype_multianswer', $positionkey) . '</div>';
                }
            }
        }
        // Print the final piece of question text:
        echo $qtextremaining;
        $this->print_question_submit_buttons($question, $state, $cmoptions, $options);
        echo '</div>';
    }
Ejemplo n.º 6
0
 function print_question_formulation_and_controls(&$question, &$state, $cmoptions, $options)
 {
     global $CFG, $OUTPUT;
     $context = $this->get_context_by_category_id($question->category);
     $subquestions = $state->options->subquestions;
     $correctanswers = $this->get_correct_responses($question, $state);
     $nameprefix = $question->name_prefix;
     $answers = array();
     // Answer choices formatted ready for output.
     $allanswers = array();
     // This and the next used to detect identical answers
     $answerids = array();
     // and adjust ids.
     $responses =& $state->responses;
     // Prepare a list of answers, removing duplicates.
     foreach ($subquestions as $subquestion) {
         foreach ($subquestion->options->answers as $ans) {
             $allanswers[$ans->id] = $ans->answer;
             if (!in_array($ans->answer, $answers)) {
                 $answers[$ans->id] = strip_tags(format_string($ans->answer, false));
                 $answerids[$ans->answer] = $ans->id;
             }
         }
     }
     // Fix up the ids of any responses that point the the eliminated duplicates.
     foreach ($responses as $subquestionid => $ignored) {
         if ($responses[$subquestionid]) {
             $responses[$subquestionid] = $answerids[$allanswers[$responses[$subquestionid]]];
         }
     }
     foreach ($correctanswers as $subquestionid => $ignored) {
         $correctanswers[$subquestionid] = $answerids[$allanswers[$correctanswers[$subquestionid]]];
     }
     // Shuffle the answers
     $answers = draw_rand_array($answers, count($answers));
     // Print formulation
     $questiontext = $this->format_text($question->questiontext, $question->questiontextformat, $cmoptions);
     // Print the input controls
     foreach ($subquestions as $key => $subquestion) {
         if ($subquestion->questiontext !== '' && !is_null($subquestion->questiontext)) {
             // Subquestion text:
             $a = new stdClass();
             $text = $this->format_subquestion_text($subquestion, $state, $context);
             $a->text = $this->format_text($text, $subquestion->questiontextformat, $cmoptions);
             // Drop-down list:
             $menuname = $nameprefix . $subquestion->id;
             $response = isset($state->responses[$subquestion->id]) ? $state->responses[$subquestion->id] : '0';
             $a->class = ' ';
             $a->feedbackimg = ' ';
             if ($options->readonly and $options->correct_responses) {
                 if (isset($correctanswers[$subquestion->id]) and $correctanswers[$subquestion->id] == $response) {
                     $correctresponse = 1;
                 } else {
                     $correctresponse = 0;
                 }
                 if ($options->feedback && $response) {
                     $a->class = question_get_feedback_class($correctresponse);
                     $a->feedbackimg = question_get_feedback_image($correctresponse);
                 }
             }
             $attributes = array();
             $attributes['disabled'] = $options->readonly ? 'disabled' : null;
             $a->control = html_writer::select($answers, $menuname, $response, array('' => 'choosedots'), $attributes);
             // Neither the editing interface or the database allow to provide
             // fedback for this question type.
             // However (as was pointed out in bug bug 3294) the randomsamatch
             // type which reuses this method can have feedback defined for
             // the wrapped shortanswer questions.
             //if ($options->feedback
             // && !empty($subquestion->options->answers[$responses[$key]]->feedback)) {
             //    print_comment($subquestion->options->answers[$responses[$key]]->feedback);
             //}
             $anss[] = $a;
         }
     }
     include "{$CFG->dirroot}/question/type/match/display.html";
 }
Ejemplo n.º 7
0
 /**
  * Prints the score obtained and maximum score available plus any penalty
  * information
  *
  * This function prints a summary of the scoring in the most recently
  * graded state (the question may not have been submitted for marking at
  * the current state). The default implementation should be suitable for most
  * question types.
  * @param object $question The question for which the grading details are
  *                         to be rendered. Question type specific information
  *                         is included. The maximum possible grade is in
  *                         ->maxgrade.
  * @param object $state    The state. In particular the grading information
  *                          is in ->grade, ->raw_grade and ->penalty.
  * @param object $cmoptions
  * @param object $options  An object describing the rendering options.
  */
 function print_question_grading_details(&$question, &$state, $cmoptions, $options)
 {
     /* The default implementation prints the number of marks if no attempt
        has been made. Otherwise it displays the grade obtained out of the
        maximum grade available and a warning if a penalty was applied for the
        attempt and displays the overall grade obtained counting all previous
        responses (and penalties) */
     if (QUESTION_EVENTDUPLICATE == $state->event) {
         echo ' ';
         print_string('duplicateresponse', 'quiz');
     }
     if ($question->maxgrade > 0 && $options->scores) {
         if (question_state_is_graded($state->last_graded)) {
             // Display the grading details from the last graded state
             $grade = new stdClass();
             $grade->cur = question_format_grade($cmoptions, $state->last_graded->grade);
             $grade->max = question_format_grade($cmoptions, $question->maxgrade);
             $grade->raw = question_format_grade($cmoptions, $state->last_graded->raw_grade);
             // let student know wether the answer was correct
             $class = question_get_feedback_class($state->last_graded->raw_grade / $question->maxgrade);
             echo '<div class="correctness ' . $class . '">' . get_string($class, 'quiz') . '</div>';
             echo '<div class="gradingdetails">';
             // print grade for this submission
             print_string('gradingdetails', 'quiz', $grade);
             if ($cmoptions->penaltyscheme) {
                 // print details of grade adjustment due to penalties
                 if ($state->last_graded->raw_grade > $state->last_graded->grade) {
                     echo ' ';
                     print_string('gradingdetailsadjustment', 'quiz', $grade);
                 }
                 // print info about new penalty
                 // penalty is relevant only if the answer is not correct and further attempts are possible
                 if ($state->last_graded->raw_grade < $question->maxgrade / 1.01 and QUESTION_EVENTCLOSEANDGRADE != $state->event) {
                     if ('' !== $state->last_graded->penalty && (double) $state->last_graded->penalty > 0.0) {
                         // A penalty was applied so display it
                         echo ' ';
                         print_string('gradingdetailspenalty', 'quiz', question_format_grade($cmoptions, $state->last_graded->penalty));
                     } else {
                         /* No penalty was applied even though the answer was
                            not correct (eg. a syntax error) so tell the student
                            that they were not penalised for the attempt */
                         echo ' ';
                         print_string('gradingdetailszeropenalty', 'quiz');
                     }
                 }
             }
             echo '</div>';
         }
     }
 }
Ejemplo n.º 8
0
 /**
  * Prints the main content of the question including any interactions
  */
 function print_question_formulation_and_controls(&$question, &$state, $cmoptions, $options)
 {
     global $CFG;
     $readonly = $options->readonly ? ' disabled="disabled"' : '';
     $formatoptions = new stdClass();
     $formatoptions->noclean = true;
     $formatoptions->para = false;
     // Print question formulation
     $questiontext = format_text($question->questiontext, $question->questiontextformat, $formatoptions, $cmoptions->course);
     $image = get_question_image($question);
     $answers =& $question->options->answers;
     $trueanswer =& $answers[$question->options->trueanswer];
     $falseanswer =& $answers[$question->options->falseanswer];
     $correctanswer = $trueanswer->fraction == 1 ? $trueanswer : $falseanswer;
     $trueclass = '';
     $falseclass = '';
     $truefeedbackimg = '';
     $falsefeedbackimg = '';
     // Work out which radio button to select (if any)
     if (isset($state->responses[''])) {
         $response = $state->responses[''];
     } else {
         $response = '';
     }
     $truechecked = $response == $trueanswer->id ? ' checked="checked"' : '';
     $falsechecked = $response == $falseanswer->id ? ' checked="checked"' : '';
     // Work out visual feedback for answer correctness.
     if ($options->feedback) {
         if ($truechecked) {
             $trueclass = question_get_feedback_class($trueanswer->fraction);
         } else {
             if ($falsechecked) {
                 $falseclass = question_get_feedback_class($falseanswer->fraction);
             }
         }
     }
     if ($options->feedback || $options->correct_responses) {
         if (isset($answers[$response])) {
             $truefeedbackimg = question_get_feedback_image($trueanswer->fraction, !empty($truechecked) && $options->feedback);
             $falsefeedbackimg = question_get_feedback_image($falseanswer->fraction, !empty($falsechecked) && $options->feedback);
         }
     }
     $inputname = ' name="' . $question->name_prefix . '" ';
     $trueid = $question->name_prefix . 'true';
     $falseid = $question->name_prefix . 'false';
     $radiotrue = '<input type="radio"' . $truechecked . $readonly . $inputname . 'id="' . $trueid . '" value="' . $trueanswer->id . '" /><label for="' . $trueid . '">' . s($trueanswer->answer) . '</label>';
     $radiofalse = '<input type="radio"' . $falsechecked . $readonly . $inputname . 'id="' . $falseid . '" value="' . $falseanswer->id . '" /><label for="' . $falseid . '">' . s($falseanswer->answer) . '</label>';
     $feedback = '';
     if ($options->feedback and isset($answers[$response])) {
         $chosenanswer = $answers[$response];
         $feedback = format_text($chosenanswer->feedback, true, $formatoptions, $cmoptions->course);
     }
     include "{$CFG->dirroot}/question/type/truefalse/display.html";
 }
 public function render_cell($x, $y, $readonly = false, $showcorrect = false)
 {
     $base = $this->render_cell_base($x, $y, $readonly);
     if (empty($showcorrect)) {
         return $base;
     }
     $class = '';
     $hasanswer = $this->has_answer($this->responses, $x, $y);
     $weight = array_key_exists($x, $this->weights) && array_key_exists($y, $this->weights[$x]) ? $this->weights[$x][$y] : 0;
     if ($hasanswer && $weight > 0) {
         $class = question_get_feedback_class(1);
     } else {
         if ($hasanswer && $weight < 0) {
             $class = question_get_feedback_class(0);
         } else {
             if (!$hasanswer && $weight > 0) {
                 $class = question_get_feedback_class(0);
             }
         }
     }
     $weighttext = $weight ? '<span class="smalltext ' . $class . '">(' . $weight * 100 . '%)</span>' : '';
     return $base . $weighttext;
 }
Ejemplo n.º 10
0
 /**
  * @param string $colname the name of the column.
  * @param object $attempt the row of data - see the SQL in display() in
  * mod/quiz/report/overview/report.php to see what fields are present,
  * and what they are called.
  * @return string the contents of the cell.
  */
 function other_cols($colname, $attempt)
 {
     global $OUTPUT;
     if (preg_match('/^qsgrade([0-9]+)$/', $colname, $matches)) {
         $questionid = $matches[1];
         $question = $this->questions[$questionid];
         if (isset($this->gradedstatesbyattempt[$attempt->attemptuniqueid][$questionid])) {
             $stateforqinattempt = $this->gradedstatesbyattempt[$attempt->attemptuniqueid][$questionid];
         } else {
             $stateforqinattempt = false;
         }
         if ($stateforqinattempt && question_state_is_graded($stateforqinattempt)) {
             $grade = quiz_rescale_grade($stateforqinattempt->grade, $this->quiz, 'question');
             if (!$this->is_downloading()) {
                 if (isset($this->regradedqs[$attempt->attemptuniqueid][$questionid])) {
                     $gradefromdb = $grade;
                     $newgrade = quiz_rescale_grade($this->regradedqs[$attempt->attemptuniqueid][$questionid]->newgrade, $this->quiz, 'question');
                     $oldgrade = quiz_rescale_grade($this->regradedqs[$attempt->attemptuniqueid][$questionid]->oldgrade, $this->quiz, 'question');
                     $grade = '<del>' . $oldgrade . '</del><br />' . $newgrade;
                 }
                 $link = new moodle_url("/mod/quiz/reviewquestion.php?attempt={$attempt->attempt}&question={$question->id}");
                 $action = new popup_action('click', $link, 'reviewquestion', array('height' => 450, 'width' => 650));
                 $linktopopup = $OUTPUT->action_link($link, $grade, $action, array('title' => get_string('reviewresponsetoq', 'quiz', $question->formattedname)));
                 if ($this->questions[$questionid]->maxgrade != 0) {
                     $fractionofgrade = $stateforqinattempt->grade / $this->questions[$questionid]->maxgrade;
                     $qclass = question_get_feedback_class($fractionofgrade);
                     $feedbackimg = question_get_feedback_image($fractionofgrade);
                     $questionclass = "que";
                     return "<span class=\"{$questionclass}\"><span class=\"{$qclass}\">" . $linktopopup . "</span></span>{$feedbackimg}";
                 } else {
                     return $linktopopup;
                 }
             } else {
                 return $grade;
             }
         } else {
             if ($stateforqinattempt && question_state_is_closed($stateforqinattempt)) {
                 $text = get_string('requiresgrading', 'quiz_overview');
                 if (!$this->is_downloading()) {
                     $link = new moodle_url("/mod/quiz/reviewquestion.php?attempt={$attempt->attempt}&question={$question->id}");
                     $action = new popup_action('click', $link, 'reviewquestion', array('height' => 450, 'width' => 650));
                     return $OUTPUT->action_link($link, $text, $action, array('title' => get_string('reviewresponsetoq', 'quiz', $question->formattedname)));
                 } else {
                     return $text;
                 }
             } else {
                 return '--';
             }
         }
     } else {
         return NULL;
     }
 }
 function print_question_formulation_and_controls(&$question, &$state, $cmoptions, $options)
 {
     global $CFG;
     $subquestions = $state->options->subquestions;
     $nameprefix = $question->name_prefix;
     $answers = array();
     $responses =& $state->responses;
     // Check browser version to see if YUI is supported properly.
     // This is similar to ajaxenabled() from lib/ajax/ajaxlib.php,
     // except it doesn't check the site-wide AJAX settings.
     $fallbackonly = false;
     $ie = check_browser_version('MSIE', 6.0);
     $ff = check_browser_version('Gecko', 20051106);
     $op = check_browser_version('Opera', 9.0);
     $sa = check_browser_version('Safari', 412);
     if (!$ie && !$ff && !$op && !$sa or !empty($USER->screenreader)) {
         $fallbackonly = true;
     }
     // Check to see if the defaultresponse option has changed from the previous
     // submission
     /*if (isset($responses['defaultresponse'])) {
           $state->options->defaultresponse = $responses['defaultresponse'];
       }
       // If it's not set at all, default is no
       else if (!isset($state->options->defaultresponse)) {
           $state->options->defaultresponse = "no";
       }*/
     if (isset($responses['defaultresponse']) and $responses['defaultresponse'] == 'on') {
         $state->options->defaultresponse = 'yes';
     } else {
         if (isset($responses['defaultresponse']) and $responses['defaultresponse'] != 'on') {
             $state->options->defaultresponse = 'no';
         } else {
             $state->options->defaultresponse = 'no';
         }
     }
     // Determine which responses are correct.
     $evaluatedresponses = $this->get_evaluated_responses($question, $state);
     $correctresponses = array();
     foreach ($subquestions as $key => $subquestion) {
         if ($subquestion->questiontext) {
             if ($evaluatedresponses[$key]) {
                 $correctresponses[$key] = true;
             } else {
                 $correctresponses[$key] = false;
             }
         }
     }
     // Generate question intro for both versions
     $questiontext = $this->format_text($question->questiontext, $question->questiontextformat, $cmoptions);
     $image = get_question_image($question);
     ////////////////////////////////
     // Generate fallback version
     ////////////////////////////////
     // Prepare a list of answers and sort them
     foreach ($subquestions as $subquestion) {
         foreach ($subquestion->options->answers as $ans) {
             $answers[$ans->answer] = $ans->answer;
         }
     }
     asort($answers);
     // Add each subquestion to the output
     foreach ($subquestions as $key => $subquestion) {
         if ($subquestion->questiontext) {
             // Subquestion text:
             $a = new stdClass();
             $a->text = $this->format_text($subquestion->questiontext, $question->questiontextformat, $cmoptions);
             // Drop-down list:
             $menuname = $nameprefix . $subquestion->code;
             $response = isset($state->responses[$subquestion->code]) ? $state->responses[$subquestion->code] : '0';
             $a->class = ' ';
             $a->feedbackimg = ' ';
             if ($options->readonly) {
                 if ($correctresponses[$subquestion->code]) {
                     $correctresponse = 1;
                 } else {
                     $correctresponse = 0;
                 }
                 if ($options->feedback && $response) {
                     $a->class = question_get_feedback_class($correctresponse);
                     $a->feedbackimg = question_get_feedback_image($correctresponse);
                 }
             }
             $a->control = choose_from_menu($answers, $menuname, $response, 'choose', '', 0, true, $options->readonly);
             $anss[] = $a;
         }
     }
     //////////////////////////////////
     // Generate javascript version
     //////////////////////////////////
     // Initialize variables
     $ulname = 'ul' . $question->id;
     $liname = 'li' . $question->id;
     $defaultresponsename = $nameprefix . 'defaultresponse';
     if ($state->options->defaultresponse == 'yes') {
         $ulclass .= 'deactivateddraglist';
     } else {
         $ulclass = 'draglist';
     }
     // Javascript to initialize variables and event callbacks
     $jsinit = array();
     // HTML to write in javascript version
     $jswrite = array();
     // Javascript Array initialization of list ids
     $lielems = array();
     foreach ($subquestions as $subquestion) {
         $lielems[] = '"' . $liname . '_' . $subquestion->code . '"';
     }
     $liarraystring = 'Array(' . implode(',', $lielems) . ')';
     // Set up event callbacks for interactive version
     if (!$options->readonly) {
         $jsinit[] = 'var hiddennames = new Object();';
         $jsinit[] = 'hiddennames.ulname = "' . $ulname . '";';
         $jsinit[] = 'hiddennames.respname = "hidden' . $nameprefix . '";';
         $jsinit[] = 'var checkboxnames = new Object();';
         $jsinit[] = 'checkboxnames.defaultresponsename = "cb' . $defaultresponsename . '";';
         $jsinit[] = 'checkboxnames.ulname = "' . $ulname . '";';
         $jsinit[] = 'YAHOO.util.Event.addListener("responseform", "click", ddOrderingSetHiddens, hiddennames);';
         $jsinit[] = 'YAHOO.util.Event.addListener("cb' . $defaultresponsename . '", "click", processGradeCheckbox, checkboxnames);';
     } else {
         $ulclass .= ' readonly';
     }
     // List class options
     if ($question->options->horizontal) {
         $ulclass .= ' inline';
     }
     // HTML for javascript version
     // Generate the hidden variables that store the responses
     $inputs = array();
     $i = 1;
     foreach ($subquestions as $subquestion) {
         if (!empty($subquestion->questiontext)) {
             $inputs[$subquestion->code] = array();
             $inputs[$subquestion->code]['id'] = 'hidden' . $nameprefix . $subquestion->code;
             $inputs[$subquestion->code]['name'] = $nameprefix . $subquestion->code;
             // If the order is defined by a previous response, use that item order
             if (isset($responses[$subquestion->code]) && $responses[$subquestion->code] > 0) {
                 $inputs[$subquestion->code]['value'] = $responses[$subquestion->code];
             } else {
                 $inputs[$subquestion->code]['value'] = $i;
                 $responses[$subquestion->code] = $i;
             }
             $i += 1;
         }
     }
     // Sort the items by response position to display them in the same order as they
     // were submitted in (or in the default shuffled order for the initial version)
     $items = array();
     foreach ($subquestions as $key => $subquestion) {
         $items[$responses[$key]] = $subquestion;
     }
     ksort($items);
     $lis = array();
     foreach ($items as $subquestion) {
         $response = isset($responses[$subquestion->code]) ? $responses[$key] : '0';
         // If readonly, set up feedback for each item
         $liclass = '';
         if ($options->readonly) {
             $liclass .= ' readonly';
         }
         $feedbackimg = '';
         if ($options->readonly) {
             if ($correctresponses[$subquestion->code]) {
                 $correctresponse = 1;
             } else {
                 $correctresponse = 0;
             }
             if ($options->feedback && $response) {
                 if ($state->options->defaultresponse == 'no') {
                     $liclass .= ' ' . question_get_feedback_class($correctresponse);
                     $feedbackimg = ' ' . question_get_feedback_image($correctresponse);
                 }
             }
         }
         if ($subquestion->questiontext) {
             // Clean up text and replace " with \\" for use in javascript
             $subquestiontext = $this->format_text($subquestion->questiontext, $question->questiontextformat, $cmoptions);
             $subquestiontext = preg_replace('/\\r\\n/', ' ', $subquestiontext);
             $subquestiontext = preg_replace('/"/', '\\"', $subquestiontext);
             // Add the list element to the output
             $lis[$subquestion->code] = array();
             $lis[$subquestion->code]['class'] = $liclass;
             $lis[$subquestion->code]['id'] = $liname . '_' . $subquestion->code;
             $lis[$subquestion->code]['text'] = $subquestiontext;
             if (preg_match('/[<[a-z].*>/', $subquestiontext)) {
                 $lis[$subquestion->code]['ishtml'] = true;
             }
             if ($feedbackimg) {
                 preg_match('/src="([^"]*)"/', $feedbackimg, $matches);
                 $lis[$subquestion->code]['feedbackimgsrc'] = $matches[1];
                 preg_match('/alt="([^"]*)"/', $feedbackimg, $matches);
                 $lis[$subquestion->code]['feedbackimgalt'] = $matches[1];
                 preg_match('/class="([^"]*)"/', $feedbackimg, $matches);
                 $lis[$subquestion->code]['feedbackimgclass'] = $matches[1];
             }
         }
     }
     // Restore defaultresponse option from state
     $defaultresponsechecked = '';
     $defaultresponsevalue = 'no';
     if ($state->options->defaultresponse == 'yes') {
         $defaultresponsechecked = 'checked="checked"';
         $defaultresponsevalue = 'yes';
     }
     $defaultresponsestr = get_string('defaultresponse', 'qtype_order');
     include "{$CFG->dirroot}/question/type/order/display.html";
 }
Ejemplo n.º 12
0
 /**
  * @desc Generates the HTML for a particular question.
  * @param integer $seed The seed of the question.
  * @param array $answers An array of answers that needs to be rendered.
  * @param object $event The event object.
  * @return string The HTML question representation.
  */
 public function render($seed, &$answers, $event)
 {
     //JIT Derivation creation
     //Usually we have this from the check answers call
     if (!isset($this->_derivation)) {
         $client = WebworkClient::Get();
         $env = WebworkQuestion::DefaultEnvironment();
         $env->problemSeed = $seed;
         $result = $client->renderProblem($env, $this->_data->code);
         $derivation = new stdClass();
         $derivation->html = base64_decode($result->output);
         $derivation->seed = $result->seed;
         $this->_derivation = $derivation;
     }
     $orderedanswers = array();
     $tempanswers = array();
     foreach ($answers as $answer) {
         $tempanswers[$answer->field] = $answer;
     }
     $answers = $tempanswers;
     $showpartialanswers = $this->_data->grading;
     $questionhtml = "";
     $parser = new HtmlParser($this->_derivation->html);
     $currentselect = "";
     $textarea = false;
     $checkboxes = array();
     while ($parser->parse()) {
         //change some attributes of html tags for moodle compliance
         if ($parser->iNodeType == NODE_TYPE_ELEMENT) {
             $nodename = $parser->iNodeName;
             if (isset($parser->iNodeAttributes['name'])) {
                 $name = $parser->iNodeAttributes['name'];
             }
             //handle generic change of node's attribute name
             if ($nodename == "INPUT" || $nodename == "SELECT" || $nodename == "TEXTAREA") {
                 $parser->iNodeAttributes['name'] = 'resp' . $this->_data->question . '_' . $name;
                 if ($event == QUESTION_EVENTGRADE && isset($answers[$name])) {
                     if ($showpartialanswers) {
                         if (isset($parser->iNodeAttributes['class'])) {
                             $class = $parser->iNodeAttributes['class'];
                         } else {
                             $class = "";
                         }
                         $parser->iNodeAttributes['class'] = $class . ' ' . question_get_feedback_class($answers[$name]->score);
                     }
                 }
             }
             //handle specific change
             if ($nodename == "INPUT") {
                 $nodetype = strtoupper($parser->iNodeAttributes['type']);
                 if ($nodetype == "CHECKBOX") {
                     if (strstr($answers[$name]->answer, $parser->iNodeAttributes['value'])) {
                         //FILLING IN ANSWER (CHECKBOX)
                         array_push($orderedanswers, $answers[$name]);
                         $parser->iNodeAttributes['checked'] = '1';
                     }
                     $parser->iNodeAttributes['name'] = $parser->iNodeAttributes['name'] . '_' . $parser->iNodeAttributes['value'];
                 } else {
                     if ($nodetype == "TEXT") {
                         if (isset($answers[$name])) {
                             //FILLING IN ANSWER (FIELD)
                             array_push($orderedanswers, $answers[$name]);
                             $parser->iNodeAttributes['value'] = $answers[$name]->answer;
                         }
                     }
                 }
             } else {
                 if ($nodename == "SELECT") {
                     $currentselect = $name;
                 } else {
                     if ($nodename == "OPTION") {
                         if ($parser->iNodeAttributes['value'] == $answers[$currentselect]->answer) {
                             //FILLING IN ANSWER (DROPDOWN)
                             array_push($orderedanswers, $answers[$currentselect]);
                             $parser->iNodeAttributes['selected'] = '1';
                         }
                     } else {
                         if ($nodename == "TEXTAREA") {
                             if (isset($answers[$name])) {
                                 array_push($orderedanswers, $answers[$name]);
                                 $textarea = true;
                                 $questionhtml .= $parser->printTag();
                                 $questionhtml .= $answers[$name]->answer;
                             }
                         }
                     }
                 }
             }
         }
         if (!$textarea) {
             $questionhtml .= $parser->printTag();
         } else {
             $textarea = false;
         }
     }
     $answers = $orderedanswers;
     return $questionhtml;
 }
/**
 * Prints the question body. Since standard moodle question functions set up
 * variables and prints html in the same function, we cannot call these functions.
 * So, the most code of this function (specially the type-specific part) is copied
 * from the standard moodle question types.
 * **/
function wrsqz_print_question_formulation_and_controls($questionType, $dbType, &$question, &$state, &$cmoptions, &$options) {
	//COMMON VARIABLES:
  global $CFG, $QTYPES;
  //1. Question text
  $formatoptions = new stdClass;
  $formatoptions->noclean = true;
  $formatoptions->para = false;

  $questiontext = format_text($question->questiontext, $question->questiontextformat,
                              $formatoptions, $cmoptions->course);

  //2. Question image
  $image = get_question_image($question);

  //3. name & strings
  $inputname = $question->name_prefix;
  $stranswer = get_string("answer", "quiz").': ';

  //4. WIRIS CAS applet
  $wirisCASApplet = '';
  $wirisCASForComputationsEnabled = !empty($question->options->wiris->options['wirisCASForComputations']);
  if($wirisCASForComputationsEnabled){
    $wirisCASContent = '';
    if (!empty($state->responses['wirisCASHidden'])) {
      $wirisCASContent = htmlentities(stripslashes_safe($state->responses['wirisCASHidden']), ENT_QUOTES, 'UTF-8');
      unset($state->responses['wirisCASHidden']);
    }else if(!empty($question->options->wiris->options['hiddenInitialCASValue'])){
      $wirisCASContent = htmlentities(stripslashes_safe($question->options->wiris->options['hiddenInitialCASValue']), ENT_QUOTES, 'UTF-8');
    }
    $wirisCASApplet = wrsqz_wirisCASAppletHTML($inputname, $wirisCASContent, false, 630, 300);
    require_js(array('yui_yahoo', 'yui_dom-event'));
    require_js(array($CFG->wwwroot.'/wiris-quizzes/js/wiris-quizzes.js',$CFG->wwwroot.'/wiris-quizzes/js/constants.js.php'));
  }
  
  //ANSWER FIELDS & FEEDBACK: QUESTION-TYPE specific
  if($questionType == 'essay'){
    // Response
    if (isset($state->responses[''])) {
      $value = stripslashes_safe($state->responses['']);
    }else{
      $value = "";
    }
    //answer
    if($wirisCASForComputationsEnabled){
      $wirisCASForComputations = $question->options->wiris->options['wirisCASForComputations'];
    }else{
      $wirisCASForComputations = '0';
    }
    //replace answer by an applet
    if($wirisCASForComputations == '2'){
      $answer = $wirisCASApplet;
      $answer .= '<input type="hidden" name="'.$inputname.'" id="edit-'.$inputname.'"/>';
      $wirisCASApplet = '';
    }else{
      if (empty($options->readonly)) {
        static $htmleditorused = false;
        $usehtmleditor = can_use_html_editor() && !$htmleditorused;
        // the student needs to type in their answer so print out a text editor
        echo '<!-- yes we can: '.$usehtmleditor.'-->';
        $answer = print_textarea($usehtmleditor, 18, 80, 630, 400, $inputname, $value, $cmoptions->course, true);
      }else{
        //it is read only, so just format the students answer and output it
        $safeformatoptions = new stdClass;
        $safeformatoptions->para = false;
        $answer = format_text($value, FORMAT_MOODLE, $safeformatoptions, $cmoptions->course);
        $answer = '<div class="answerreview">' . $answer . '</div>';
      }
      if($wirisCASForComputationsEnabled){
        $wirisCASApplet = '<tr><td>'.$wirisCASApplet.'</td></tr>';
      }
    }
    
    // feedback handling
    $feedback = '';
    if ($options->feedback && !empty($answers)) {
      foreach ($answers as $answer) {
        $feedback = format_text($answer->feedback, '', $formatoptions, $cmoptions->course);
      }
    }
    
  }else if($questionType == 'match'){
    $subquestions   = $state->options->subquestions;
    $correctanswers = $QTYPES[$question->qtype]->get_correct_responses($question, $state);
    $answers        = array(); // Answer choices formatted ready for output.
    $allanswers     = array(); // This and the next used to detect identical answers
    $answerids      = array(); // and adjust ids.
    $responses      = &$state->responses;

    // Prepare a list of answers, removing duplicates.
    foreach ($subquestions as $subquestion) {
      foreach ($subquestion->options->answers as $ans) {
        $allanswers[$ans->id] = $ans->answer;
        if (!in_array($ans->answer, $answers)) {
          $answers[$ans->id] = strip_tags(format_string($ans->answer, false));
          $answerids[$ans->answer] = $ans->id;
        }
      }
    }
    // Fix up the ids of any responses that point the the eliminated duplicates.
    foreach ($responses as $subquestionid => $ignored) {
      if ($responses[$subquestionid]) {
        $responses[$subquestionid] = $answerids[$allanswers[$responses[$subquestionid]]];
      }
    }
    foreach ($correctanswers as $subquestionid => $ignored) {
      $correctanswers[$subquestionid] = $answerids[$allanswers[$correctanswers[$subquestionid]]];
    }
    // Shuffle the answers
    $answers = draw_rand_array($answers, count($answers));
    // Print the input controls
    foreach ($subquestions as $key => $subquestion) {
      if ($subquestion->questiontext !== '' && !is_null($subquestion->questiontext)) {
        // Subquestion text:
        $a = new stdClass;
        $a->text = format_text($subquestion->questiontext,
        $question->questiontextformat, $cmoptions);
        // Drop-down list:
        $menuname = $inputname.$subquestion->id;
        $response = isset($state->responses[$subquestion->id])
                    ? $state->responses[$subquestion->id] : '0';
        $a->class = ' ';
        $a->feedbackimg = ' ';

        if ($options->readonly and $options->correct_responses) {
          if (isset($correctanswers[$subquestion->id])
          and ($correctanswers[$subquestion->id] == $response)) {
            $correctresponse = 1;
          } else {
            $correctresponse = 0;
          }
          if ($options->feedback && $response) {
            $a->class = question_get_feedback_class($correctresponse);
            $a->feedbackimg = question_get_feedback_image($correctresponse);
          }
        }

        $a->control = choose_from_menu($answers, $menuname, $response, 'choose',
                                       '', 0, true, $options->readonly);
        $anss[] = $a;
      }
    }

  }else if($questionType == 'multianswer'){

  }else if($questionType == 'multichoice'){
  
    $answers = &$question->options->answers;
    $correctanswers = $QTYPES['multichoicewiris']->get_correct_responses($question, $state);
    $readonly = empty($options->readonly) ? '' : 'disabled="disabled"';
    $answerprompt = ($question->options->single) ? get_string('singleanswer', 'quiz') :
                    get_string('multipleanswers', 'quiz');
    // Print each answer in a separate row
    foreach ($state->options->order as $key => $aid) {
      $answer = &$answers[$aid];
      $checked = '';
      $chosen = false;

      if ($question->options->single) {
        $type = 'type="radio"';
        $name   = "name=\"{$question->name_prefix}\"";
        if (isset($state->responses['']) and $aid == $state->responses['']) {
          $checked = 'checked="checked"';
          $chosen = true;
        }
      } else {
        $type = ' type="checkbox" ';
        $name   = "name=\"{$question->name_prefix}{$aid}\"";
        if (isset($state->responses[$aid])) {
          $checked = 'checked="checked"';
          $chosen = true;
        }
      }

      $a = new stdClass;
      $a->id   = $question->name_prefix . $aid;
      $a->class = '';
      $a->feedbackimg = '';

      // Print the control
      $a->control = "<input $readonly id=\"$a->id\" $name $checked $type value=\"$aid\" />";

      if ($options->correct_responses && $answer->fraction > 0) {
        $a->class = question_get_feedback_class(1);
      }
      if (($options->feedback && $chosen) || $options->correct_responses) {
        if ($type == ' type="checkbox" ') {
          $a->feedbackimg = question_get_feedback_image($answer->fraction > 0 ? 1 : 0, $chosen && $options->feedback);
        } else {
          $a->feedbackimg = question_get_feedback_image($answer->fraction, $chosen && $options->feedback);
        }
      }

      // Print the answer text
      $a->text = $QTYPES['multichoicewiris']->number_in_style($key, $question->options->answernumbering) .
                 format_text($answer->answer, FORMAT_MOODLE, $formatoptions, $cmoptions->course);

      // Print feedback if feedback is on
      if (($options->feedback || $options->correct_responses) && $checked) {
        $a->feedback = format_text($answer->feedback, true, $formatoptions, $cmoptions->course);
      } else {
        $a->feedback = '';
      }

      $anss[] = clone($a);
    }

    $feedback = '';
      if ($options->feedback) {
        if ($state->raw_grade >= $question->maxgrade/1.01) {
          $feedback = $question->options->correctfeedback;
        } else if ($state->raw_grade > 0) {
          $feedback = $question->options->partiallycorrectfeedback;
        } else {
          $feedback = $question->options->incorrectfeedback;
        }
        $feedback = format_text($feedback, $question->questiontextformat,
                    $formatoptions, $cmoptions->course);
        }

  

  }else if($questionType == 'shortanswer'){
    $value = '';
    $readonly = (empty($options->readonly)) ? '' : 'readonly="readonly"';
    $feedback = '';
		$class = '';
		$feedbackimg = '';

    if (isset($state->responses['']) && $state->responses[''] != '') {
      $value = s($state->responses[''], true);
    }
    mb_parse_str($question->options->wiris->eqoption, $eqoptionArray);
		$wirisEditorEnabled = (isset($eqoptionArray['editor']) && $eqoptionArray['editor'] == 'true');
		if($wirisCASForComputationsEnabled && $wirisEditorEnabled){
      //copy button
      $wirisCASApplet .= '<input id="'.$inputname.'copy_button" name="'.$inputname.'copy_button" type="button" '.
                         'value="'.wrsqz_get_string('wrsqz_copyresponse')
                         .'" onclick="copyCASSessionToEditor('.$question->id.',\''.$inputname.'\')"/>';
      require_js('yui_connection');
    }
    //$wirisCASForComputationsEnabled = (isset($eqoptionArray['wirisCASForComputations']) && $eqoptionArray['wirisCASForComputations'] == 'true');
		$multipleAnswers = (isset($eqoptionArray['multipleAnswers']) && $eqoptionArray['multipleAnswers'] == 'true');

		if ($multipleAnswers) {
			$formulaGrammar = 'http://' . $CFG->wirisservicehost . ':' . $CFG->wirisserviceport . $CFG->wirisservicepath . '/test/grammars/grammar-assign.txt';
			$formulaGrammarTarget = 'math2';
		}else {
			$formulaGrammar = 'http://' . $CFG->wirisservicehost . ':' . $CFG->wirisserviceport . $CFG->wirisservicepath . '/test/grammars/grammar.txt';
			$formulaGrammarTarget = 'math';
		}
    $wirisEditorApplet = wrsqz_wirisEditorAppletHTML($inputname, $formulaGrammar, $formulaGrammarTarget, $value);
    require_js(array('yui_yahoo', 'yui_dom-event'));
    require_js(array($CFG->wwwroot.'/wiris-quizzes/js/wiris-quizzes.js', $CFG->wwwroot.'/wiris-quizzes/js/constants.js.php'));
    
    // Chose feedback according to current response
		if ($options->feedback) {
			$class = question_get_feedback_class(0);
			$feedbackimg = question_get_feedback_image(0);
			$i = 0;

			foreach ($question->options->answers as $answer) {
				if (wrsqz_testResponse($question, $state, $answer) || (!empty($state->grades) && $state->grades[$i] > 0.0)) {
					$class = question_get_feedback_class($answer->fraction);
					$feedbackimg = question_get_feedback_image($answer->fraction);

					if ($answer->feedback) {
						$feedback = format_text($answer->feedback, true, $formatoptions, $cmoptions->course);
					}
					break;
				}
				++$i;
			}
		}
  }else if($questionType == 'truefalse'){
    $readonly = $options->readonly ? ' disabled="disabled"' : '';
    $answers = &$question->options->answers;
    $trueanswer = &$answers[$question->options->trueanswer];
    $falseanswer = &$answers[$question->options->falseanswer];
    $correctanswer = ($trueanswer->fraction == 1) ? $trueanswer : $falseanswer;

    $trueclass = '';
    $falseclass = '';
    $truefeedbackimg = '';
    $falsefeedbackimg = '';

    // Work out which radio button to select (if any)
    if (isset($state->responses[''])) {
      $response = $state->responses[''];
    } else {
      $response = '';
    }
    $truechecked = ($response == $trueanswer->id) ? ' checked="checked"' : '';
    $falsechecked = ($response == $falseanswer->id) ? ' checked="checked"' : '';

    // Work out visual feedback for answer correctness.
    if ($options->feedback) {
      if ($truechecked) {
         $trueclass = question_get_feedback_class($trueanswer->fraction);
      } else if ($falsechecked) {
         $falseclass = question_get_feedback_class($falseanswer->fraction);
      }
    }
    if ($options->feedback || $options->correct_responses) {
      if (isset($answers[$response])) {
        $truefeedbackimg = question_get_feedback_image($trueanswer->fraction, !empty($truechecked) && $options->feedback);
        $falsefeedbackimg = question_get_feedback_image($falseanswer->fraction, !empty($falsechecked) && $options->feedback);
      }
    }

    $inputname = ' name="'.$question->name_prefix.'" ';
    $trueid    = $question->name_prefix.'true';
    $falseid   = $question->name_prefix.'false';

    $radiotrue = '<input type="radio"' . $truechecked . $readonly . $inputname
      . 'id="'.$trueid . '" value="' . $trueanswer->id . '" /><label for="'.$trueid . '">'
      . s($trueanswer->answer) . '</label>';
    $radiofalse = '<input type="radio"' . $falsechecked . $readonly . $inputname
      . 'id="'.$falseid . '" value="' . $falseanswer->id . '" /><label for="'.$falseid . '">'
      . s($falseanswer->answer) . '</label>';

    $feedback = '';
    if ($options->feedback and isset($answers[$response])) {
      //choose feedback depending on correctness of response
      if($answers[$response]->fraction == 1){
        $feedback = format_text($trueanswer->feedback, true, $formatoptions, $cmoptions->course);
      }else{
        $feedback = format_text($falseanswer->feedback, true, $formatoptions, $cmoptions->course);
      }
    }
  }
  //print body
  include("$CFG->dirroot/question/type/$question->qtype/display.html");

  //print buttons
  $QTYPES[$question->qtype]->print_question_submit_buttons($question, $state, $cmoptions, $options);
  echo '</div>'; //close <div class="block clearfix">
  if($questionType == 'essay' && empty($options->readonly) && !empty($usehtmleditor)){
    use_html_editor($inputname);
    $htmleditorused = true;
  }else if($questionType == 'truefalse'){
    echo '</div>'; //close <div class = "truefalse"/>
  }
}
Ejemplo n.º 14
0
 function print_question_formulation_and_controls(&$question, &$state, $cmoptions, $options)
 {
     global $CFG;
     /// This implementation is also used by question type 'numerical'
     $readonly = empty($options->readonly) ? '' : 'readonly="readonly"';
     $formatoptions = new stdClass();
     $formatoptions->noclean = true;
     $formatoptions->para = false;
     $nameprefix = $question->name_prefix;
     /// Print question text and media
     $questiontext = format_text($question->questiontext, $question->questiontextformat, $formatoptions, $cmoptions->course);
     $image = get_question_image($question, $cmoptions->course);
     /// Print input controls
     if (isset($state->responses['']) && $state->responses[''] != '') {
         $value = ' value="' . s($state->responses[''], true) . '" ';
     } else {
         $value = ' value="" ';
     }
     $inputname = ' name="' . $nameprefix . '" ';
     $feedback = '';
     $class = '';
     $feedbackimg = '';
     if ($options->feedback) {
         $class = question_get_feedback_class(0);
         $feedbackimg = question_get_feedback_image(0);
         foreach ($question->options->answers as $answer) {
             if ($this->test_response($question, $state, $answer)) {
                 // Answer was correct or partially correct.
                 $class = question_get_feedback_class($answer->fraction);
                 $feedbackimg = question_get_feedback_image($answer->fraction);
                 if ($answer->feedback) {
                     $feedback = format_text($answer->feedback, true, $formatoptions, $cmoptions->course);
                 }
                 break;
             }
         }
     }
     /// Removed correct answer, to be displayed later MDL-7496
     include "{$CFG->dirroot}/question/type/shortanswer/display.html";
 }
Ejemplo n.º 15
0
 function print_question_formulation_and_controls(&$question, &$state, $cmoptions, $options)
 {
     global $CFG;
     $subquestions = $state->options->subquestions;
     $correctanswers = $this->get_correct_responses($question, $state);
     $nameprefix = $question->name_prefix;
     $answers = array();
     $allanswers = array();
     $answerids = array();
     $responses =& $state->responses;
     // Prepare a list of answers, removing duplicates.
     foreach ($subquestions as $subquestion) {
         foreach ($subquestion->options->answers as $ans) {
             $allanswers[$ans->id] = $ans->answer;
             if (!in_array($ans->answer, $answers)) {
                 $answers[$ans->id] = $ans->answer;
                 $answerids[$ans->answer] = $ans->id;
             }
         }
     }
     // Fix up the ids of any responses that point the the eliminated duplicates.
     foreach ($responses as $subquestionid => $ignored) {
         if ($responses[$subquestionid]) {
             $responses[$subquestionid] = $answerids[$allanswers[$responses[$subquestionid]]];
         }
     }
     foreach ($correctanswers as $subquestionid => $ignored) {
         $correctanswers[$subquestionid] = $answerids[$allanswers[$correctanswers[$subquestionid]]];
     }
     // Shuffle the answers
     $answers = draw_rand_array($answers, count($answers));
     // Print formulation
     $questiontext = $this->format_text($question->questiontext, $question->questiontextformat, $cmoptions);
     $image = get_question_image($question);
     // Print the input controls
     foreach ($subquestions as $key => $subquestion) {
         if ($subquestion->questiontext != '') {
             // Subquestion text:
             $a = new stdClass();
             $a->text = $this->format_text($subquestion->questiontext, $question->questiontextformat, $cmoptions);
             // Drop-down list:
             $menuname = $nameprefix . $subquestion->id;
             $response = isset($state->responses[$subquestion->id]) ? $state->responses[$subquestion->id] : '0';
             $a->class = ' ';
             $a->feedbackimg = ' ';
             if ($options->readonly and $options->correct_responses) {
                 if (isset($correctanswers[$subquestion->id]) and $correctanswers[$subquestion->id] == $response) {
                     $correctresponse = 1;
                 } else {
                     $correctresponse = 0;
                 }
                 if ($options->feedback && $response) {
                     $a->class = question_get_feedback_class($correctresponse);
                     $a->feedbackimg = question_get_feedback_image($correctresponse);
                 }
             }
             $a->control = choose_from_menu($answers, $menuname, $response, 'choose', '', 0, true, $options->readonly);
             // Neither the editing interface or the database allow to provide
             // fedback for this question type.
             // However (as was pointed out in bug bug 3294) the randomsamatch
             // type which reuses this method can have feedback defined for
             // the wrapped shortanswer questions.
             //if ($options->feedback
             // && !empty($subquestion->options->answers[$responses[$key]]->feedback)) {
             //    print_comment($subquestion->options->answers[$responses[$key]]->feedback);
             //}
             $anss[] = $a;
         }
     }
     include "{$CFG->dirroot}/question/type/match/display.html";
 }
Ejemplo n.º 16
0
 function print_question_formulation_and_controls(&$question, &$state, $cmoptions, $options)
 {
     global $CFG;
     $answers =& $question->options->answers;
     $correctanswers = $this->get_correct_responses($question, $state);
     $readonly = empty($options->readonly) ? '' : 'disabled="disabled"';
     $formatoptions = new stdClass();
     $formatoptions->noclean = true;
     $formatoptions->para = false;
     // Print formulation
     $questiontext = format_text($question->questiontext, $question->questiontextformat, $formatoptions, $cmoptions->course);
     $image = get_question_image($question);
     $answerprompt = $question->options->single ? get_string('singleanswer', 'quiz') : get_string('multipleanswers', 'quiz');
     // Print each answer in a separate row
     foreach ($state->options->order as $key => $aid) {
         $answer =& $answers[$aid];
         $checked = '';
         $chosen = false;
         if ($question->options->single) {
             $type = 'type="radio"';
             $name = "name=\"{$question->name_prefix}\"";
             if (isset($state->responses['']) and $aid == $state->responses['']) {
                 $checked = 'checked="checked"';
                 $chosen = true;
             }
         } else {
             $type = ' type="checkbox" ';
             $name = "name=\"{$question->name_prefix}{$aid}\"";
             if (isset($state->responses[$aid])) {
                 $checked = 'checked="checked"';
                 $chosen = true;
             }
         }
         $a = new stdClass();
         $a->id = $question->name_prefix . $aid;
         $a->class = '';
         $a->feedbackimg = '';
         // Print the control
         $a->control = "<input {$readonly} id=\"{$a->id}\" {$name} {$checked} {$type} value=\"{$aid}\" />";
         if ($options->correct_responses && $answer->fraction > 0) {
             $a->class = question_get_feedback_class(1);
         }
         if ($options->feedback && $chosen || $options->correct_responses) {
             if ($type == ' type="checkbox" ') {
                 $a->feedbackimg = question_get_feedback_image($answer->fraction > 0 ? 1 : 0, $chosen && $options->feedback);
             } else {
                 $a->feedbackimg = question_get_feedback_image($answer->fraction, $chosen && $options->feedback);
             }
         }
         // Print the answer text
         $a->text = $this->number_in_style($key, $question->options->answernumbering) . format_text($answer->answer, FORMAT_MOODLE, $formatoptions, $cmoptions->course);
         // Print feedback if feedback is on
         if (($options->feedback || $options->correct_responses) && $checked) {
             $a->feedback = format_text($answer->feedback, true, $formatoptions, $cmoptions->course);
         } else {
             $a->feedback = '';
         }
         $anss[] = clone $a;
     }
     $feedback = '';
     if ($options->feedback) {
         if ($state->raw_grade >= $question->maxgrade / 1.01) {
             $feedback = $question->options->correctfeedback;
         } else {
             if ($state->raw_grade > 0) {
                 $feedback = $question->options->partiallycorrectfeedback;
             } else {
                 $feedback = $question->options->incorrectfeedback;
             }
         }
         $feedback = format_text($feedback, $question->questiontextformat, $formatoptions, $cmoptions->course);
     }
     include "{$CFG->dirroot}/question/type/multichoice/display.html";
 }
Ejemplo n.º 17
0
 /**
  * @param string $colname the name of the column.
  * @param object $attempt the row of data - see the SQL in display() in
  * mod/quiz/report/overview/report.php to see what fields are present,
  * and what they are called.
  * @return string the contents of the cell.
  */
 function other_cols($colname, $attempt)
 {
     if (preg_match('/^qsgrade([0-9]+)$/', $colname, $matches)) {
         $questionid = $matches[1];
         $question = $this->questions[$questionid];
         if (isset($this->gradedstatesbyattempt[$attempt->attemptuniqueid][$questionid])) {
             $stateforqinattempt = $this->gradedstatesbyattempt[$attempt->attemptuniqueid][$questionid];
         } else {
             $stateforqinattempt = false;
         }
         if ($stateforqinattempt && question_state_is_graded($stateforqinattempt)) {
             $grade = quiz_rescale_grade($stateforqinattempt->grade, $this->quiz, 'question');
             if (!$this->is_downloading()) {
                 if (isset($this->regradedqs[$attempt->attemptuniqueid][$questionid])) {
                     $gradefromdb = $grade;
                     $newgrade = quiz_rescale_grade($this->regradedqs[$attempt->attemptuniqueid][$questionid]->newgrade, $this->quiz, 'question');
                     $oldgrade = quiz_rescale_grade($this->regradedqs[$attempt->attemptuniqueid][$questionid]->oldgrade, $this->quiz, 'question');
                     $grade = '<del>' . $oldgrade . '</del><br />' . $newgrade;
                 }
                 $linktopopup = link_to_popup_window('/mod/quiz/reviewquestion.php?attempt=' . $attempt->attempt . '&amp;question=' . $question->id, 'reviewquestion', $grade, 450, 650, get_string('reviewresponse', 'quiz'), 'none', true);
                 if ($this->questions[$questionid]->maxgrade != 0) {
                     $fractionofgrade = $stateforqinattempt->grade / $this->questions[$questionid]->maxgrade;
                     $qclass = question_get_feedback_class($fractionofgrade);
                     $feedbackimg = question_get_feedback_image($fractionofgrade);
                     $questionclass = "que";
                     return "<span class=\"{$questionclass}\"><span class=\"{$qclass}\">" . $linktopopup . "</span></span>{$feedbackimg}";
                 } else {
                     return $linktopopup;
                 }
             } else {
                 return $grade;
             }
         } else {
             return '--';
         }
     } else {
         return NULL;
     }
 }
 /**
  * Prints the main content of the question including any interactions
  *
  * This function prints the main content of the question including the
  * interactions for the question in the state given. The last graded responses
  * are printed or indicated and the current responses are selected or filled in.
  * Any names (eg. for any form elements) are prefixed with $question->name_prefix.
  * This method is called from the print_question method. The algebra question type
  * changes this from the default method to include a "display formula" button which
  * interprets the formula in the response box and gives a graphical representation
  * for the student to check.
  *
  * @param object $question The question to be rendered. Question type
  *                         specific information is included. The name
  *                         prefix for any named elements is in ->name_prefix.
  * @param object $state    The state to render the question in. The grading
  *                         information is in ->grade, ->raw_grade and
  *                         ->penalty. The current responses are in
  *                         ->responses. This is an associative array (or the
  *                         empty string or null in the case of no responses
  *                         submitted). The last graded state is in
  *                         ->last_graded (hence the most recently graded
  *                         responses are in ->last_graded->responses). The
  *                         question type specific information is also
  *                         included.
  *                         The state is passed by reference because some adaptive
  *                         questions may want to update it during rendering
  * @param object $cmoptions
  * @param object $options  An object describing the rendering options.
  */
 function print_question_formulation_and_controls(&$question, &$state, $cmoptions, $options)
 {
     global $CFG;
     /// This implementation is copied from short answer
     $readonly = empty($options->readonly) ? '' : 'readonly="readonly"';
     $formatoptions = new stdClass();
     $formatoptions->noclean = true;
     $formatoptions->para = false;
     $nameprefix = $question->name_prefix;
     // Print the text associated with the question
     $questiontext = format_text($question->questiontext, $question->questiontextformat, $formatoptions, $cmoptions->course);
     // Get the image, if any, associated with the question
     $image = get_question_image($question);
     // Sets the value of the input box for the question to the current student
     // response if there is one
     if (isset($state->responses['']) && $state->responses[''] != '') {
         $value = ' value="' . s($state->responses[''], true) . '" ';
     } else {
         $value = ' value="" ';
     }
     // Defines the name of the input box where the student enters a response for the question
     $inputname = ' name="' . $nameprefix . '" ';
     $feedback = '';
     $class = '';
     $feedbackimg = '';
     if ($options->feedback) {
         $class = question_get_feedback_class(0);
         $feedbackimg = question_get_feedback_image(0);
         // Parse the response here since this saves time parsing once for each comparison
         $response = $this->parse_expression($state, $question);
         // Loop over all the answers to the question
         foreach ($question->options->answers as $answer) {
             // Compare the response against the current answer
             if ($this->test_response($question, $response, $answer)) {
                 // Answer was correct or partially correct.
                 $class = question_get_feedback_class($answer->fraction);
                 $feedbackimg = question_get_feedback_image($answer->fraction);
                 if ($answer->feedback) {
                     $feedback = format_text($answer->feedback, true, $formatoptions, $cmoptions->course);
                 }
                 break;
             }
         }
     }
     // The name for the iframe which displays the rendered formula
     $iframename = ' name="' . $nameprefix . 'if"';
     // Name of the javascript function which causes the entered formula to be rendered
     $df_name = $nameprefix . '_display';
     // Create an array of variable names to use when displaying the function entered
     $varnames = array();
     if ($question and isset($question->options->variables)) {
         foreach ($question->options->variables as $var) {
             $varnames[] = $var->name;
         }
     }
     $varnames = implode(',', $varnames);
     // Javascript function which the button uses to display the rendering
     // This function sents the source of the iframe to the 'displayformula.php' script giving
     // it an argument of the formula entered by the student.
     $displayfunction = 'function ' . $df_name . "() {\n" . '    var text="vars=' . $varnames . '&expr="+escape(document.getElementsByName("' . $nameprefix . '")[0].value);' . "\n" . "    if(text.length != 0) {\n" . '      document.getElementsByName("' . $nameprefix . 'if")[0].src="' . $CFG->wwwroot . '/question/type/algebra/displayformula.php?"+' . 'text.replace(/\\+/g,"%2b")' . "\n" . "    }\n" . "  }\n";
     // Include the HTML/php file which uses the variables above to render the question
     include "{$CFG->dirroot}/question/type/algebra/display.html";
 }
Ejemplo n.º 19
0
 /**
  * Performs response processing and grading
  * The function was redefined for handling correctly the two parts
  * number and unit of numerical or calculated questions
  * The code handles also the case when there no unit defined by the user or
  * when used in a multianswer (Cloze) question.
  * This function performs response processing and grading and updates
  * the state accordingly.
  * @return boolean         Indicates success or failure.
  * @param object $question The question to be graded. Question type
  *                         specific information is included.
  * @param object $state    The state of the question to grade. The current
  *                         responses are in ->responses. The last graded state
  *                         is in ->last_graded (hence the most recently graded
  *                         responses are in ->last_graded->responses). The
  *                         question type specific information is also
  *                         included. The ->raw_grade and ->penalty fields
  *                         must be updated. The method is able to
  *                         close the question session (preventing any further
  *                         attempts at this question) by setting
  *                         $state->event to QUESTION_EVENTCLOSEANDGRADE
  * @param object $cmoptions
  */
 function grade_responses(&$question, &$state, $cmoptions)
 {
     if (isset($state->responses['']) && $state->responses[''] != '' && !isset($state->responses['answer'])) {
         $this->split_old_answer($state->responses[''], $question->options->units, $state->responses['answer'], $state->responses['unit']);
     }
     $state->raw_grade = 0;
     $valid_numerical_unit = false;
     $break = 0;
     $unittested = '';
     $hasunits = 0;
     $answerasterisk = false;
     $break = 0;
     foreach ($question->options->answers as $answer) {
         if ($this->test_response($question, $state, $answer)) {
             // Answer was correct or partially correct.
             $state->raw_grade = $answer->fraction;
             if ($question->options->unitgradingtype == 0 || $answer->answer === '*') {
                 // if * then unit has the $answer->fraction value
                 // if $question->options->unitgradingtype == 0 everything has been checked
                 // if $question->options->showunits == NUMERICALQUESTIONUNITTEXTINPUTDISPLAY
                 // then number - unit combination has been used to test response
                 // so the unit should have same color
             } else {
                 // so we need to apply unit grading i.e. to check if the number-unit combination
                 // was the rigth one
                 $valid_numerical_unit = false;
                 $class = question_get_feedback_class($answer->fraction);
                 $feedbackimg = question_get_feedback_image($answer->fraction);
                 if (isset($state->responses['unit']) && $state->responses['unit'] != '') {
                     foreach ($question->options->units as $key => $unit) {
                         if ($unit->unit == $state->responses['unit']) {
                             $response = $this->apply_unit($state->responses['answer'] . $state->responses['unit'], array($question->options->units[$key]));
                             if ($response !== false) {
                                 $this->get_tolerance_interval($answer);
                                 if ($answer->min <= $response && $response <= $answer->max) {
                                     $valid_numerical_unit = true;
                                 }
                             }
                             break;
                         }
                     }
                 }
             }
             break;
         }
     }
     // apply unit penalty
     $raw_unitpenalty = 0;
     if ($question->options->unitgradingtype != 0 && !empty($question->options->unitpenalty) && $valid_numerical_unit != true) {
         if ($question->options->unitgradingtype == 1) {
             $raw_unitpenalty = $question->options->unitpenalty * $state->raw_grade;
         } else {
             $raw_unitpenalty = $question->options->unitpenalty;
         }
         $state->raw_grade -= $raw_unitpenalty;
     }
     // Make sure we don't assign negative or too high marks.
     $state->raw_grade = min(max((double) $state->raw_grade, 0.0), 1.0) * $question->maxgrade;
     // Update the penalty.
     $state->penalty = $question->penalty * $question->maxgrade;
     // mark the state as graded
     $state->event = $state->event == QUESTION_EVENTCLOSE ? QUESTION_EVENTCLOSEANDGRADE : QUESTION_EVENTGRADE;
     return true;
 }
Ejemplo n.º 20
0
/**
 * Returns the html for question feedback image.
 * @param float   $fraction  value representing the correctness of the user's
 *                           response to a question.
 * @param boolean $selected  whether or not the answer is the one that the
 *                           user picked.
 * @return string
 */
function question_get_feedback_image($fraction, $selected = true)
{
    global $CFG;
    static $icons = array('correct' => 'tick_green', 'partiallycorrect' => 'tick_amber', 'incorrect' => 'cross_red');
    if ($selected) {
        $size = 'big';
    } else {
        $size = 'small';
    }
    $class = question_get_feedback_class($fraction);
    return '<img src="' . $CFG->pixpath . '/i/' . $icons[$class] . '_' . $size . '.gif" ' . 'alt="' . get_string($class, 'quiz') . '" class="icon" />';
}
 function print_question_formulation_and_controls(&$question, &$state, $cmoptions, $options)
 {
     global $CFG, $USER;
     $subquestions = $state->options->subquestions;
     $correctanswers = $this->get_correct_responses($question, $state);
     $nameprefix = $question->name_prefix;
     $answers = array();
     $allanswers = array();
     $answerids = array();
     $responses =& $state->responses;
     // Check browser version to see if YUI is supported properly.
     // This is similar to ajaxenabled() from lib/ajax/ajaxlib.php,
     // except it doesn't check the site-wide AJAX settings.
     $fallbackonly = false;
     $ie = check_browser_version('MSIE', 6.0);
     $ff = check_browser_version('Gecko', 20051106);
     $op = check_browser_version('Opera', 9.0);
     $sa = check_browser_version('Safari', 412);
     if (!$ie && !$ff && !$op && !$sa or !empty($USER->screenreader)) {
         $fallbackonly = true;
     }
     // Prepare a list of answers, removing duplicates.
     foreach ($subquestions as $subquestion) {
         foreach ($subquestion->options->answers as $ans) {
             $allanswers[$ans->id] = $this->format_text($ans->answer, $question->questiontextformat, $cmoptions);
             if (!in_array($allanswers[$ans->id], $answers)) {
                 $ans->answer = $allanswers[$ans->id];
                 $answers[$ans->id] = $ans->answer;
                 $answerids[$ans->answer] = $ans->id;
             }
         }
     }
     // Fix up the ids of any responses that point the the eliminated duplicates.
     foreach ($responses as $subquestionid => $ignored) {
         if ($responses[$subquestionid]) {
             $responses[$subquestionid] = $answerids[$allanswers[$responses[$subquestionid]]];
         }
     }
     foreach ($correctanswers as $subquestionid => $ignored) {
         $correctanswers[$subquestionid] = $answerids[$allanswers[$correctanswers[$subquestionid]]];
     }
     // Shuffle the answers
     $answers = draw_rand_array($answers, count($answers));
     // Print formulation
     $questiontext = $this->format_text($question->questiontext, $question->questiontextformat, $cmoptions);
     $image = get_question_image($question);
     // Javascript Array initialization of list ids
     $elems = array();
     foreach ($subquestions as $subquestion) {
         if ($subquestion->questiontext) {
             $elems[] = '"' . $subquestion->id . '"';
         }
     }
     $questionsarraystring = 'Array(' . implode(',', $elems) . ')';
     $elems = array();
     foreach ($answers as $key => $answer) {
         $elems[] = '"' . $key . '"';
     }
     $answersarraystring = 'Array(' . implode(',', $elems) . ')';
     $elems = array();
     foreach ($subquestions as $subquestion) {
         if ($subquestion->questiontext) {
             $elems[] = '"' . $responses[$subquestion->id] . '"';
         }
     }
     $responsesarraystring = 'Array(' . implode(',', $elems) . ')';
     // Print the input controls
     foreach ($subquestions as $key => $subquestion) {
         if ($subquestion->questiontext) {
             // Subquestion text:
             $a = new stdClass();
             $a->id = $subquestion->id;
             $a->text = $this->format_text($subquestion->questiontext, $question->questiontextformat, $cmoptions);
             // Drop-down list:
             $menuname = $nameprefix . $subquestion->id;
             $response = isset($state->responses[$subquestion->id]) ? $state->responses[$subquestion->id] : '0';
             $a->class = ' ';
             $a->feedbackimg = ' ';
             if ($options->readonly and $options->correct_responses) {
                 if (isset($correctanswers[$subquestion->id]) and $correctanswers[$subquestion->id] == $response) {
                     $correctresponse = 1;
                 } else {
                     $correctresponse = 0;
                 }
                 if ($options->feedback && $response) {
                     $a->class = question_get_feedback_class($correctresponse);
                     $a->feedbackimg = question_get_feedback_image($correctresponse);
                 }
             }
             if (preg_match('/<img/', $a->feedbackimg)) {
                 preg_match('/src="([^"]*)"/', $a->feedbackimg, $matches);
                 $a->feedbackimgsrc = $matches[1];
                 preg_match('/alt="([^"]*)"/', $a->feedbackimg, $matches);
                 $a->feedbackimgalt = $matches[1];
                 preg_match('/class="([^"]*)"/', $a->feedbackimg, $matches);
                 $a->feedbackimgclass = $matches[1];
             }
             $a->control = choose_from_menu($answers, $menuname, $response, 'choose', '', 0, true, $options->readonly);
             // Neither the editing interface or the database allow to provide
             // fedback for this question type.
             // However (as was pointed out in bug bug 3294) the randomsamatch
             // type which reuses this method can have feedback defined for
             // the wrapped shortanswer questions.
             //if ($options->feedback
             // && !empty($subquestion->options->answers[$responses[$key]]->feedback)) {
             //    print_comment($subquestion->options->answers[$responses[$key]]->feedback);
             //}
             $anss[] = $a;
         }
     }
     $dragstring = get_string('draganswerhere', 'qtype_ddmatch');
     include "{$CFG->dirroot}/question/type/ddmatch/display.html";
 }
 function response_summary($question, $state, $length = 80)
 {
     $responses = $this->get_actual_response($question, $state);
     $summaries = '';
     foreach ($question->subpart->parts as $idx => $part) {
         if ($state->subanum == -1 || $state->subanum == $idx) {
             $c = question_get_feedback_class($state->fractions[$idx]);
             $summaries .= '<div class="' . $c . '">' . '<i>(' . ($idx + 1) . '.) </i>' . shorten_text($state->responses[$idx], $length) . '</div>';
         }
     }
     return $summaries;
 }
Ejemplo n.º 23
0
 /**
  * Return a summary of the current state of a question in this attempt. You must previously
  * have called load_question_states to load the state data about this question.
  *
  * @param integer $questionid question id of a question that belongs to this quiz.
  * @return string a brief string (that could be used as a CSS class name, for example)
  * that describes the current state of a question in this attempt. Possible results are:
  * open|saved|closed|correct|partiallycorrect|incorrect.
  */
 public function get_question_status($questionid)
 {
     $state = $this->states[$questionid];
     switch ($state->event) {
         case QUESTION_EVENTOPEN:
             return 'open';
         case QUESTION_EVENTSAVE:
         case QUESTION_EVENTGRADE:
         case QUESTION_EVENTSUBMIT:
             return 'answered';
         case QUESTION_EVENTCLOSEANDGRADE:
         case QUESTION_EVENTCLOSE:
         case QUESTION_EVENTMANUALGRADE:
             $options = $this->get_render_options($questionid);
             if ($options->scores && $this->questions[$questionid]->maxgrade > 0) {
                 return question_get_feedback_class($state->last_graded->raw_grade / $this->questions[$questionid]->maxgrade);
             } else {
                 return 'closed';
             }
         default:
             $a = new stdClass();
             $a->event = $state->event;
             $a->questionid = $questionid;
             $a->attemptid = $this->attempt->id;
             throw new moodle_quiz_exception($this, 'errorunexpectedevent', $a);
     }
 }
Ejemplo n.º 24
0
 function other_cols($colname, $attempt)
 {
     global $QTYPES, $OUTPUT;
     static $states = array();
     if (preg_match('/^qsanswer([0-9]+)$/', $colname, $matches)) {
         if ($attempt->uniqueid == 0) {
             return '-';
         }
         $questionid = $matches[1];
         if (isset($this->gradedstatesbyattempt[$attempt->uniqueid][$questionid])) {
             $stateforqinattempt = $this->gradedstatesbyattempt[$attempt->uniqueid][$questionid];
         } else {
             return '-';
         }
         $question = $this->questions[$questionid];
         restore_question_state($question, $stateforqinattempt);
         if (!$this->is_downloading() || $this->is_downloading() == 'xhtml') {
             $formathtml = true;
         } else {
             $formathtml = false;
         }
         $summary = $QTYPES[$question->qtype]->response_summary($question, $stateforqinattempt, QUIZ_REPORT_RESPONSES_MAX_LEN_TO_DISPLAY, $formathtml);
         if (!$this->is_downloading()) {
             if ($summary) {
                 $link = html_link::make("/mod/quiz/reviewquestion.php?attempt={$attempt->attempt}&question={$question->id}", $summary);
                 $link->add_action(new popup_action('click', $link->url, 'reviewquestion', array('height' => 450, 'width' => 650)));
                 $link->title = $question->formattedname;
                 $summary = $OUTPUT->link($link);
                 if (question_state_is_graded($stateforqinattempt) && $question->maxgrade > 0) {
                     $grade = $stateforqinattempt->grade / $question->maxgrade;
                     $qclass = question_get_feedback_class($grade);
                     $feedbackimg = question_get_feedback_image($grade);
                     $questionclass = "que";
                     return "<span class=\"{$questionclass}\"><span class=\"{$qclass}\">" . $summary . "</span></span>{$feedbackimg}";
                 } else {
                     return $summary;
                 }
             } else {
                 return '';
             }
         } else {
             return $summary;
         }
     } else {
         return NULL;
     }
 }
Ejemplo n.º 25
0
 function other_cols($colname, $attempt)
 {
     global $QTYPES;
     static $states = array();
     if (preg_match('/^qsanswer([0-9]+)$/', $colname, $matches)) {
         if ($attempt->uniqueid == 0) {
             return '-';
         }
         $questionid = $matches[1];
         if (isset($this->gradedstatesbyattempt[$attempt->uniqueid][$questionid])) {
             $stateforqinattempt = $this->gradedstatesbyattempt[$attempt->uniqueid][$questionid];
         } else {
             return '-';
         }
         $question = $this->questions[$questionid];
         restore_question_state($question, $stateforqinattempt);
         if (!$this->is_downloading() || $this->is_downloading() == 'xhtml') {
             $formathtml = true;
         } else {
             $formathtml = false;
         }
         $summary = $QTYPES[$question->qtype]->response_summary($question, $stateforqinattempt, QUIZ_REPORT_RESPONSES_MAX_LEN_TO_DISPLAY, $formathtml);
         if (!$this->is_downloading()) {
             if ($summary) {
                 $summary = link_to_popup_window('/mod/quiz/reviewquestion.php?attempt=' . $attempt->attempt . '&amp;question=' . $question->id, 'reviewquestion', $summary, 450, 650, get_string('reviewresponse', 'quiz'), 'none', true);
                 if (question_state_is_graded($stateforqinattempt) && $question->maxgrade > 0) {
                     $grade = $stateforqinattempt->grade / $question->maxgrade;
                     $qclass = question_get_feedback_class($grade);
                     $feedbackimg = question_get_feedback_image($grade);
                     $questionclass = "que";
                     return "<span class=\"{$questionclass}\"><span class=\"{$qclass}\">" . $summary . "</span></span>{$feedbackimg}";
                 } else {
                     return $summary;
                 }
             } else {
                 return '';
             }
         } else {
             return $summary;
         }
     } else {
         return NULL;
     }
 }