You are here

function qformat_hotpot::process_jquiz in Quiz 6.6

Same name and namespace in other branches
  1. 6.5 includes/moodle/question/format/hotpot/format.php \qformat_hotpot::process_jquiz()
1 call to qformat_hotpot::process_jquiz()
qformat_hotpot::readquestions in includes/moodle/question/format/hotpot/format.php
Parses an array of lines into an array of questions, where each item is a question object as defined by readquestion(). Questions are defined as anything between blank lines.

File

includes/moodle/question/format/hotpot/format.php, line 357

Class

qformat_hotpot
@package questionbank @subpackage importexport

Code

function process_jquiz(&$xml, &$questions) {

  // define default grade (per question)
  $defaultgrade = 1;

  // xml tags to the start of the questions
  $tags = 'data,questions';
  $x = 0;
  while (($exercise = "[{$x}]['#']") && $xml
    ->xml_value($tags, $exercise)) {

    // there is usually only one 'questions' object in a single exercise
    $q = 0;
    while (($question_record = $exercise . "['question-record'][{$q}]['#']") && $xml
      ->xml_value($tags, $question_record)) {
      if (method_exists($this, 'defaultquestion')) {
        $question = $this
          ->defaultquestion();
      }
      else {
        $question = new stdClass();
        $question->usecase = 0;

        // Ignore case
        $question->image = "";

        // No images with this format
      }
      $question->defaultgrade = $defaultgrade;
      $question->name = $this
        ->hotpot_get_title($xml, $q, true);
      $text = $xml
        ->xml_value($tags, $question_record . "['question'][0]['#']");
      $question->questiontext = $this
        ->hotpot_prepare_str($text);
      if ($xml
        ->xml_value($tags, $question_record . "['answers']")) {

        // HP6 JQuiz
        $answers = $question_record . "['answers'][0]['#']";
      }
      else {

        // HP5 JBC or JQuiz
        $answers = $question_record;
      }
      if ($xml
        ->xml_value($tags, $question_record . "['question-type']")) {

        // HP6 JQuiz
        $type = $xml
          ->xml_value($tags, $question_record . "['question-type'][0]['#']");

        //  1 : multiple choice
        //  2 : short-answer
        //  3 : hybrid
        //  4 : multiple select
      }
      else {

        // HP5
        switch ($xml->quiztype) {
          case 'jbc':
            $must_select_all = $xml
              ->xml_value($tags, $question_record . "['must-select-all'][0]['#']");
            if (empty($must_select_all)) {
              $type = 1;

              // multichoice
            }
            else {
              $type = 4;

              // multiselect
            }
            break;
          case 'jquiz':
            $type = 2;

            // shortanswer
            break;
          default:
            $type = 0;
        }
      }
      $question->qtype = $type == 2 ? SHORTANSWER : MULTICHOICE;
      $question->single = $type == 4 ? 0 : 1;

      // workaround required to calculate scores for multiple select answers
      $no_of_correct_answers = 0;
      if ($type == 4) {
        $a = 0;
        while (($answer = $answers . "['answer'][{$a}]['#']") && $xml
          ->xml_value($tags, $answer)) {
          $correct = $xml
            ->xml_value($tags, $answer . "['correct'][0]['#']");
          if (empty($correct)) {

            // do nothing
          }
          else {
            $no_of_correct_answers++;
          }
          $a++;
        }
      }
      $a = 0;
      $question->answer = array();
      $question->fraction = array();
      $question->feedback = array();
      $aa = 0;
      $correct_answers = array();
      $correct_answers_all_zero = true;
      while (($answer = $answers . "['answer'][{$a}]['#']") && $xml
        ->xml_value($tags, $answer)) {
        $correct = $xml
          ->xml_value($tags, $answer . "['correct'][0]['#']");
        if (empty($correct)) {
          $fraction = 0;
        }
        else {
          if ($type == 4) {

            // multiple select
            // strange behavior if the $fraction isn't exact to 5 decimal places
            $fraction = round(1 / $no_of_correct_answers, 5);
          }
          else {
            if ($xml
              ->xml_value($tags, $answer . "['percent-correct']")) {

              // HP6 JQuiz
              $percent = $xml
                ->xml_value($tags, $answer . "['percent-correct'][0]['#']");
              $fraction = $percent / 100;
            }
            else {

              // HP5 JBC or JQuiz
              $fraction = 1;
            }
          }
        }
        $answertext = $this
          ->hotpot_prepare_str($xml
          ->xml_value($tags, $answer . "['text'][0]['#']"));
        if ($answertext != '') {
          $question->answer[$aa] = $answertext;
          $question->fraction[$aa] = $fraction;
          $question->feedback[$aa] = $this
            ->hotpot_prepare_str($xml
            ->xml_value($tags, $answer . "['feedback'][0]['#']"));
          if ($correct) {
            if ($fraction) {
              $correct_answers_all_zero = false;
            }
            $correct_answers[] = $aa;
          }
          $aa++;
        }
        $a++;
      }
      if ($correct_answers_all_zero) {

        // correct answers all have score of 0%,
        // so reset score for correct answers 100%
        foreach ($correct_answers as $aa) {
          $question->fraction[$aa] = 1;
        }
      }

      // add a sanity check for empty questions, see MDL-17779
      if (!empty($question->questiontext)) {
        $questions[] = $question;
      }
      $q++;
    }
    $x++;
  }
}