[ Index ]

PHP Cross Reference of moodle-2.8

title

Body

[close]

/question/type/calculatedmulti/ -> questiontype.php (source)

   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  /**
  18   * Question type class for the calculated multiple-choice question type.
  19   *
  20   * @package    qtype
  21   * @subpackage calculatedmulti
  22   * @copyright  2009 Pierre Pichet
  23   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   */
  25  
  26  
  27  defined('MOODLE_INTERNAL') || die();
  28  
  29  require_once($CFG->dirroot . '/question/type/multichoice/questiontype.php');
  30  require_once($CFG->dirroot . '/question/type/calculated/questiontype.php');
  31  
  32  
  33  /**
  34   * The calculated multiple-choice question type.
  35   *
  36   * @copyright  2009 Pierre Pichet
  37   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  38   */
  39  class qtype_calculatedmulti extends qtype_calculated {
  40  
  41      public function save_question_options($question) {
  42          global $CFG, $DB;
  43          $context = $question->context;
  44  
  45          // Make it impossible to save bad formulas anywhere.
  46          $this->validate_question_data($question);
  47  
  48          // Calculated options.
  49          $update = true;
  50          $options = $DB->get_record('question_calculated_options',
  51                  array('question' => $question->id));
  52          if (!$options) {
  53              $options = new stdClass();
  54              $options->question = $question->id;
  55              $options->correctfeedback = '';
  56              $options->partiallycorrectfeedback = '';
  57              $options->incorrectfeedback = '';
  58              $options->id = $DB->insert_record('question_calculated_options', $options);
  59          }
  60          $options->synchronize = $question->synchronize;
  61          $options->single = $question->single;
  62          $options->answernumbering = $question->answernumbering;
  63          $options->shuffleanswers = $question->shuffleanswers;
  64          $options = $this->save_combined_feedback_helper($options, $question, $context, true);
  65          $DB->update_record('question_calculated_options', $options);
  66  
  67          // Get old versions of the objects.
  68          if (!$oldanswers = $DB->get_records('question_answers',
  69                  array('question' => $question->id), 'id ASC')) {
  70              $oldanswers = array();
  71          }
  72          if (!$oldoptions = $DB->get_records('question_calculated',
  73                  array('question' => $question->id), 'answer ASC')) {
  74              $oldoptions = array();
  75          }
  76  
  77          // Insert all the new answers.
  78          foreach ($question->answer as $key => $answerdata) {
  79              if (is_array($answerdata)) {
  80                  $answerdata = $answerdata['text'];
  81              }
  82              if (trim($answerdata) == '') {
  83                  continue;
  84              }
  85  
  86              // Update an existing answer if possible.
  87              $answer = array_shift($oldanswers);
  88              if (!$answer) {
  89                  $answer = new stdClass();
  90                  $answer->question = $question->id;
  91                  $answer->answer   = '';
  92                  $answer->feedback = '';
  93                  $answer->id       = $DB->insert_record('question_answers', $answer);
  94              }
  95  
  96              if (is_array($answerdata)) {
  97                  // Doing an import.
  98                  $answer->answer = $this->import_or_save_files($answerdata,
  99                          $context, 'question', 'answer', $answer->id);
 100                  $answer->answerformat = $answerdata['format'];
 101              } else {
 102                  // Saving the form.
 103                  $answer->answer = $answerdata;
 104                  $answer->answerformat = FORMAT_HTML;
 105              }
 106              $answer->fraction = $question->fraction[$key];
 107              $answer->feedback = $this->import_or_save_files($question->feedback[$key],
 108                      $context, 'question', 'answerfeedback', $answer->id);
 109              $answer->feedbackformat = $question->feedback[$key]['format'];
 110  
 111              $DB->update_record("question_answers", $answer);
 112  
 113              // Set up the options object.
 114              if (!$options = array_shift($oldoptions)) {
 115                  $options = new stdClass();
 116              }
 117              $options->question            = $question->id;
 118              $options->answer              = $answer->id;
 119              $options->tolerance           = trim($question->tolerance[$key]);
 120              $options->tolerancetype       = trim($question->tolerancetype[$key]);
 121              $options->correctanswerlength = trim($question->correctanswerlength[$key]);
 122              $options->correctanswerformat = trim($question->correctanswerformat[$key]);
 123  
 124              // Save options.
 125              if (isset($options->id)) {
 126                  // Reusing existing record.
 127                  $DB->update_record('question_calculated', $options);
 128              } else {
 129                  // New options.
 130                  $DB->insert_record('question_calculated', $options);
 131              }
 132          }
 133  
 134          // Delete old answer records.
 135          if (!empty($oldanswers)) {
 136              foreach ($oldanswers as $oa) {
 137                  $DB->delete_records('question_answers', array('id' => $oa->id));
 138              }
 139          }
 140          if (!empty($oldoptions)) {
 141              foreach ($oldoptions as $oo) {
 142                  $DB->delete_records('question_calculated', array('id' => $oo->id));
 143              }
 144          }
 145  
 146          $this->save_hints($question, true);
 147  
 148          if (isset($question->import_process) && $question->import_process) {
 149              $this->import_datasets($question);
 150          }
 151          // Report any problems.
 152          if (!empty($result->notice)) {
 153              return $result;
 154          }
 155  
 156          return true;
 157      }
 158  
 159      protected function validate_answer($answer) {
 160          $error = qtype_calculated_find_formula_errors_in_text($answer);
 161          if ($error) {
 162              throw new coding_exception($error);
 163          }
 164      }
 165  
 166      protected function validate_question_data($question) {
 167          parent::validate_question_data($question);
 168          $this->validate_text($question->correctfeedback['text']);
 169          $this->validate_text($question->partiallycorrectfeedback['text']);
 170          $this->validate_text($question->incorrectfeedback['text']);
 171      }
 172  
 173      protected function make_question_instance($questiondata) {
 174          question_bank::load_question_definition_classes($this->name());
 175          if ($questiondata->options->single) {
 176              $class = 'qtype_calculatedmulti_single_question';
 177          } else {
 178              $class = 'qtype_calculatedmulti_multi_question';
 179          }
 180          return new $class();
 181      }
 182  
 183      protected function initialise_question_instance(question_definition $question, $questiondata) {
 184          question_type::initialise_question_instance($question, $questiondata);
 185  
 186          $question->shuffleanswers = $questiondata->options->shuffleanswers;
 187          $question->answernumbering = $questiondata->options->answernumbering;
 188          if (!empty($questiondata->options->layout)) {
 189              $question->layout = $questiondata->options->layout;
 190          } else {
 191              $question->layout = qtype_multichoice_single_question::LAYOUT_VERTICAL;
 192          }
 193  
 194          $question->synchronised = $questiondata->options->synchronize;
 195  
 196          $this->initialise_combined_feedback($question, $questiondata, true);
 197          $this->initialise_question_answers($question, $questiondata);
 198  
 199          foreach ($questiondata->options->answers as $a) {
 200              $question->answers[$a->id]->correctanswerlength = $a->correctanswerlength;
 201              $question->answers[$a->id]->correctanswerformat = $a->correctanswerformat;
 202          }
 203  
 204          $question->datasetloader = new qtype_calculated_dataset_loader($questiondata->id);
 205      }
 206  
 207      public function comment_header($question) {
 208          $strheader = '';
 209          $delimiter = '';
 210  
 211          $answers = $question->options->answers;
 212  
 213          foreach ($answers as $key => $answer) {
 214              $ans = shorten_text($answer->answer, 17, true);
 215              $strheader .= $delimiter.$ans;
 216              $delimiter = '<br/><br/>';
 217          }
 218          return $strheader;
 219      }
 220  
 221      public function comment_on_datasetitems($qtypeobj, $questionid, $questiontext,
 222              $answers, $data, $number) {
 223          global $DB;
 224          $comment = new stdClass();
 225          $comment->stranswers = array();
 226          $comment->outsidelimit = false;
 227          $comment->answers = array();
 228  
 229          $answers = fullclone($answers);
 230          $errors = '';
 231          $delimiter = ': ';
 232          foreach ($answers as $key => $answer) {
 233              $anssubstituted = $this->substitute_variables($answer->answer, $data);
 234              // Evaluate the equations i.e {=5+4).
 235              $anstext = '';
 236              $anstextremaining = $anssubstituted;
 237              while (preg_match('~\{=([^[:space:]}]*)}~', $anstextremaining, $regs1)) {
 238                  $anstextsplits = explode($regs1[0], $anstextremaining, 2);
 239                  $anstext =$anstext.$anstextsplits[0];
 240                  $anstextremaining = $anstextsplits[1];
 241                  if (empty($regs1[1])) {
 242                      $str = '';
 243                  } else {
 244                      if ($formulaerrors = qtype_calculated_find_formula_errors($regs1[1])) {
 245                          $str=$formulaerrors;
 246                      } else {
 247                          eval('$str = '.$regs1[1].';');
 248                      }
 249                  }
 250                  $anstext = $anstext.$str;
 251              }
 252              $anstext .= $anstextremaining;
 253              $comment->stranswers[$key] = $anssubstituted.'<br/>'.$anstext;
 254          }
 255          return fullclone($comment);
 256      }
 257  
 258      public function get_virtual_qtype() {
 259          return question_bank::get_qtype('multichoice');
 260      }
 261  
 262      public function get_possible_responses($questiondata) {
 263          if ($questiondata->options->single) {
 264              $responses = array();
 265  
 266              foreach ($questiondata->options->answers as $aid => $answer) {
 267                  $responses[$aid] = new question_possible_response($answer->answer,
 268                          $answer->fraction);
 269              }
 270  
 271              $responses[null] = question_possible_response::no_response();
 272              return array($questiondata->id => $responses);
 273          } else {
 274              $parts = array();
 275  
 276              foreach ($questiondata->options->answers as $aid => $answer) {
 277                  $parts[$aid] = array($aid =>
 278                          new question_possible_response($answer->answer, $answer->fraction));
 279              }
 280  
 281              return $parts;
 282          }
 283      }
 284  
 285      public function move_files($questionid, $oldcontextid, $newcontextid) {
 286          $fs = get_file_storage();
 287  
 288          parent::move_files($questionid, $oldcontextid, $newcontextid);
 289          $this->move_files_in_answers($questionid, $oldcontextid, $newcontextid, true);
 290          $this->move_files_in_hints($questionid, $oldcontextid, $newcontextid);
 291  
 292          $fs->move_area_files_to_new_context($oldcontextid,
 293                  $newcontextid, 'qtype_calculatedmulti', 'correctfeedback', $questionid);
 294          $fs->move_area_files_to_new_context($oldcontextid,
 295                  $newcontextid, 'qtype_calculatedmulti', 'partiallycorrectfeedback', $questionid);
 296          $fs->move_area_files_to_new_context($oldcontextid,
 297                  $newcontextid, 'qtype_calculatedmulti', 'incorrectfeedback', $questionid);
 298      }
 299  
 300      protected function delete_files($questionid, $contextid) {
 301          $fs = get_file_storage();
 302  
 303          parent::delete_files($questionid, $contextid);
 304          $this->delete_files_in_answers($questionid, $contextid, true);
 305          $this->delete_files_in_hints($questionid, $contextid);
 306  
 307          $fs->delete_area_files($contextid, 'qtype_calculatedmulti',
 308                  'correctfeedback', $questionid);
 309          $fs->delete_area_files($contextid, 'qtype_calculatedmulti',
 310                  'partiallycorrectfeedback', $questionid);
 311          $fs->delete_area_files($contextid, 'qtype_calculatedmulti',
 312                  'incorrectfeedback', $questionid);
 313      }
 314  }


Generated: Fri Nov 28 20:29:05 2014 Cross-referenced by PHPXref 0.7.1