Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.
   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  /**
  17   * @package    backup-convert
  18   * @copyright  2012 Darko Miletic <dmiletic@moodlerooms.com>
  19   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  20   */
  21  
  22  defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.');
  23  
  24  require_once ('cc_asssesment.php');
  25  
  26  class cc_assesment_question_sfib extends cc_assesment_question_proc_base {
  27      public function __construct($quiz, $questions, $manifest, $section, $question_node, $rootpath, $contextid, $outdir) {
  28          parent::__construct($quiz, $questions, $manifest, $section, $question_node, $rootpath, $contextid, $outdir);
  29          $this->qtype = cc_qti_profiletype::field_entry;
  30          $this->correct_answer_node_id = $this->questions->nodeValue(
  31              'plugin_qtype_truefalse_question/truefalse/trueanswer',
  32              $this->question_node
  33          );
  34          $maximum_quiz_grade = (int)$this->quiz->nodeValue('/activity/quiz/grade');
  35          $this->total_grade_value = ($maximum_quiz_grade + 1).'.0000000';
  36      }
  37  
  38      public function on_generate_metadata() {
  39          parent::on_generate_metadata();
  40  
  41          $category = $this->questions->nodeValue('../../name', $this->question_node);
  42          if (!empty($category)) {
  43              $this->qmetadata->set_category($category);
  44          }
  45      }
  46  
  47      public function on_generate_presentation() {
  48          parent::on_generate_presentation();
  49          $response_str = new cc_assesment_response_strtype();
  50          $response_fib = new cc_assesment_render_fibtype();
  51  
  52           // The standard requires that only rows attribute must be set,
  53           // the rest may or may not be configured. For the sake of brevity we leave it empty.
  54          $response_fib->set_rows(1);
  55          $response_str->set_render_fib($response_fib);
  56          $this->qpresentation->set_response_str($response_str);
  57      }
  58  
  59      public function on_generate_feedbacks() {
  60          parent::on_generate_feedbacks();
  61          // Question combined feedback.
  62          $responsenodes = $this->questions->nodeList('plugin_qtype_shortanswer_question//answer', $this->question_node);
  63          $count = 0;
  64          foreach ($responsenodes as $respnode) {
  65              $content = $this->questions->nodeValue('feedback', $respnode);
  66              if (empty($content)) {
  67                  continue;
  68              }
  69  
  70              $correct = (int)$this->questions->nodeValue('fraction', $respnode) == 1;
  71              $answerid = (int)$this->questions->nodeValue('@id', $respnode);
  72  
  73              $result = cc_helpers::process_linked_files( $content,
  74                                                          $this->manifest,
  75                                                          $this->rootpath,
  76                                                          $this->contextid,
  77                                                          $this->outdir);
  78              $ident = $correct ? 'correct' : 'incorrect';
  79              $ident .= '_'.$count.'_fb';
  80              cc_assesment_helper::add_feedback( $this->qitem,
  81                                                  $result[0],
  82                                                  cc_qti_values::htmltype,
  83                                                  $ident);
  84  
  85              pkg_resource_dependencies::instance()->add($result[1]);
  86  
  87              if ($correct) {
  88                  $this->correct_feedbacks[$answerid] = $ident;
  89              } else {
  90                  $this->incorrect_feedbacks[$answerid] = $ident;
  91              }
  92  
  93              ++$count;
  94          }
  95      }
  96  
  97      public function on_generate_response_processing() {
  98          parent::on_generate_response_processing();
  99  
 100          // General unconditional feedback must be added as a first respcondition
 101          // without any condition and just displayfeedback (if exists).
 102          if (!empty($this->general_feedback)) {
 103              $qrespcondition = new cc_assesment_respconditiontype();
 104              $qrespcondition->set_title('General feedback');
 105              $this->qresprocessing->add_respcondition($qrespcondition);
 106              $qrespcondition->enable_continue();
 107              // Define the condition for success.
 108              $qconditionvar = new cc_assignment_conditionvar();
 109              $qrespcondition->set_conditionvar($qconditionvar);
 110              $qother = new cc_assignment_conditionvar_othertype();
 111              $qconditionvar->set_other($qother);
 112              $qdisplayfeedback = new cc_assignment_displayfeedbacktype();
 113              $qrespcondition->add_displayfeedback($qdisplayfeedback);
 114              $qdisplayfeedback->set_feedbacktype(cc_qti_values::Response);
 115              $qdisplayfeedback->set_linkrefid('general_fb');
 116          }
 117  
 118          // Answer separate conditions.
 119          $correct_responses = $this->questions->nodeList(
 120              'plugin_qtype_shortanswer_question//answer[fraction=1]', $this->question_node);
 121          $incorrect_responses = $this->questions->nodeList(
 122              'plugin_qtype_shortanswer_question//answer[fraction<1]', $this->question_node);
 123          $items = array(
 124              array($correct_responses, $this->correct_feedbacks),
 125              array($incorrect_responses, $this->incorrect_feedbacks)
 126          );
 127          foreach ($items as $respfeed) {
 128              foreach ($respfeed[0] as $coresponse) {
 129                  $qrespcondition = new cc_assesment_respconditiontype();
 130                  $qrespcondition->enable_continue();
 131                  $this->qresprocessing->add_respcondition($qrespcondition);
 132                  $qconditionvar = new cc_assignment_conditionvar();
 133                  $qrespcondition->set_conditionvar($qconditionvar);
 134                  $respc = $this->questions->nodeValue('answertext', $coresponse);
 135                  $resid = $this->questions->nodeValue('@id', $coresponse);
 136                  $qvarequal = new cc_assignment_conditionvar_varequaltype($respc);
 137                  $qconditionvar->set_varequal($qvarequal);
 138                  $qvarequal->set_respident('response');
 139                  $qvarequal->enable_case(false);
 140                  if (!empty($respfeed[1][$resid])) {
 141                      $qdisplayfeedback = new cc_assignment_displayfeedbacktype();
 142                      $qrespcondition->add_displayfeedback($qdisplayfeedback);
 143                      $qdisplayfeedback->set_feedbacktype(cc_qti_values::Response);
 144                      $qdisplayfeedback->set_linkrefid($respfeed[1][$resid]);
 145                  }
 146              }
 147          }
 148          // Success condition.
 149          // For all question types outside of the Essay question, scoring is done in a
 150          // single <respcondition> with a continue flag set to No. The outcome is always
 151          // a variable named SCORE which value must be set to 100 in case of correct answer.
 152          // Partial scores (not 0 or 100) are not supported.
 153          $qrespcondition = new cc_assesment_respconditiontype();
 154          $qrespcondition->set_title('Correct');
 155          $this->qresprocessing->add_respcondition($qrespcondition);
 156          $qrespcondition->enable_continue(false);
 157          $qsetvar = new cc_assignment_setvartype(100);
 158          $qrespcondition->add_setvar($qsetvar);
 159          // Define the condition for success.
 160          $qconditionvar = new cc_assignment_conditionvar();
 161          $qrespcondition->set_conditionvar($qconditionvar);
 162  
 163          foreach ($correct_responses as $coresponse) {
 164              $respc = $this->questions->nodeValue('answertext', $coresponse);
 165              $qvarequal = new cc_assignment_conditionvar_varequaltype($respc);
 166              $qconditionvar->set_varequal($qvarequal);
 167              $qvarequal->set_respident('response');
 168              $qvarequal->enable_case(false);
 169          }
 170  
 171          // Add incorrect handling.
 172          $qrespcondition = new cc_assesment_respconditiontype();
 173          $this->qresprocessing->add_respcondition($qrespcondition);
 174          $qrespcondition->enable_continue(false);
 175          // Define the condition for failure.
 176          $qconditionvar = new cc_assignment_conditionvar();
 177          $qrespcondition->set_conditionvar($qconditionvar);
 178          $qother = new cc_assignment_conditionvar_othertype();
 179          $qconditionvar->set_other($qother);
 180          $qsetvar = new cc_assignment_setvartype(0);
 181          $qrespcondition->add_setvar($qsetvar);
 182      }
 183  }