mirror of
https://github.com/moodle/moodle.git
synced 2025-04-16 14:02:32 +02:00
Merge branch 'MDL-38792' of https://github.com/ppichet/moodle
This commit is contained in:
commit
f57832826b
@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
@ -47,12 +46,12 @@ class moodle1_qtype_calculated_handler extends moodle1_qtype_handler {
|
||||
*/
|
||||
public function process_question(array $data, array $raw) {
|
||||
|
||||
// convert and write the answers first
|
||||
// Convert and write the answers first.
|
||||
if (isset($data['answers'])) {
|
||||
$this->write_answers($data['answers'], $this->pluginname);
|
||||
}
|
||||
|
||||
// convert and write the numerical units and numerical options
|
||||
// Convert and write the numerical units and numerical options.
|
||||
if (isset($data['calculated'][0]['numerical_units'])) {
|
||||
$numericalunits = $data['calculated'][0]['numerical_units'];
|
||||
} else {
|
||||
@ -64,7 +63,7 @@ class moodle1_qtype_calculated_handler extends moodle1_qtype_handler {
|
||||
$this->write_numerical_units($numericalunits);
|
||||
$this->write_numerical_options($numericaloptions);
|
||||
|
||||
// write dataset_definitions
|
||||
// Write dataset_definitions.
|
||||
if (isset($data['calculated'][0]['dataset_definitions']['dataset_definition'])) {
|
||||
$datasetdefinitions = $data['calculated'][0]['dataset_definitions']['dataset_definition'];
|
||||
} else {
|
||||
@ -72,7 +71,7 @@ class moodle1_qtype_calculated_handler extends moodle1_qtype_handler {
|
||||
}
|
||||
$this->write_dataset_definitions($datasetdefinitions);
|
||||
|
||||
// write calculated_records
|
||||
// Write calculated_records.
|
||||
$this->xmlwriter->begin_tag('calculated_records');
|
||||
foreach ($data['calculated'] as $calculatedrecord) {
|
||||
$record = array(
|
||||
@ -87,7 +86,7 @@ class moodle1_qtype_calculated_handler extends moodle1_qtype_handler {
|
||||
}
|
||||
$this->xmlwriter->end_tag('calculated_records');
|
||||
|
||||
// write calculated_options
|
||||
// Write calculated_options.
|
||||
$options = array(
|
||||
'calculate_option' => array(
|
||||
'id' => $this->converter->get_nextid(),
|
||||
|
@ -38,31 +38,31 @@ class backup_qtype_calculated_plugin extends backup_qtype_plugin {
|
||||
*/
|
||||
protected function define_question_plugin_structure() {
|
||||
|
||||
// Define the virtual plugin element with the condition to fulfill
|
||||
// Define the virtual plugin element with the condition to fulfill.
|
||||
// Note: we use $this->pluginname so for extended plugins this will work
|
||||
// automatically: calculatedsimple and calculatedmulti
|
||||
// automatically: calculatedsimple and calculatedmulti.
|
||||
$plugin = $this->get_plugin_element(null, '../../qtype', $this->pluginname);
|
||||
|
||||
// Create one standard named plugin element (the visible container)
|
||||
// Create one standard named plugin element (the visible container).
|
||||
$pluginwrapper = new backup_nested_element($this->get_recommended_name());
|
||||
|
||||
// connect the visible container ASAP
|
||||
// Connect the visible container ASAP.
|
||||
$plugin->add_child($pluginwrapper);
|
||||
|
||||
// This qtype uses standard question_answers, add them here
|
||||
// to the tree before any other information that will use them
|
||||
// to the tree before any other information that will use them.
|
||||
$this->add_question_question_answers($pluginwrapper);
|
||||
|
||||
// This qtype uses standard numerical units, add them here
|
||||
// This qtype uses standard numerical units, add them here.
|
||||
$this->add_question_numerical_units($pluginwrapper);
|
||||
|
||||
// This qtype uses standard numerical options, add them here
|
||||
// This qtype uses standard numerical options, add them here.
|
||||
$this->add_question_numerical_options($pluginwrapper);
|
||||
|
||||
// This qtype uses standard datasets, add them here
|
||||
// This qtype uses standard datasets, add them here.
|
||||
$this->add_question_datasets($pluginwrapper);
|
||||
|
||||
// Now create the qtype own structures
|
||||
// Now create the qtype own structures.
|
||||
$calculatedrecords = new backup_nested_element('calculated_records');
|
||||
$calculatedrecord = new backup_nested_element('calculated_record', array('id'), array(
|
||||
'answer', 'tolerance', 'tolerancetype', 'correctanswerlength',
|
||||
@ -74,20 +74,20 @@ class backup_qtype_calculated_plugin extends backup_qtype_plugin {
|
||||
'correctfeedbackformat', 'partiallycorrectfeedback', 'partiallycorrectfeedbackformat',
|
||||
'incorrectfeedback', 'incorrectfeedbackformat', 'answernumbering'));
|
||||
|
||||
// Now the own qtype tree
|
||||
// Now the own qtype tree.
|
||||
$pluginwrapper->add_child($calculatedrecords);
|
||||
$calculatedrecords->add_child($calculatedrecord);
|
||||
|
||||
$pluginwrapper->add_child($calculatedoptions);
|
||||
$calculatedoptions->add_child($calculatedoption);
|
||||
|
||||
// set source to populate the data
|
||||
// Set source to populate the data.
|
||||
$calculatedrecord->set_source_table('question_calculated',
|
||||
array('question' => backup::VAR_PARENTID));
|
||||
$calculatedoption->set_source_table('question_calculated_options',
|
||||
array('question' => backup::VAR_PARENTID));
|
||||
|
||||
// don't need to annotate ids nor files
|
||||
// Don't need to annotate ids nor files.
|
||||
|
||||
return $plugin;
|
||||
}
|
||||
|
@ -41,17 +41,17 @@ class restore_qtype_calculated_plugin extends restore_qtype_plugin {
|
||||
|
||||
$paths = array();
|
||||
|
||||
// This qtype uses question_answers, add them
|
||||
// This qtype uses question_answers, add them.
|
||||
$this->add_question_question_answers($paths);
|
||||
|
||||
// This qtype uses question_numerical_options and question_numerical_units, add them
|
||||
// This qtype uses question_numerical_options and question_numerical_units, add them.
|
||||
$this->add_question_numerical_options($paths);
|
||||
$this->add_question_numerical_units($paths);
|
||||
|
||||
// This qtype uses question datasets, add them
|
||||
// This qtype uses question datasets, add them.
|
||||
$this->add_question_datasets($paths);
|
||||
|
||||
// Add own qtype stuff
|
||||
// Add own qtype stuff.
|
||||
$elename = 'calculated_record';
|
||||
$elepath = $this->get_pathfor('/calculated_records/calculated_record');
|
||||
$paths[] = new restore_path_element($elename, $elepath);
|
||||
@ -60,7 +60,7 @@ class restore_qtype_calculated_plugin extends restore_qtype_plugin {
|
||||
$elepath = $this->get_pathfor('/calculated_options/calculated_option');
|
||||
$paths[] = new restore_path_element($elename, $elepath);
|
||||
|
||||
return $paths; // And we return the interesting paths
|
||||
return $paths; // And we return the interesting paths.
|
||||
}
|
||||
|
||||
/**
|
||||
@ -72,19 +72,19 @@ class restore_qtype_calculated_plugin extends restore_qtype_plugin {
|
||||
$data = (object)$data;
|
||||
$oldid = $data->id;
|
||||
|
||||
// Detect if the question is created or mapped
|
||||
// Detect if the question is created or mapped.
|
||||
$oldquestionid = $this->get_old_parentid('question');
|
||||
$newquestionid = $this->get_new_parentid('question');
|
||||
$questioncreated = $this->get_mappingid('question_created', $oldquestionid) ?
|
||||
true : false;
|
||||
|
||||
// If the question has been created by restore, we need to create its
|
||||
// question_calculated too
|
||||
// question_calculated too.
|
||||
if ($questioncreated) {
|
||||
// Adjust some columns
|
||||
// Adjust some columns.
|
||||
$data->question = $newquestionid;
|
||||
$data->answer = $this->get_mappingid('question_answer', $data->answer);
|
||||
// Insert record
|
||||
// Insert record.
|
||||
$newitemid = $DB->insert_record('question_calculated', $data);
|
||||
}
|
||||
}
|
||||
@ -98,18 +98,18 @@ class restore_qtype_calculated_plugin extends restore_qtype_plugin {
|
||||
$data = (object)$data;
|
||||
$oldid = $data->id;
|
||||
|
||||
// Detect if the question is created or mapped
|
||||
// Detect if the question is created or mapped.
|
||||
$oldquestionid = $this->get_old_parentid('question');
|
||||
$newquestionid = $this->get_new_parentid('question');
|
||||
$questioncreated = $this->get_mappingid('question_created', $oldquestionid) ?
|
||||
true : false;
|
||||
|
||||
// If the question has been created by restore, we need to create its
|
||||
// question_calculated too
|
||||
// question_calculated too.
|
||||
if ($questioncreated) {
|
||||
// Adjust some columns
|
||||
// Adjust some columns.
|
||||
$data->question = $newquestionid;
|
||||
// Insert record
|
||||
// Insert record.
|
||||
$newitemid = $DB->insert_record('question_calculated_options', $data);
|
||||
}
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ class question_dataset_dependent_definitions_form extends question_wizard_form {
|
||||
$datadefscat = $this->qtypeobj->get_dataset_definitions_category($this->question);
|
||||
$datasetmenus = array();
|
||||
$label = "<div class='mdl-align'>".get_string('datasetrole', 'qtype_calculated')."</div>";
|
||||
// explaining the role of datasets so other strings can be shortened
|
||||
// Explaining the role of datasets so other strings can be shortened.
|
||||
$mform->addElement('html', $label);
|
||||
$mform->addElement('header', 'mandatoryhdr',
|
||||
get_string('mandatoryhdr', 'qtype_calculated'));
|
||||
@ -136,7 +136,7 @@ class question_dataset_dependent_definitions_form extends question_wizard_form {
|
||||
$key++;
|
||||
}
|
||||
}
|
||||
// temporary strings
|
||||
// Temporary strings.
|
||||
$mform->addElement('header', 'synchronizehdr',
|
||||
get_string('synchronize', 'qtype_calculated'));
|
||||
$mform->addElement('radio', 'synchronize', '',
|
||||
|
@ -80,7 +80,7 @@ class question_dataset_dependent_items_form extends question_wizard_form {
|
||||
}
|
||||
$this->category = $category;
|
||||
$this->categorycontext = context::instance_by_id($category->contextid);
|
||||
//get the dataset defintions for this question
|
||||
// Get the dataset defintions for this question.
|
||||
if (empty($question->id)) {
|
||||
$this->datasetdefs = $this->qtypeobj->get_dataset_definitions(
|
||||
$question->id, $SESSION->calculated->definitionform->dataset);
|
||||
@ -93,7 +93,7 @@ class question_dataset_dependent_items_form extends question_wizard_form {
|
||||
}
|
||||
|
||||
foreach ($this->datasetdefs as $datasetdef) {
|
||||
// Get maxnumber
|
||||
// Get maxnumber.
|
||||
if ($this->maxnumber == -1 || $datasetdef->itemcount < $this->maxnumber) {
|
||||
$this->maxnumber = $datasetdef->itemcount;
|
||||
}
|
||||
@ -108,8 +108,7 @@ class question_dataset_dependent_items_form extends question_wizard_form {
|
||||
}
|
||||
|
||||
protected function definition() {
|
||||
$labelsharedwildcard = get_string("sharedwildcard", "qtype_calculated");
|
||||
|
||||
$labelsharedwildcard = get_string("sharedwildcard", "qtype_calculated");
|
||||
$mform =& $this->_form;
|
||||
$mform->setDisableShortforms();
|
||||
|
||||
@ -124,7 +123,7 @@ class question_dataset_dependent_items_form extends question_wizard_form {
|
||||
$html2 = $this->qtypeobj->print_dataset_definitions_category_shared(
|
||||
$this->question, $this->datasetdefs);
|
||||
$mform->addElement('static', 'listcategory', $label, $html2);
|
||||
//----------------------------------------------------------------------
|
||||
// ...----------------------------------------------------------------------.
|
||||
$mform->addElement('submit', 'updatedatasets',
|
||||
get_string('updatedatasetparam', 'qtype_calculated'));
|
||||
$mform->registerNoSubmitButton('updatedatasets');
|
||||
@ -269,7 +268,7 @@ class question_dataset_dependent_items_form extends question_wizard_form {
|
||||
$mform->addGroup($addgrp1, 'addgrp1', '', ' ', false);
|
||||
$mform->registerNoSubmitButton('showbutton');
|
||||
$mform->closeHeaderBefore('addgrp1');
|
||||
//----------------------------------------------------------------------
|
||||
// ...----------------------------------------------------------------------.
|
||||
$j = $this->noofitems * count($this->datasetdefs);
|
||||
$k = optional_param('selectshow', 1, PARAM_INT);
|
||||
for ($i = $this->noofitems; $i >= 1; $i--) {
|
||||
@ -301,9 +300,9 @@ class question_dataset_dependent_items_form extends question_wizard_form {
|
||||
$j--;
|
||||
}
|
||||
if ('' != $strquestionlabel && ($k > 0 )) {
|
||||
//|| $this->outsidelimit || !empty($this->numbererrors )
|
||||
// ... $this->outsidelimit || !empty($this->numbererrors ).
|
||||
$repeated[] = $mform->addElement('static', "answercomment[$i]", $strquestionlabel);
|
||||
// decode equations in question text
|
||||
// Decode equations in question text.
|
||||
$qtext = $this->qtypeobj->substitute_variables(
|
||||
$this->question->questiontext, $data);
|
||||
$textequations = $this->qtypeobj->find_math_equations($qtext);
|
||||
@ -326,8 +325,8 @@ class question_dataset_dependent_items_form extends question_wizard_form {
|
||||
|
||||
}
|
||||
$mform->addElement('static', 'outsidelimit', '', '');
|
||||
//----------------------------------------------------------------------
|
||||
// Non standard name for button element needed so not using add_action_buttons
|
||||
// ...----------------------------------------------------------------------
|
||||
// Non standard name for button element needed so not using add_action_buttons.
|
||||
if (!($this->noofitems==0) ) {
|
||||
$mform->addElement('submit', 'savechanges', get_string('savechanges'));
|
||||
$mform->closeHeaderBefore('savechanges');
|
||||
@ -387,7 +386,7 @@ class question_dataset_dependent_items_form extends question_wizard_form {
|
||||
}
|
||||
}
|
||||
}
|
||||
//fill out all data sets and also the fields for the next item to add.
|
||||
// Fill out all data sets and also the fields for the next item to add.
|
||||
$j = $this->noofitems * count($this->datasetdefs);
|
||||
for ($itemnumber = $this->noofitems; $itemnumber >= 1; $itemnumber--) {
|
||||
$data = array();
|
||||
@ -416,8 +415,8 @@ class question_dataset_dependent_items_form extends question_wizard_form {
|
||||
$formdata['selectdelete'] = '1';
|
||||
$formdata['selectadd'] = '1';
|
||||
$j = $this->noofitems * count($this->datasetdefs)+1;
|
||||
$data = array(); // data for comment_on_datasetitems later
|
||||
//dataset generation dafaults
|
||||
$data = array(); // Data for comment_on_datasetitems later.
|
||||
// Dataset generation defaults.
|
||||
if ($this->qtypeobj->supports_dataset_item_generation()) {
|
||||
$itemnumber = $this->noofitems+1;
|
||||
foreach ($this->datasetdefs as $defid => $datasetdef) {
|
||||
@ -436,7 +435,7 @@ class question_dataset_dependent_items_form extends question_wizard_form {
|
||||
}
|
||||
}
|
||||
|
||||
//existing records override generated data depending on radio element
|
||||
// Existing records override generated data depending on radio element.
|
||||
$j = $this->noofitems * count($this->datasetdefs) + 1;
|
||||
if (!$this->regenerate && !optional_param('updatedatasets', false, PARAM_BOOL) &&
|
||||
!optional_param('updateanswers', false, PARAM_BOOL)) {
|
||||
|
@ -36,17 +36,14 @@ function xmldb_qtype_calculated_upgrade($oldversion) {
|
||||
|
||||
$dbman = $DB->get_manager();
|
||||
|
||||
|
||||
// Moodle v2.2.0 release upgrade line
|
||||
// Put any upgrade step following this
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Moodle v2.3.0 release upgrade line
|
||||
// Put any upgrade step following this
|
||||
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Moodle v2.4.0 release upgrade line
|
||||
// Put any upgrade step following this
|
||||
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ class qtype_calculated_qe2_attempt_updater extends question_qtype_attempt_update
|
||||
protected function parse_response($state) {
|
||||
if (strpos($state->answer, '-') < 7) {
|
||||
// Broken state, skip it.
|
||||
throw new coding_exception("Brokes state {$state->id} for calcluated
|
||||
throw new coding_exception("Brokes state {$state->id} for calculated
|
||||
question {$state->question}. (It did not specify a dataset.");
|
||||
}
|
||||
list($datasetbit, $realanswer) = explode('-', $state->answer, 2);
|
||||
@ -92,7 +92,7 @@ class qtype_calculated_qe2_attempt_updater extends question_qtype_attempt_update
|
||||
if (is_null($this->selecteditem)) {
|
||||
$this->load_dataset($selecteditem);
|
||||
} else if ($this->selecteditem != $selecteditem) {
|
||||
$this->logger->log_assumption("Different states for calcluated question
|
||||
$this->logger->log_assumption("Different states for calculated question
|
||||
{$state->question} used different dataset items. Ignoring the change
|
||||
in state {$state->id} and coninuting to use item {$this->selecteditem}.");
|
||||
}
|
||||
@ -248,7 +248,7 @@ class qtype_calculated_qe2_attempt_updater extends question_qtype_attempt_update
|
||||
* @return float the computed result.
|
||||
*/
|
||||
protected function calculate_raw($expression) {
|
||||
// This validation trick from http://php.net/manual/en/function.eval.php
|
||||
// This validation trick from http://php.net/manual/en/function.eval.php.
|
||||
if (!@eval('return true; $result = ' . $expression . ';')) {
|
||||
return '[Invalid expression ' . $expression . ']';
|
||||
}
|
||||
|
@ -147,7 +147,7 @@ class qtype_calculated_edit_form extends qtype_numerical_edit_form {
|
||||
$mform->createElement('submit', $addfieldsname, $addstring), 'listcategory');
|
||||
$mform->registerNoSubmitButton('createoptionbutton');
|
||||
|
||||
// Editing as regular.
|
||||
// Editing as regular question.
|
||||
$mform->setType('single', PARAM_INT);
|
||||
|
||||
$mform->addElement('hidden', 'shuffleanswers', '1');
|
||||
|
@ -315,7 +315,7 @@ class qtype_calculated_variable_substituter {
|
||||
*/
|
||||
public function format_float($x, $length = null, $format = null) {
|
||||
if (!is_null($length) && !is_null($format)) {
|
||||
if ($format == 1) {
|
||||
if ($format == '1' ) { // Answer is to have $length decimals.
|
||||
// Decimal places.
|
||||
$x = sprintf('%.' . $length . 'F', $x);
|
||||
} else if ($format == 2) {
|
||||
@ -351,7 +351,7 @@ class qtype_calculated_variable_substituter {
|
||||
* @return float the computed result.
|
||||
*/
|
||||
protected function calculate_raw($expression) {
|
||||
// This validation trick from http://php.net/manual/en/function.eval.php
|
||||
// This validation trick from http://php.net/manual/en/function.eval.php .
|
||||
if (!@eval('return true; $result = ' . $expression . ';')) {
|
||||
throw new moodle_exception('illegalformulasyntax', 'qtype_calculated', '', $expression);
|
||||
}
|
||||
@ -404,14 +404,14 @@ class qtype_calculated_variable_substituter {
|
||||
*/
|
||||
public function get_formula_errors($formula) {
|
||||
// Validates the formula submitted from the question edit page.
|
||||
// Returns false if everything is alright.
|
||||
// Otherwise it constructs an error message
|
||||
// Strip away dataset names
|
||||
// Returns false if everything is alright
|
||||
// otherwise it constructs an error message.
|
||||
// Strip away dataset names.
|
||||
while (preg_match('~\\{[[:alpha:]][^>} <{"\']*\\}~', $formula, $regs)) {
|
||||
$formula = str_replace($regs[0], '1', $formula);
|
||||
}
|
||||
|
||||
// Strip away empty space and lowercase it
|
||||
// Strip away empty space and lowercase it.
|
||||
$formula = strtolower(str_replace(' ', '', $formula));
|
||||
|
||||
$safeoperatorchar = '-+/*%>:^\~<?=&|!'; /* */
|
||||
@ -421,21 +421,21 @@ class qtype_calculated_variable_substituter {
|
||||
"\\(($operatorornumber+(,$operatorornumber+((,$operatorornumber+)+)?)?)?\\)~",
|
||||
$formula, $regs)) {
|
||||
switch ($regs[2]) {
|
||||
// Simple parenthesis
|
||||
// Simple parenthesis.
|
||||
case '':
|
||||
if ((isset($regs[4]) && $regs[4]) || strlen($regs[3]) == 0) {
|
||||
return get_string('illegalformulasyntax', 'qtype_calculated', $regs[0]);
|
||||
}
|
||||
break;
|
||||
|
||||
// Zero argument functions
|
||||
// Zero argument functions.
|
||||
case 'pi':
|
||||
if ($regs[3]) {
|
||||
return get_string('functiontakesnoargs', 'qtype_calculated', $regs[2]);
|
||||
}
|
||||
break;
|
||||
|
||||
// Single argument functions (the most common case)
|
||||
// Single argument functions (the most common case).
|
||||
case 'abs': case 'acos': case 'acosh': case 'asin': case 'asinh':
|
||||
case 'atan': case 'atanh': case 'bindec': case 'ceil': case 'cos':
|
||||
case 'cosh': case 'decbin': case 'decoct': case 'deg2rad':
|
||||
@ -448,7 +448,7 @@ class qtype_calculated_variable_substituter {
|
||||
}
|
||||
break;
|
||||
|
||||
// Functions that take one or two arguments
|
||||
// Functions that take one or two arguments.
|
||||
case 'log': case 'round':
|
||||
if (!empty($regs[5]) || empty($regs[3])) {
|
||||
return get_string('functiontakesoneortwoargs', 'qtype_calculated',
|
||||
@ -456,14 +456,14 @@ class qtype_calculated_variable_substituter {
|
||||
}
|
||||
break;
|
||||
|
||||
// Functions that must have two arguments
|
||||
// Functions that must have two arguments.
|
||||
case 'atan2': case 'fmod': case 'pow':
|
||||
if (!empty($regs[5]) || empty($regs[4])) {
|
||||
return get_string('functiontakestwoargs', 'qtype_calculated', $regs[2]);
|
||||
}
|
||||
break;
|
||||
|
||||
// Functions that take two or more arguments
|
||||
// Functions that take two or more arguments.
|
||||
case 'min': case 'max':
|
||||
if (empty($regs[4])) {
|
||||
return get_string('functiontakesatleasttwo', 'qtype_calculated', $regs[2]);
|
||||
@ -474,13 +474,13 @@ class qtype_calculated_variable_substituter {
|
||||
return get_string('unsupportedformulafunction', 'qtype_calculated', $regs[2]);
|
||||
}
|
||||
|
||||
// Exchange the function call with '1' and then chack for
|
||||
// another function call...
|
||||
// Exchange the function call with '1' and then check for another function call.
|
||||
|
||||
if ($regs[1]) {
|
||||
// The function call is proceeded by an operator
|
||||
// The function call is proceeded by an operator.
|
||||
$formula = str_replace($regs[0], $regs[1] . '1', $formula);
|
||||
} else {
|
||||
// The function call starts the formula
|
||||
// The function call starts the formula.
|
||||
$formula = preg_replace("~^$regs[2]\\([^)]*\\)~", '1', $formula);
|
||||
}
|
||||
}
|
||||
@ -488,7 +488,7 @@ class qtype_calculated_variable_substituter {
|
||||
if (preg_match("~[^$safeoperatorchar.0-9eE]+~", $formula, $regs)) {
|
||||
return get_string('illegalformulasyntax', 'qtype_calculated', $regs[0]);
|
||||
} else {
|
||||
// Formula just might be valid
|
||||
// Formula just might be valid.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -57,11 +57,11 @@ class restore_qtype_calculatedmulti_plugin extends restore_qtype_calculated_plug
|
||||
public function recode_legacy_state_answer($state) {
|
||||
$answer = $state->answer;
|
||||
$result = '';
|
||||
// datasetxx-yy:zz format
|
||||
// Datasetxx-yy:zz format.
|
||||
if (preg_match('~^dataset([0-9]+)-(.*)$~', $answer, $matches)) {
|
||||
$itemid = $matches[1];
|
||||
$subanswer = $matches[2];
|
||||
// Delegate subanswer recode to multichoice qtype, faking one question_states record
|
||||
// Delegate subanswer recode to multichoice qtype, faking one question_states record.
|
||||
$substate = new stdClass();
|
||||
$substate->answer = $subanswer;
|
||||
$newanswer = $this->step->restore_recode_legacy_answer($substate, 'multichoice');
|
||||
|
@ -272,7 +272,7 @@ class qtype_calculatedmulti_qe2_attempt_updater extends question_qtype_attempt_u
|
||||
* @return float the computed result.
|
||||
*/
|
||||
protected function calculate_raw($expression) {
|
||||
// This validation trick from http://php.net/manual/en/function.eval.php
|
||||
// This validation trick from http://php.net/manual/en/function.eval.php.
|
||||
if (!@eval('return true; $result = ' . $expression . ';')) {
|
||||
return '[Invalid expression ' . $expression . ']';
|
||||
}
|
||||
|
@ -158,7 +158,6 @@ class qtype_calculatedmulti_edit_form extends question_edit_form {
|
||||
$mform->addHelpButton('answeroptions[0]', 'answeroptions', 'qtype_calculatedmulti');
|
||||
|
||||
$repeated = array();
|
||||
// if ($this->editasmultichoice == 1) {
|
||||
$nounits = optional_param('nounits', 1, PARAM_INT);
|
||||
$mform->addElement('hidden', 'nounits', $nounits);
|
||||
$mform->setType('nounits', PARAM_INT);
|
||||
|
@ -42,7 +42,7 @@ class qtype_calculatedmulti extends qtype_calculated {
|
||||
global $CFG, $DB;
|
||||
$context = $question->context;
|
||||
|
||||
// Calculated options
|
||||
// Calculated options.
|
||||
$update = true;
|
||||
$options = $DB->get_record('question_calculated_options',
|
||||
array('question' => $question->id));
|
||||
@ -61,7 +61,7 @@ class qtype_calculatedmulti extends qtype_calculated {
|
||||
$options = $this->save_combined_feedback_helper($options, $question, $context, true);
|
||||
$DB->update_record('question_calculated_options', $options);
|
||||
|
||||
// Get old versions of the objects
|
||||
// Get old versions of the objects.
|
||||
if (!$oldanswers = $DB->get_records('question_answers',
|
||||
array('question' => $question->id), 'id ASC')) {
|
||||
$oldanswers = array();
|
||||
@ -71,7 +71,7 @@ class qtype_calculatedmulti extends qtype_calculated {
|
||||
$oldoptions = array();
|
||||
}
|
||||
|
||||
// Insert all the new answers
|
||||
// Insert all the new answers.
|
||||
if (isset($question->answer) && !isset($question->answers)) {
|
||||
$question->answers = $question->answer;
|
||||
}
|
||||
@ -94,12 +94,12 @@ class qtype_calculatedmulti extends qtype_calculated {
|
||||
}
|
||||
|
||||
if (is_array($answerdata)) {
|
||||
// Doing an import
|
||||
// Doing an import.
|
||||
$answer->answer = $this->import_or_save_files($answerdata,
|
||||
$context, 'question', 'answer', $answer->id);
|
||||
$answer->answerformat = $answerdata['format'];
|
||||
} else {
|
||||
// Saving the form
|
||||
// Saving the form.
|
||||
$answer->answer = $answerdata;
|
||||
$answer->answerformat = FORMAT_HTML;
|
||||
}
|
||||
@ -110,7 +110,7 @@ class qtype_calculatedmulti extends qtype_calculated {
|
||||
|
||||
$DB->update_record("question_answers", $answer);
|
||||
|
||||
// Set up the options object
|
||||
// Set up the options object.
|
||||
if (!$options = array_shift($oldoptions)) {
|
||||
$options = new stdClass();
|
||||
}
|
||||
@ -121,17 +121,17 @@ class qtype_calculatedmulti extends qtype_calculated {
|
||||
$options->correctanswerlength = trim($question->correctanswerlength[$key]);
|
||||
$options->correctanswerformat = trim($question->correctanswerformat[$key]);
|
||||
|
||||
// Save options
|
||||
// Save options.
|
||||
if (isset($options->id)) {
|
||||
// reusing existing record
|
||||
// Reusing existing record.
|
||||
$DB->update_record('question_calculated', $options);
|
||||
} else {
|
||||
// new options
|
||||
// New options.
|
||||
$DB->insert_record('question_calculated', $options);
|
||||
}
|
||||
}
|
||||
|
||||
// delete old answer records
|
||||
// Delete old answer records.
|
||||
if (!empty($oldanswers)) {
|
||||
foreach ($oldanswers as $oa) {
|
||||
$DB->delete_records('question_answers', array('id' => $oa->id));
|
||||
@ -220,7 +220,7 @@ class qtype_calculatedmulti extends qtype_calculated {
|
||||
$delimiter = ': ';
|
||||
foreach ($answers as $key => $answer) {
|
||||
$answer->answer = $this->substitute_variables($answer->answer, $data);
|
||||
//evaluate the equations i.e {=5+4)
|
||||
// Evaluate the equations i.e {=5+4).
|
||||
$qtext = '';
|
||||
$qtextremaining = $answer->answer;
|
||||
while (preg_match('~\{=([^[:space:]}]*)}~', $qtextremaining, $regs1)) {
|
||||
|
@ -46,7 +46,7 @@ class qtype_calculatedmulti_test_helper extends question_test_helper {
|
||||
* @return qtype_calculatedmulti_question
|
||||
*/
|
||||
public function make_calculatedmulti_question_sum() {
|
||||
// TODO
|
||||
// TODO.
|
||||
question_bank::load_question_definition_classes('calculated');
|
||||
$q = new qtype_calculatedmulti_question();
|
||||
test_question_maker::initialise_a_question($q);
|
||||
|
@ -74,15 +74,15 @@ class qtype_calculatedsimple_edit_form extends qtype_calculated_edit_form {
|
||||
$this->question = $question;
|
||||
|
||||
$this->qtypeobj = question_bank::get_qtype($this->question->qtype);
|
||||
// get the dataset definitions for this question
|
||||
// coming here everytime even when using a NoSubmitButton
|
||||
// so this will only set the values to the actual question database content
|
||||
// which is not what we want so this should be removed from here
|
||||
// get priority to paramdatasets
|
||||
// Get the dataset definitions for this question.
|
||||
// Coming here everytime even when using a NoSubmitButton.
|
||||
// This will only set the values to the actual question database content
|
||||
// which is not what we want, so this should be removed from here.
|
||||
// Get priority to paramdatasets.
|
||||
|
||||
$this->reload = optional_param('reload', false, PARAM_BOOL);
|
||||
if (!$this->reload) { // use database data as this is first pass
|
||||
// question->id == 0 so no stored datasets
|
||||
if (!$this->reload) { // Use database data as this is first pass
|
||||
// Question->id == 0 so no stored datasets.
|
||||
if (!empty($question->id)) {
|
||||
|
||||
$this->datasetdefs = $this->qtypeobj->get_dataset_definitions(
|
||||
@ -90,7 +90,7 @@ class qtype_calculatedsimple_edit_form extends qtype_calculated_edit_form {
|
||||
|
||||
if (!empty($this->datasetdefs)) {
|
||||
foreach ($this->datasetdefs as $defid => $datasetdef) {
|
||||
// first get the items in case their number does not correspond to itemcount
|
||||
// First get the items in case their number does not correspond to itemcount.
|
||||
if (isset($datasetdef->id)) {
|
||||
$this->datasetdefs[$defid]->items =
|
||||
$this->qtypeobj->get_database_dataset_items($datasetdef->id);
|
||||
@ -100,7 +100,7 @@ class qtype_calculatedsimple_edit_form extends qtype_calculated_edit_form {
|
||||
$datasetdef->itemcount = 0;
|
||||
}
|
||||
}
|
||||
// Get maxnumber
|
||||
// Get maxnumber.
|
||||
if ($this->maxnumber == -1 || $datasetdef->itemcount < $this->maxnumber) {
|
||||
$this->maxnumber = $datasetdef->itemcount;
|
||||
}
|
||||
@ -118,34 +118,34 @@ class qtype_calculatedsimple_edit_form extends qtype_calculated_edit_form {
|
||||
$newdatasetvalues = false;
|
||||
$newdataset = false;
|
||||
} else {
|
||||
// handle reload to get values from the form-elements
|
||||
// Handle reload to get values from the form-elements
|
||||
// answers, datasetdefs and data_items. In any case the validation
|
||||
// step will warn the user of any error in settings the values.
|
||||
// Verification for the specific dataset values as the other parameters
|
||||
// unints, feeedback etc are handled elsewhere
|
||||
// handle request buttons :
|
||||
// 'analyzequestion' (Identify the wild cards {x..} present in answers)
|
||||
// 'addbutton' (create new set of datatitems)
|
||||
// 'updatedatasets' is handled automatically on each reload
|
||||
// units, feeedback etc are handled elsewhere.
|
||||
// Handle request buttons :
|
||||
// 'analyzequestion' (Identify the wild cards {x..} present in answers).
|
||||
// 'addbutton' (create new set of datatitems).
|
||||
// 'updatedatasets' is handled automatically on each reload.
|
||||
// The analyzequestion is done every time on reload
|
||||
// to detect any new wild cards so that the current display reflects
|
||||
// the mandatory (i.e. in answers) datasets
|
||||
// to implement : don't do any changes if the question is used in a quiz.
|
||||
// the mandatory (i.e. in answers) datasets.
|
||||
// To implement : don't do any changes if the question is used in a quiz.
|
||||
// If new datadef, new properties should erase items.
|
||||
// Most of the data
|
||||
// most of the data.
|
||||
$datasettoremove = false;
|
||||
$newdatasetvalues = false;
|
||||
$newdataset = false;
|
||||
$dummyform = new stdClass();
|
||||
$mandatorydatasets = array();
|
||||
// should not test on adding a new answer
|
||||
// should test if there are already olddatasets or if the 'analyzequestion'
|
||||
// submit button has been clicked
|
||||
// Should not test on adding a new answer.
|
||||
// Should test if there are already olddatasets or if the 'analyzequestion'.
|
||||
// submit button has been clicked.
|
||||
if (optional_param_array('datasetdef', false, PARAM_BOOL) ||
|
||||
optional_param('analyzequestion', false, PARAM_BOOL)) {
|
||||
|
||||
if ($dummyform->answer = optional_param_array('answer', '', PARAM_NOTAGS)) {
|
||||
// there is always at least one answer...
|
||||
// There is always at least one answer...
|
||||
$fraction = optional_param_array('fraction', '', PARAM_FLOAT);
|
||||
$tolerance = optional_param_array('tolerance', '', PARAM_FLOAT);
|
||||
$tolerancetype = optional_param_array('tolerancetype', '', PARAM_FLOAT);
|
||||
@ -153,7 +153,7 @@ class qtype_calculatedsimple_edit_form extends qtype_calculated_edit_form {
|
||||
$correctanswerformat = optional_param_array('correctanswerformat', '', PARAM_INT);
|
||||
|
||||
foreach ($dummyform->answer as $key => $answer) {
|
||||
if (trim($answer) != '') { // just look for non-empty
|
||||
if (trim($answer) != '') { // Just look for non-empty.
|
||||
$this->answer[$key] = new stdClass();
|
||||
$this->answer[$key]->answer = $answer;
|
||||
$this->answer[$key]->fraction = $fraction[$key];
|
||||
@ -167,7 +167,7 @@ class qtype_calculatedsimple_edit_form extends qtype_calculated_edit_form {
|
||||
}
|
||||
}
|
||||
$this->datasetdefs = array();
|
||||
// rebuild datasetdefs from old values
|
||||
// Rebuild datasetdefs from old values.
|
||||
if ($olddef = optional_param_array('datasetdef', '', PARAM_RAW)) {
|
||||
$calcmin = optional_param_array('calcmin', '', PARAM_FLOAT);
|
||||
$calclength = optional_param_array('calclength', '', PARAM_INT);
|
||||
@ -184,7 +184,7 @@ class qtype_calculatedsimple_edit_form extends qtype_calculated_edit_form {
|
||||
$this->datasetdefs[$def]->calcmin = $calcmin[$key];
|
||||
$this->datasetdefs[$def]->calcmax = $calcmax[$key];
|
||||
$this->datasetdefs[$def]->calclength = $calclength[$key];
|
||||
//then compare with new values
|
||||
// Then compare with new values.
|
||||
if (preg_match('~^(uniform|loguniform):([^:]*):([^:]*):([0-9]*)$~',
|
||||
$this->datasetdefs[$def]->options, $regs)) {
|
||||
if ($this->datasetdefs[$def]->calcmin != $regs[2]||
|
||||
@ -199,7 +199,7 @@ class qtype_calculatedsimple_edit_form extends qtype_calculated_edit_form {
|
||||
$this->datasetdefs[$def]->calclength;
|
||||
}
|
||||
}
|
||||
// detect new datasets
|
||||
// Detect new datasets.
|
||||
$newdataset = false;
|
||||
foreach ($mandatorydatasets as $datasetname) {
|
||||
if (!isset($this->datasetdefs["1-0-$datasetname"])) {
|
||||
@ -214,7 +214,7 @@ class qtype_calculatedsimple_edit_form extends qtype_calculated_edit_form {
|
||||
$this->datasetdefs["1-0-$datasetname"]->name = $datasetname;
|
||||
}
|
||||
}
|
||||
// remove obsolete datasets
|
||||
// Remove obsolete datasets.
|
||||
$datasettoremove = false;
|
||||
foreach ($this->datasetdefs as $defkey => $datasetdef) {
|
||||
if (!isset($datasetdef->name)) {
|
||||
@ -223,10 +223,10 @@ class qtype_calculatedsimple_edit_form extends qtype_calculated_edit_form {
|
||||
}
|
||||
}
|
||||
}
|
||||
} // handle reload
|
||||
// create items if $newdataset and noofitems > 0 and !$newdatasetvalues
|
||||
// eliminate any items if $newdatasetvalues
|
||||
// eliminate any items if $datasettoremove, $newdataset, $newdatasetvalues
|
||||
} // Handle reload.
|
||||
// Create items if $newdataset and noofitems > 0 and !$newdatasetvalues.
|
||||
// Eliminate any items if $newdatasetvalues.
|
||||
// Eliminate any items if $datasettoremove, $newdataset, $newdatasetvalues.
|
||||
if ($datasettoremove ||$newdataset ||$newdatasetvalues) {
|
||||
foreach ($this->datasetdefs as $defkey => $datasetdef) {
|
||||
$datasetdef->itemcount = 0;
|
||||
@ -235,7 +235,7 @@ class qtype_calculatedsimple_edit_form extends qtype_calculated_edit_form {
|
||||
}
|
||||
$maxnumber = -1;
|
||||
if (optional_param('addbutton', false, PARAM_BOOL)) {
|
||||
$maxnumber = optional_param('selectadd', '', PARAM_INT); //FIXME: sloppy coding
|
||||
$maxnumber = optional_param('selectadd', '', PARAM_INT); // FIXME: sloppy coding.
|
||||
foreach ($this->datasetdefs as $defid => $datasetdef) {
|
||||
$datasetdef->itemcount = $maxnumber;
|
||||
unset($datasetdef->items);
|
||||
@ -250,7 +250,7 @@ class qtype_calculatedsimple_edit_form extends qtype_calculated_edit_form {
|
||||
}
|
||||
$this->maxnumber = $maxnumber;
|
||||
} else {
|
||||
// Handle reload dataset items
|
||||
// Handle reload dataset items.
|
||||
if (optional_param_array('definition', '', PARAM_NOTAGS) &&
|
||||
!($datasettoremove ||$newdataset ||$newdatasetvalues)) {
|
||||
$i = 1;
|
||||
@ -310,7 +310,7 @@ class qtype_calculatedsimple_edit_form extends qtype_calculated_edit_form {
|
||||
$label = "<div class='mdl-align'></div><div class='mdl-align'>" .
|
||||
get_string('wildcardrole', 'qtype_calculatedsimple') . "</div>";
|
||||
$mform->addElement('html', "<div class='mdl-align'> </div>");
|
||||
// explaining the role of datasets so other strings can be shortened
|
||||
// Explaining the role of datasets so other strings can be shortened.
|
||||
$mform->addElement('html', $label);
|
||||
|
||||
$mform->addElement('submit', 'analyzequestion',
|
||||
@ -323,13 +323,13 @@ class qtype_calculatedsimple_edit_form extends qtype_calculated_edit_form {
|
||||
} else {
|
||||
$this->noofitems = 0;
|
||||
}
|
||||
if (!empty($this->datasetdefs)) {//So there are some datadefs
|
||||
// we put them on the page
|
||||
if (!empty($this->datasetdefs)) {// So there are some datadefs.
|
||||
// We put them on the page.
|
||||
$key = 0;
|
||||
$mform->addElement('header', 'additemhdr',
|
||||
get_string('wildcardparam', 'qtype_calculatedsimple'));
|
||||
$idx = 1;
|
||||
if (!empty($this->datasetdefs)) {// unnecessary test
|
||||
if (!empty($this->datasetdefs)) {// Unnecessary test.
|
||||
$j = (($this->noofitems) * count($this->datasetdefs))+1;//
|
||||
foreach ($this->datasetdefs as $defkey => $datasetdef) {
|
||||
$mform->addElement('static', "na[$j]",
|
||||
@ -344,8 +344,8 @@ class qtype_calculatedsimple_edit_form extends qtype_calculated_edit_form {
|
||||
$j++;
|
||||
}
|
||||
}
|
||||
//this should be done before the elements are created and stored as $this->formdata;
|
||||
//fill out all data sets and also the fields for the next item to add.
|
||||
// This should be done before the elements are created and stored as $this->formdata.
|
||||
// Fill out all data sets and also the fields for the next item to add.
|
||||
/*Here we do already the values error analysis so that
|
||||
* we could force all wild cards values display if there is an error in values.
|
||||
* as using a , in a number */
|
||||
@ -382,7 +382,7 @@ class qtype_calculatedsimple_edit_form extends qtype_calculated_edit_form {
|
||||
get_string('notvalidnumber', 'qtype_calculated', $a);
|
||||
$numbererrors .= $this->numbererrors['number['.$j.']']."<br />";
|
||||
}
|
||||
} else if (stristr($number, 'x')) { // hexa will pass the test
|
||||
} else if (stristr($number, 'x')) { // Hexa will pass the test.
|
||||
$a = new stdClass();
|
||||
$a->name = '{'.$datasetdef->name.'}';
|
||||
$a->value = $datasetdef->items[$itemnumber]->value;
|
||||
@ -427,7 +427,7 @@ class qtype_calculatedsimple_edit_form extends qtype_calculated_edit_form {
|
||||
$this->formdata['selectdelete'] = '1';
|
||||
$this->formdata['selectadd'] = '1';
|
||||
$j = $this->noofitems * count($this->datasetdefs)+1;
|
||||
$data = array(); // data for comment_on_datasetitems later
|
||||
$data = array(); // Data for comment_on_datasetitems later.
|
||||
$idx = 1;
|
||||
foreach ($this->datasetdefs as $defid => $datasetdef) {
|
||||
$this->formdata["datasetdef[$idx]"] = $defid;
|
||||
@ -488,7 +488,7 @@ class qtype_calculatedsimple_edit_form extends qtype_calculated_edit_form {
|
||||
$mform->registerNoSubmitButton('updatedatasets');
|
||||
$mform->setAdvanced("updatedatasets", true);
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// ...--------------------------------------------------------------.
|
||||
$j = $this->noofitems * count($this->datasetdefs);
|
||||
$k = optional_param('selectshow', 1, PARAM_INT);
|
||||
|
||||
@ -538,9 +538,9 @@ class qtype_calculatedsimple_edit_form extends qtype_calculated_edit_form {
|
||||
$mform->closeHeaderBefore('warningnowildcards');
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Non standard name for button element needed so not using add_action_buttons
|
||||
// hidden elements
|
||||
// ...----------------------------------------------------------------------.
|
||||
// Non standard name for button element needed so not using add_action_buttons.
|
||||
// Hidden elements.
|
||||
|
||||
$mform->addElement('hidden', 'id');
|
||||
$mform->setType('id', PARAM_INT);
|
||||
|
@ -37,19 +37,19 @@ require_once($CFG->dirroot . '/question/type/calculated/questiontype.php');
|
||||
*/
|
||||
class qtype_calculatedsimple extends qtype_calculated {
|
||||
|
||||
// Used by the function custom_generator_tools:
|
||||
// Used by the function custom_generator_tools.
|
||||
public $wizard_pages_number = 1;
|
||||
|
||||
public function save_question_options($question) {
|
||||
global $CFG, $DB;
|
||||
$context = $question->context;
|
||||
// Get old answers:
|
||||
// Get old answers.
|
||||
|
||||
if (isset($question->answer) && !isset($question->answers)) {
|
||||
$question->answers = $question->answer;
|
||||
}
|
||||
|
||||
// Get old versions of the objects
|
||||
// Get old versions of the objects.
|
||||
if (!$oldanswers = $DB->get_records('question_answers',
|
||||
array('question' => $question->id), 'id ASC')) {
|
||||
$oldanswers = array();
|
||||
@ -68,7 +68,7 @@ class qtype_calculatedsimple extends qtype_calculated {
|
||||
} else {
|
||||
$units = &$result->units;
|
||||
}
|
||||
// Insert all the new answers
|
||||
// Insert all the new answers.
|
||||
if (isset($question->answer) && !isset($question->answers)) {
|
||||
$question->answers = $question->answer;
|
||||
}
|
||||
@ -98,7 +98,7 @@ class qtype_calculatedsimple extends qtype_calculated {
|
||||
|
||||
$DB->update_record("question_answers", $answer);
|
||||
|
||||
// Set up the options object
|
||||
// Set up the options object.
|
||||
if (!$options = array_shift($oldoptions)) {
|
||||
$options = new stdClass();
|
||||
}
|
||||
@ -109,24 +109,24 @@ class qtype_calculatedsimple extends qtype_calculated {
|
||||
$options->correctanswerlength = trim($question->correctanswerlength[$key]);
|
||||
$options->correctanswerformat = trim($question->correctanswerformat[$key]);
|
||||
|
||||
// Save options
|
||||
// Save options.
|
||||
if (isset($options->id)) {
|
||||
// reusing existing record
|
||||
// Reusing existing record.
|
||||
$DB->update_record('question_calculated', $options);
|
||||
} else {
|
||||
// new options
|
||||
// New options.
|
||||
$DB->insert_record('question_calculated', $options);
|
||||
}
|
||||
}
|
||||
|
||||
// delete old answer records
|
||||
// Delete old answer records.
|
||||
if (!empty($oldanswers)) {
|
||||
foreach ($oldanswers as $oa) {
|
||||
$DB->delete_records('question_answers', array('id' => $oa->id));
|
||||
}
|
||||
}
|
||||
|
||||
// delete old answer records
|
||||
// Delete old answer records.
|
||||
if (!empty($oldoptions)) {
|
||||
foreach ($oldoptions as $oo) {
|
||||
$DB->delete_records('question_calculated', array('id' => $oo->id));
|
||||
@ -136,10 +136,10 @@ class qtype_calculatedsimple extends qtype_calculated {
|
||||
if (isset($question->import_process) && $question->import_process) {
|
||||
$this->import_datasets($question);
|
||||
} else {
|
||||
//save datasets and datatitems from form i.e in question
|
||||
// Save datasets and datatitems from form i.e in question.
|
||||
$question->dataset = $question->datasetdef;
|
||||
|
||||
// Save datasets
|
||||
// Save datasets.
|
||||
$datasetdefinitions = $this->get_dataset_definitions($question->id, $question->dataset);
|
||||
$tmpdatasets = array_flip($question->dataset);
|
||||
$defids = array_keys($datasetdefinitions);
|
||||
@ -148,7 +148,7 @@ class qtype_calculatedsimple extends qtype_calculated {
|
||||
$datasetdef = &$datasetdefinitions[$defid];
|
||||
if (isset($datasetdef->id)) {
|
||||
if (!isset($tmpdatasets[$defid])) {
|
||||
// This dataset is not used any more, delete it
|
||||
// This dataset is not used any more, delete it.
|
||||
$DB->delete_records('question_datasets', array('question' => $question->id,
|
||||
'datasetdefinition' => $datasetdef->id));
|
||||
$DB->delete_records('question_dataset_definitions',
|
||||
@ -156,7 +156,7 @@ class qtype_calculatedsimple extends qtype_calculated {
|
||||
$DB->delete_records('question_dataset_items',
|
||||
array('definition' => $datasetdef->id));
|
||||
}
|
||||
// This has already been saved or just got deleted
|
||||
// This has already been saved or just got deleted.
|
||||
unset($datasetdefinitions[$defid]);
|
||||
continue;
|
||||
}
|
||||
@ -169,12 +169,12 @@ class qtype_calculatedsimple extends qtype_calculated {
|
||||
unset($datasetdefinitions[$defid]);
|
||||
}
|
||||
// Remove local obsolete datasets as well as relations
|
||||
// to datasets in other categories:
|
||||
// to datasets in other categories.
|
||||
if (!empty($datasetdefinitions)) {
|
||||
foreach ($datasetdefinitions as $def) {
|
||||
$DB->delete_records('question_datasets', array('question' => $question->id,
|
||||
'datasetdefinition' => $def->id));
|
||||
if ($def->category == 0) { // Question local dataset
|
||||
if ($def->category == 0) { // Question local dataset.
|
||||
$DB->delete_records('question_dataset_definitions',
|
||||
array('id' => $def->id));
|
||||
$DB->delete_records('question_dataset_items',
|
||||
@ -183,7 +183,7 @@ class qtype_calculatedsimple extends qtype_calculated {
|
||||
}
|
||||
}
|
||||
$datasetdefs = $this->get_dataset_definitions($question->id, $question->dataset);
|
||||
// Handle adding and removing of dataset items
|
||||
// Handle adding and removing of dataset items.
|
||||
$i = 1;
|
||||
ksort($question->definition);
|
||||
foreach ($question->definition as $key => $defid) {
|
||||
@ -192,7 +192,7 @@ class qtype_calculatedsimple extends qtype_calculated {
|
||||
$addeditem->value = $question->number[$i];
|
||||
$addeditem->itemnumber = ceil($i / count($datasetdefs));
|
||||
if (empty($question->makecopy) && $question->itemid[$i]) {
|
||||
// Reuse any previously used record
|
||||
// Reuse any previously used record.
|
||||
$addeditem->id = $question->itemid[$i];
|
||||
$DB->update_record('question_dataset_items', $addeditem);
|
||||
} else {
|
||||
@ -206,7 +206,7 @@ class qtype_calculatedsimple extends qtype_calculated {
|
||||
foreach ($datasetdefs as $key => $newdef) {
|
||||
if (isset($newdef->id) && $newdef->itemcount <= $maxnumber) {
|
||||
$newdef->itemcount = $maxnumber;
|
||||
// Save the new value for options
|
||||
// Save the new value for options.
|
||||
$DB->update_record('question_dataset_definitions', $newdef);
|
||||
}
|
||||
}
|
||||
@ -282,9 +282,9 @@ class qtype_calculatedsimple extends qtype_calculated {
|
||||
|
||||
public function dataset_options($form, $name, $mandatory = true, $renameabledatasets = false) {
|
||||
// Takes datasets from the parent implementation but
|
||||
// filters options that are currently not accepted by calculated
|
||||
// It also determines a default selection...
|
||||
//$renameabledatasets not implemented anmywhere
|
||||
// filters options that are currently not accepted by calculated.
|
||||
// It also determines a default selection
|
||||
// $renameabledatasets not implemented anywhere.
|
||||
list($options, $selected) = $this->dataset_options_from_database(
|
||||
$form, $name, '', 'qtype_calculated');
|
||||
|
||||
@ -295,9 +295,9 @@ class qtype_calculatedsimple extends qtype_calculated {
|
||||
}
|
||||
if (!$selected) {
|
||||
if ($mandatory) {
|
||||
$selected = "1-0-$name"; // Default
|
||||
$selected = "1-0-$name"; // Default.
|
||||
} else {
|
||||
$selected = "0"; // Default
|
||||
$selected = "0"; // Default.
|
||||
}
|
||||
}
|
||||
return array($options, $selected);
|
||||
|
@ -56,11 +56,10 @@ class qtype_description extends question_type {
|
||||
}
|
||||
|
||||
public function actual_number_of_questions($question) {
|
||||
/// Used for the feature number-of-questions-per-page
|
||||
/// to determine the actual number of questions wrapped
|
||||
/// by this question.
|
||||
/// The question type description is not even a question
|
||||
/// in itself so it will return ZERO!
|
||||
// Used for the feature number-of-questions-per-page
|
||||
// to determine the actual number of questions wrapped by this question.
|
||||
// The question type description is not even a question
|
||||
// in itself so it will return ZERO!
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -542,13 +542,13 @@ abstract class question_edit_form extends question_wizard_form {
|
||||
// Prepare the feedback editor to display files in draft area.
|
||||
$draftitemid = file_get_submitted_draft_itemid('answer['.$key.']');
|
||||
$question->answer[$key]['text'] = file_prepare_draft_area(
|
||||
$draftitemid, // draftid
|
||||
$draftitemid, // Draftid
|
||||
$this->context->id, // context
|
||||
'question', // component
|
||||
'answer', // filarea
|
||||
!empty($answer->id) ? (int) $answer->id : null, // itemid
|
||||
$this->fileoptions, // options
|
||||
$answer->answer // text
|
||||
$answer->answer // text.
|
||||
);
|
||||
$question->answer[$key]['itemid'] = $draftitemid;
|
||||
$question->answer[$key]['format'] = $answer->answerformat;
|
||||
@ -573,13 +573,13 @@ abstract class question_edit_form extends question_wizard_form {
|
||||
// Prepare the feedback editor to display files in draft area.
|
||||
$draftitemid = file_get_submitted_draft_itemid('feedback['.$key.']');
|
||||
$question->feedback[$key]['text'] = file_prepare_draft_area(
|
||||
$draftitemid, // draftid
|
||||
$draftitemid, // Draftid
|
||||
$this->context->id, // context
|
||||
'question', // component
|
||||
'answerfeedback', // filarea
|
||||
!empty($answer->id) ? (int) $answer->id : null, // itemid
|
||||
$this->fileoptions, // options
|
||||
$answer->feedback // text
|
||||
$answer->feedback // text.
|
||||
);
|
||||
$question->feedback[$key]['itemid'] = $draftitemid;
|
||||
$question->feedback[$key]['format'] = $answer->feedbackformat;
|
||||
@ -605,13 +605,13 @@ abstract class question_edit_form extends question_wizard_form {
|
||||
$draftid = file_get_submitted_draft_itemid($feedbackname);
|
||||
$feedback = array();
|
||||
$feedback['text'] = file_prepare_draft_area(
|
||||
$draftid, // draftid
|
||||
$draftid, // Draftid
|
||||
$this->context->id, // context
|
||||
'question', // component
|
||||
$feedbackname, // filarea
|
||||
!empty($question->id) ? (int) $question->id : null, // itemid
|
||||
$this->fileoptions, // options
|
||||
$question->options->$feedbackname // text
|
||||
$question->options->$feedbackname // text.
|
||||
);
|
||||
$feedbackformat = $feedbackname . 'format';
|
||||
$feedback['format'] = $question->options->$feedbackformat;
|
||||
@ -645,13 +645,13 @@ abstract class question_edit_form extends question_wizard_form {
|
||||
// Prepare feedback editor to display files in draft area.
|
||||
$draftitemid = file_get_submitted_draft_itemid('hint['.$key.']');
|
||||
$question->hint[$key]['text'] = file_prepare_draft_area(
|
||||
$draftitemid, // draftid
|
||||
$draftitemid, // Draftid
|
||||
$this->context->id, // context
|
||||
'question', // component
|
||||
'hint', // filarea
|
||||
!empty($hint->id) ? (int) $hint->id : null, // itemid
|
||||
$this->fileoptions, // options
|
||||
$hint->hint // text
|
||||
$hint->hint // text.
|
||||
);
|
||||
$question->hint[$key]['itemid'] = $draftitemid;
|
||||
$question->hint[$key]['format'] = $hint->hintformat;
|
||||
|
@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
@ -40,7 +39,7 @@ class moodle1_qtype_essay_handler extends moodle1_qtype_handler {
|
||||
* Appends the essay specific information to the question
|
||||
*/
|
||||
public function process_question(array $data, array $raw) {
|
||||
// data added on the upgrade step 2011031000
|
||||
// Data added on the upgrade step 2011031000.
|
||||
$this->write_xml('essay', array(
|
||||
'id' => $this->converter->get_nextid(),
|
||||
'responseformat' => 'editor',
|
||||
|
@ -38,29 +38,29 @@ class backup_qtype_essay_plugin extends backup_qtype_plugin {
|
||||
*/
|
||||
protected function define_question_plugin_structure() {
|
||||
|
||||
// Define the virtual plugin element with the condition to fulfill
|
||||
// Define the virtual plugin element with the condition to fulfill.
|
||||
$plugin = $this->get_plugin_element(null, '../../qtype', 'essay');
|
||||
|
||||
// Create one standard named plugin element (the visible container)
|
||||
// Create one standard named plugin element (the visible container).
|
||||
$pluginwrapper = new backup_nested_element($this->get_recommended_name());
|
||||
|
||||
// connect the visible container ASAP
|
||||
// Connect the visible container ASAP.
|
||||
$plugin->add_child($pluginwrapper);
|
||||
|
||||
// Now create the qtype own structures
|
||||
// Now create the qtype own structures.
|
||||
$essay = new backup_nested_element('essay', array('id'), array(
|
||||
'responseformat', 'responsefieldlines', 'attachments',
|
||||
'graderinfo', 'graderinfoformat', 'responsetemplate',
|
||||
'responsetemplateformat'));
|
||||
|
||||
// Now the own qtype tree
|
||||
// Now the own qtype tree.
|
||||
$pluginwrapper->add_child($essay);
|
||||
|
||||
// set source to populate the data
|
||||
// Set source to populate the data.
|
||||
$essay->set_source_table('qtype_essay_options',
|
||||
array('questionid' => backup::VAR_PARENTID));
|
||||
|
||||
// don't need to annotate ids nor files
|
||||
// Don't need to annotate ids nor files.
|
||||
|
||||
return $plugin;
|
||||
}
|
||||
|
@ -59,12 +59,12 @@ class restore_qtype_essay_plugin extends restore_qtype_plugin {
|
||||
$data->responsetemplateformat = FORMAT_HTML;
|
||||
}
|
||||
|
||||
// Detect if the question is created or mapped
|
||||
// Detect if the question is created or mapped.
|
||||
$questioncreated = $this->get_mappingid('question_created',
|
||||
$this->get_old_parentid('question')) ? true : false;
|
||||
|
||||
// If the question has been created by restore, we need to create its
|
||||
// qtype_essay too
|
||||
// qtype_essay too.
|
||||
if ($questioncreated) {
|
||||
$data->questionid = $this->get_new_parentid('question');
|
||||
$newitemid = $DB->insert_record('qtype_essay_options', $data);
|
||||
|
@ -36,9 +36,8 @@ function xmldb_qtype_essay_upgrade($oldversion) {
|
||||
|
||||
$dbman = $DB->get_manager();
|
||||
|
||||
|
||||
// Moodle v2.2.0 release upgrade line
|
||||
// Put any upgrade step following this
|
||||
// Put any upgrade step following this.
|
||||
|
||||
if ($oldversion < 2011102701) {
|
||||
$sql = "
|
||||
@ -47,7 +46,7 @@ function xmldb_qtype_essay_upgrade($oldversion) {
|
||||
|
||||
WHERE q.qtype = 'essay'
|
||||
AND " . $DB->sql_isnotempty('question_answers', 'feedback', false, true);
|
||||
// In Moodle <= 2.0 essay had both question.generalfeedback and question_answers.feedback.
|
||||
// In Moodle <= 2.0 essay had both question.generalfeedback and question_answers.feedback
|
||||
// This was silly, and in Moodel >= 2.1 only question.generalfeedback. To avoid
|
||||
// dataloss, we concatenate question_answers.feedback onto the end of question.generalfeedback.
|
||||
$count = $DB->count_records_sql("
|
||||
@ -101,11 +100,10 @@ function xmldb_qtype_essay_upgrade($oldversion) {
|
||||
}
|
||||
|
||||
// Moodle v2.3.0 release upgrade line
|
||||
// Put any upgrade step following this
|
||||
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Moodle v2.4.0 release upgrade line
|
||||
// Put any upgrade step following this
|
||||
// Put any upgrade step following this.
|
||||
|
||||
if ($oldversion < 2013011800) {
|
||||
// Then we delete the old question_answers rows for essay questions.
|
||||
|
@ -72,13 +72,13 @@ class qtype_essay_edit_form extends question_edit_form {
|
||||
$draftid = file_get_submitted_draft_itemid('graderinfo');
|
||||
$question->graderinfo = array();
|
||||
$question->graderinfo['text'] = file_prepare_draft_area(
|
||||
$draftid, // draftid
|
||||
$draftid, // Draftid
|
||||
$this->context->id, // context
|
||||
'qtype_essay', // component
|
||||
'graderinfo', // filarea
|
||||
!empty($question->id) ? (int) $question->id : null, // itemid
|
||||
$this->fileoptions, // options
|
||||
$question->options->graderinfo // text
|
||||
$question->options->graderinfo // text.
|
||||
);
|
||||
$question->graderinfo['format'] = $question->options->graderinfoformat;
|
||||
$question->graderinfo['itemid'] = $draftid;
|
||||
|
@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
@ -50,12 +49,12 @@ class moodle1_qtype_multianswer_handler extends moodle1_qtype_handler {
|
||||
*/
|
||||
public function process_question(array $data, array $raw) {
|
||||
|
||||
// convert and write the answers first
|
||||
// Convert and write the answers first.
|
||||
if (isset($data['answers'])) {
|
||||
$this->write_answers($data['answers'], $this->pluginname);
|
||||
}
|
||||
|
||||
// convert and write the multianswer extra fields
|
||||
// Convert and write the multianswer extra fields.
|
||||
foreach ($data['multianswers'] as $multianswers) {
|
||||
foreach ($multianswers as $multianswer) {
|
||||
$this->write_xml('multianswer', $multianswer, array('/multianswer/id'));
|
||||
|
@ -38,31 +38,31 @@ class backup_qtype_multianswer_plugin extends backup_qtype_plugin {
|
||||
*/
|
||||
protected function define_question_plugin_structure() {
|
||||
|
||||
// Define the virtual plugin element with the condition to fulfill
|
||||
// Define the virtual plugin element with the condition to fulfill.
|
||||
$plugin = $this->get_plugin_element(null, '../../qtype', 'multianswer');
|
||||
|
||||
// Create one standard named plugin element (the visible container)
|
||||
// Create one standard named plugin element (the visible container).
|
||||
$pluginwrapper = new backup_nested_element($this->get_recommended_name());
|
||||
|
||||
// connect the visible container ASAP
|
||||
// Connect the visible container ASAP.
|
||||
$plugin->add_child($pluginwrapper);
|
||||
|
||||
// This qtype uses standard question_answers, add them here
|
||||
// to the tree before any other information that will use them
|
||||
// to the tree before any other information that will use them.
|
||||
$this->add_question_question_answers($pluginwrapper);
|
||||
|
||||
// Now create the qtype own structures
|
||||
// Now create the qtype own structures.
|
||||
$multianswer = new backup_nested_element('multianswer', array('id'), array(
|
||||
'question', 'sequence'));
|
||||
|
||||
// Now the own qtype tree
|
||||
// Now the own qtype tree.
|
||||
$pluginwrapper->add_child($multianswer);
|
||||
|
||||
// set source to populate the data
|
||||
// Set source to populate the data.
|
||||
$multianswer->set_source_table('question_multianswer',
|
||||
array('question' => backup::VAR_PARENTID));
|
||||
|
||||
// don't need to annotate ids nor files
|
||||
// Don't need to annotate ids nor files.
|
||||
|
||||
return $plugin;
|
||||
}
|
||||
|
@ -40,15 +40,15 @@ class restore_qtype_multianswer_plugin extends restore_qtype_plugin {
|
||||
protected function define_question_plugin_structure() {
|
||||
$paths = array();
|
||||
|
||||
// This qtype uses question_answers, add them
|
||||
// This qtype uses question_answers, add them.
|
||||
$this->add_question_question_answers($paths);
|
||||
|
||||
// Add own qtype stuff
|
||||
// Add own qtype stuff.
|
||||
$elename = 'multianswer';
|
||||
$elepath = $this->get_pathfor('/multianswer');
|
||||
$paths[] = new restore_path_element($elename, $elepath);
|
||||
|
||||
return $paths; // And we return the interesting paths
|
||||
return $paths; // And we return the interesting paths.
|
||||
}
|
||||
|
||||
/**
|
||||
@ -60,23 +60,23 @@ class restore_qtype_multianswer_plugin extends restore_qtype_plugin {
|
||||
$data = (object)$data;
|
||||
$oldid = $data->id;
|
||||
|
||||
// Detect if the question is created or mapped
|
||||
// Detect if the question is created or mapped.
|
||||
$oldquestionid = $this->get_old_parentid('question');
|
||||
$newquestionid = $this->get_new_parentid('question');
|
||||
$questioncreated = $this->get_mappingid('question_created', $oldquestionid) ? true : false;
|
||||
|
||||
// If the question has been created by restore, we need to create its
|
||||
// question_multianswer too
|
||||
// question_multianswer too.
|
||||
if ($questioncreated) {
|
||||
// Adjust some columns
|
||||
// Adjust some columns.
|
||||
$data->question = $newquestionid;
|
||||
// Note: multianswer->sequence is a list of question->id values. We aren't
|
||||
// recoding them here (because some questions can be missing yet). Instead
|
||||
// we'll perform the recode in the {@link after_execute} method of the plugin
|
||||
// that gets executed once all questions have been created
|
||||
// Insert record
|
||||
// that gets executed once all questions have been created.
|
||||
// Insert record.
|
||||
$newitemid = $DB->insert_record('question_multianswer', $data);
|
||||
// Create mapping (need it for after_execute recode of sequence)
|
||||
// Create mapping (need it for after_execute recode of sequence).
|
||||
$this->set_mapping('question_multianswer', $oldid, $newitemid);
|
||||
}
|
||||
}
|
||||
@ -93,7 +93,7 @@ class restore_qtype_multianswer_plugin extends restore_qtype_plugin {
|
||||
public function after_execute_question() {
|
||||
global $DB;
|
||||
// Now that all the questions have been restored, let's process
|
||||
// the created question_multianswer sequences (list of question ids)
|
||||
// the created question_multianswer sequences (list of question ids).
|
||||
$rs = $DB->get_recordset_sql("
|
||||
SELECT qma.id, qma.sequence
|
||||
FROM {question_multianswer} qma
|
||||
@ -152,21 +152,21 @@ class restore_qtype_multianswer_plugin extends restore_qtype_plugin {
|
||||
global $DB;
|
||||
$answer = $state->answer;
|
||||
$resultarr = array();
|
||||
// Get sequence of questions
|
||||
// Get sequence of questions.
|
||||
$sequence = $DB->get_field('question_multianswer', 'sequence',
|
||||
array('question' => $state->question));
|
||||
$sequencearr = explode(',', $sequence);
|
||||
// Let's process each pair
|
||||
// Let's process each pair.
|
||||
foreach (explode(',', $answer) as $pair) {
|
||||
$pairarr = explode('-', $pair);
|
||||
$sequenceid = $pairarr[0];
|
||||
$subanswer = $pairarr[1];
|
||||
// Calculate the questionid based on sequenceid
|
||||
// Note it is already one *new* questionid that doesn't need mapping
|
||||
// Calculate the questionid based on sequenceid.
|
||||
// Note it is already one *new* questionid that doesn't need mapping.
|
||||
$questionid = $sequencearr[$sequenceid-1];
|
||||
// Fetch qtype of the question (needed for delegation)
|
||||
// Fetch qtype of the question (needed for delegation).
|
||||
$questionqtype = $DB->get_field('question', 'qtype', array('id' => $questionid));
|
||||
// Delegate subanswer recode to proper qtype, faking one question_states record
|
||||
// Delegate subanswer recode to proper qtype, faking one question_states record.
|
||||
$substate = new stdClass();
|
||||
$substate->question = $questionid;
|
||||
$substate->answer = $subanswer;
|
||||
|
@ -36,17 +36,14 @@ function xmldb_qtype_multianswer_upgrade($oldversion) {
|
||||
|
||||
$dbman = $DB->get_manager();
|
||||
|
||||
|
||||
// Moodle v2.2.0 release upgrade line
|
||||
// Put any upgrade step following this
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Moodle v2.3.0 release upgrade line
|
||||
// Put any upgrade step following this
|
||||
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Moodle v2.4.0 release upgrade line
|
||||
// Put any upgrade step following this
|
||||
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -44,30 +44,30 @@ class qtype_multianswer extends question_type {
|
||||
public function get_question_options($question) {
|
||||
global $DB, $OUTPUT;
|
||||
|
||||
// Get relevant data indexed by positionkey from the multianswers table
|
||||
// Get relevant data indexed by positionkey from the multianswers table.
|
||||
$sequence = $DB->get_field('question_multianswer', 'sequence',
|
||||
array('question' => $question->id), '*', MUST_EXIST);
|
||||
|
||||
$wrappedquestions = $DB->get_records_list('question', 'id',
|
||||
explode(',', $sequence), 'id ASC');
|
||||
|
||||
// We want an array with question ids as index and the positions as values
|
||||
// We want an array with question ids as index and the positions as values.
|
||||
$sequence = array_flip(explode(',', $sequence));
|
||||
array_walk($sequence, create_function('&$val', '$val++;'));
|
||||
|
||||
// If a question is lost, the corresponding index is null
|
||||
// so this null convention is used to test $question->options->questions
|
||||
// before using the values.
|
||||
// first all possible questions from sequence are nulled
|
||||
// then filled with the data if available in $wrappedquestions
|
||||
// First all possible questions from sequence are nulled
|
||||
// then filled with the data if available in $wrappedquestions.
|
||||
foreach ($sequence as $seq) {
|
||||
$question->options->questions[$seq] = '';
|
||||
}
|
||||
|
||||
foreach ($wrappedquestions as $wrapped) {
|
||||
question_bank::get_qtype($wrapped->qtype)->get_question_options($wrapped);
|
||||
// for wrapped questions the maxgrade is always equal to the defaultmark,
|
||||
// there is no entry in the question_instances table for them
|
||||
// For wrapped questions the maxgrade is always equal to the defaultmark,
|
||||
// there is no entry in the question_instances table for them.
|
||||
$wrapped->maxmark = $wrapped->defaultmark;
|
||||
$question->options->questions[$sequence[$wrapped->id]] = $wrapped;
|
||||
}
|
||||
@ -84,12 +84,12 @@ class qtype_multianswer extends question_type {
|
||||
|
||||
// This function needs to be able to handle the case where the existing set of wrapped
|
||||
// questions does not match the new set of wrapped questions so that some need to be
|
||||
// created, some modified and some deleted
|
||||
// created, some modified and some deleted.
|
||||
// Unfortunately the code currently simply overwrites existing ones in sequence. This
|
||||
// will make re-marking after a re-ordering of wrapped questions impossible and
|
||||
// will also create difficulties if questiontype specific tables reference the id.
|
||||
|
||||
// First we get all the existing wrapped questions
|
||||
// First we get all the existing wrapped questions.
|
||||
if (!$oldwrappedids = $DB->get_field('question_multianswer', 'sequence',
|
||||
array('question' => $question->id))) {
|
||||
$oldwrappedquestions = array();
|
||||
@ -101,7 +101,7 @@ class qtype_multianswer extends question_type {
|
||||
$sequence = array();
|
||||
foreach ($question->options->questions as $wrapped) {
|
||||
if (!empty($wrapped)) {
|
||||
// if we still have some old wrapped question ids, reuse the next of them
|
||||
// If we still have some old wrapped question ids, reuse the next of them.
|
||||
|
||||
if (is_array($oldwrappedquestions) &&
|
||||
$oldwrappedquestion = array_shift($oldwrappedquestions)) {
|
||||
@ -133,19 +133,19 @@ class qtype_multianswer extends question_type {
|
||||
$wrapped->name = $question->name;
|
||||
$wrapped->parent = $question->id;
|
||||
$previousid = $wrapped->id;
|
||||
// save_question strips this extra bit off the category again.
|
||||
// Save_question strips this extra bit off the category again.
|
||||
$wrapped->category = $question->category . ',1';
|
||||
$wrapped = question_bank::get_qtype($wrapped->qtype)->save_question(
|
||||
$wrapped, clone($wrapped));
|
||||
$sequence[] = $wrapped->id;
|
||||
if ($previousid != 0 && $previousid != $wrapped->id) {
|
||||
// for some reasons a new question has been created
|
||||
// so delete the old one
|
||||
// For some reasons a new question has been created
|
||||
// so delete the old one.
|
||||
question_delete_question($previousid);
|
||||
}
|
||||
}
|
||||
|
||||
// Delete redundant wrapped questions
|
||||
// Delete redundant wrapped questions.
|
||||
if (is_array($oldwrappedquestions) && count($oldwrappedquestions)) {
|
||||
foreach ($oldwrappedquestions as $oldwrappedquestion) {
|
||||
question_delete_question($oldwrappedquestion->id);
|
||||
@ -240,10 +240,10 @@ class qtype_multianswer extends question_type {
|
||||
}
|
||||
|
||||
|
||||
// ANSWER_ALTERNATIVE regexes
|
||||
// ANSWER_ALTERNATIVE regexes.
|
||||
define('ANSWER_ALTERNATIVE_FRACTION_REGEX',
|
||||
'=|%(-?[0-9]+)%');
|
||||
// for the syntax '(?<!' see http://www.perl.com/doc/manual/html/pod/perlre.html#item_C
|
||||
// For the syntax '(?<!' see http://www.perl.com/doc/manual/html/pod/perlre.html#item_C.
|
||||
define('ANSWER_ALTERNATIVE_ANSWER_REGEX',
|
||||
'.+?(?<!\\\\|&|&)(?=[~#}]|$)');
|
||||
define('ANSWER_ALTERNATIVE_FEEDBACK_REGEX',
|
||||
@ -253,24 +253,24 @@ define('ANSWER_ALTERNATIVE_REGEX',
|
||||
'(' . ANSWER_ALTERNATIVE_ANSWER_REGEX . ')' .
|
||||
'(#(' . ANSWER_ALTERNATIVE_FEEDBACK_REGEX .'))?');
|
||||
|
||||
// Parenthesis positions for ANSWER_ALTERNATIVE_REGEX
|
||||
// Parenthesis positions for ANSWER_ALTERNATIVE_REGEX.
|
||||
define('ANSWER_ALTERNATIVE_REGEX_PERCENTILE_FRACTION', 2);
|
||||
define('ANSWER_ALTERNATIVE_REGEX_FRACTION', 1);
|
||||
define('ANSWER_ALTERNATIVE_REGEX_ANSWER', 3);
|
||||
define('ANSWER_ALTERNATIVE_REGEX_FEEDBACK', 5);
|
||||
|
||||
// NUMBER_FORMATED_ALTERNATIVE_ANSWER_REGEX is used
|
||||
// for identifying numerical answers in ANSWER_ALTERNATIVE_REGEX_ANSWER
|
||||
// for identifying numerical answers in ANSWER_ALTERNATIVE_REGEX_ANSWER.
|
||||
define('NUMBER_REGEX',
|
||||
'-?(([0-9]+[.,]?[0-9]*|[.,][0-9]+)([eE][-+]?[0-9]+)?)');
|
||||
define('NUMERICAL_ALTERNATIVE_REGEX',
|
||||
'^(' . NUMBER_REGEX . ')(:' . NUMBER_REGEX . ')?$');
|
||||
|
||||
// Parenthesis positions for NUMERICAL_FORMATED_ALTERNATIVE_ANSWER_REGEX
|
||||
// Parenthesis positions for NUMERICAL_FORMATED_ALTERNATIVE_ANSWER_REGEX.
|
||||
define('NUMERICAL_CORRECT_ANSWER', 1);
|
||||
define('NUMERICAL_ABS_ERROR_MARGIN', 6);
|
||||
|
||||
// Remaining ANSWER regexes
|
||||
// Remaining ANSWER regexes.
|
||||
define('ANSWER_TYPE_DEF_REGEX',
|
||||
'(NUMERICAL|NM)|(MULTICHOICE|MC)|(MULTICHOICE_V|MCV)|(MULTICHOICE_H|MCH)|' .
|
||||
'(SHORTANSWER|SA|MW)|(SHORTANSWER_C|SAC|MWC)');
|
||||
@ -284,7 +284,7 @@ define('ANSWER_REGEX',
|
||||
. ANSWER_ALTERNATIVE_REGEX
|
||||
. ')*)\}');
|
||||
|
||||
// Parenthesis positions for singulars in ANSWER_REGEX
|
||||
// Parenthesis positions for singulars in ANSWER_REGEX.
|
||||
define('ANSWER_REGEX_NORM', 1);
|
||||
define('ANSWER_REGEX_ANSWER_TYPE_NUMERICAL', 3);
|
||||
define('ANSWER_REGEX_ANSWER_TYPE_MULTICHOICE', 4);
|
||||
@ -295,7 +295,7 @@ define('ANSWER_REGEX_ANSWER_TYPE_SHORTANSWER_C', 8);
|
||||
define('ANSWER_REGEX_ALTERNATIVES', 9);
|
||||
|
||||
function qtype_multianswer_extract_question($text) {
|
||||
// $text is an array [text][format][itemid]
|
||||
// Variable $text is an array [text][format][itemid].
|
||||
$question = new stdClass();
|
||||
$question->qtype = 'multianswer';
|
||||
$question->questiontext = $text;
|
||||
@ -305,7 +305,7 @@ function qtype_multianswer_extract_question($text) {
|
||||
|
||||
$question->options = new stdClass();
|
||||
$question->options->questions = array();
|
||||
$question->defaultmark = 0; // Will be increased for each answer norm
|
||||
$question->defaultmark = 0; // Will be increased for each answer norm.
|
||||
|
||||
for ($positionkey = 1;
|
||||
preg_match('/'.ANSWER_REGEX.'/s', $question->questiontext['text'], $answerregs);
|
||||
@ -384,7 +384,7 @@ function qtype_multianswer_extract_question($text) {
|
||||
|
||||
// Each $wrapped simulates a $form that can be processed by the
|
||||
// respective save_question and save_question_options methods of the
|
||||
// wrapped questiontypes
|
||||
// wrapped questiontypes.
|
||||
$wrapped->answer = array();
|
||||
$wrapped->fraction = array();
|
||||
$wrapped->feedback = array();
|
||||
@ -425,7 +425,7 @@ function qtype_multianswer_extract_question($text) {
|
||||
} else {
|
||||
$wrapped->tolerance["$answerindex"] = 0;
|
||||
}
|
||||
} else { // Tolerance can stay undefined for non numerical questions
|
||||
} else { // Tolerance can stay undefined for non numerical questions.
|
||||
// Undo quoting done by the HTML editor.
|
||||
$answer = html_entity_decode(
|
||||
$altregs[ANSWER_ALTERNATIVE_REGEX_ANSWER], ENT_QUOTES, 'UTF-8');
|
||||
|
@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
@ -44,15 +43,15 @@ class moodle1_qtype_multichoice_handler extends moodle1_qtype_handler {
|
||||
*/
|
||||
public function process_question(array $data, array $raw) {
|
||||
|
||||
// convert and write the answers first
|
||||
// Convert and write the answers first.
|
||||
if (isset($data['answers'])) {
|
||||
$this->write_answers($data['answers'], $this->pluginname);
|
||||
}
|
||||
|
||||
// convert and write the multichoice
|
||||
// Convert and write the multichoice.
|
||||
if (!isset($data['multichoice'])) {
|
||||
// This should never happen, but it can do if the 1.9 site contained
|
||||
// corrupt data/
|
||||
// corrupt data.
|
||||
$data['multichoice'] = array(array(
|
||||
'single' => 1,
|
||||
'shuffleanswers' => 1,
|
||||
@ -78,13 +77,13 @@ class moodle1_qtype_multichoice_handler extends moodle1_qtype_handler {
|
||||
protected function write_multichoice(array $multichoices, $oldquestiontextformat, $questionid) {
|
||||
global $CFG;
|
||||
|
||||
// the grouped array is supposed to have just one element - let us use foreach anyway
|
||||
// just to be sure we do not loose anything
|
||||
// The grouped array is supposed to have just one element - let us use foreach anyway
|
||||
// just to be sure we do not loose anything.
|
||||
foreach ($multichoices as $multichoice) {
|
||||
// append an artificial 'id' attribute (is not included in moodle.xml)
|
||||
// Append an artificial 'id' attribute (is not included in moodle.xml).
|
||||
$multichoice['id'] = $this->converter->get_nextid();
|
||||
|
||||
// replay the upgrade step 2009021801
|
||||
// Replay the upgrade step 2009021801.
|
||||
$multichoice['correctfeedbackformat'] = 0;
|
||||
$multichoice['partiallycorrectfeedbackformat'] = 0;
|
||||
$multichoice['incorrectfeedbackformat'] = 0;
|
||||
|
@ -38,34 +38,34 @@ class backup_qtype_multichoice_plugin extends backup_qtype_plugin {
|
||||
*/
|
||||
protected function define_question_plugin_structure() {
|
||||
|
||||
// Define the virtual plugin element with the condition to fulfill
|
||||
// Define the virtual plugin element with the condition to fulfill.
|
||||
$plugin = $this->get_plugin_element(null, '../../qtype', 'multichoice');
|
||||
|
||||
// Create one standard named plugin element (the visible container)
|
||||
// Create one standard named plugin element (the visible container).
|
||||
$pluginwrapper = new backup_nested_element($this->get_recommended_name());
|
||||
|
||||
// connect the visible container ASAP
|
||||
// Connect the visible container ASAP.
|
||||
$plugin->add_child($pluginwrapper);
|
||||
|
||||
// This qtype uses standard question_answers, add them here
|
||||
// to the tree before any other information that will use them
|
||||
// to the tree before any other information that will use them.
|
||||
$this->add_question_question_answers($pluginwrapper);
|
||||
|
||||
// Now create the qtype own structures
|
||||
// Now create the qtype own structures.
|
||||
$multichoice = new backup_nested_element('multichoice', array('id'), array(
|
||||
'layout', 'answers', 'single', 'shuffleanswers',
|
||||
'correctfeedback', 'correctfeedbackformat',
|
||||
'partiallycorrectfeedback', 'partiallycorrectfeedbackformat',
|
||||
'incorrectfeedback', 'incorrectfeedbackformat', 'answernumbering', 'shownumcorrect'));
|
||||
|
||||
// Now the own qtype tree
|
||||
// Now the own qtype tree.
|
||||
$pluginwrapper->add_child($multichoice);
|
||||
|
||||
// set source to populate the data
|
||||
// Set source to populate the data.
|
||||
$multichoice->set_source_table('question_multichoice',
|
||||
array('question' => backup::VAR_PARENTID));
|
||||
|
||||
// don't need to annotate ids nor files
|
||||
// Don't need to annotate ids nor files.
|
||||
|
||||
return $plugin;
|
||||
}
|
||||
|
@ -41,16 +41,16 @@ class restore_qtype_multichoice_plugin extends restore_qtype_plugin {
|
||||
|
||||
$paths = array();
|
||||
|
||||
// This qtype uses question_answers, add them
|
||||
// This qtype uses question_answers, add them.
|
||||
$this->add_question_question_answers($paths);
|
||||
|
||||
// Add own qtype stuff
|
||||
// Add own qtype stuff.
|
||||
$elename = 'multichoice';
|
||||
// we used get_recommended_name() so this works
|
||||
// We used get_recommended_name() so this works.
|
||||
$elepath = $this->get_pathfor('/multichoice');
|
||||
$paths[] = new restore_path_element($elename, $elepath);
|
||||
|
||||
return $paths; // And we return the interesting paths
|
||||
return $paths; // And we return the interesting paths.
|
||||
}
|
||||
|
||||
/**
|
||||
@ -62,17 +62,17 @@ class restore_qtype_multichoice_plugin extends restore_qtype_plugin {
|
||||
$data = (object)$data;
|
||||
$oldid = $data->id;
|
||||
|
||||
// Detect if the question is created or mapped
|
||||
// Detect if the question is created or mapped.
|
||||
$oldquestionid = $this->get_old_parentid('question');
|
||||
$newquestionid = $this->get_new_parentid('question');
|
||||
$questioncreated = (bool) $this->get_mappingid('question_created', $oldquestionid);
|
||||
|
||||
// If the question has been created by restore, we need to create its
|
||||
// question_multichoice too
|
||||
// question_multichoice too.
|
||||
if ($questioncreated) {
|
||||
// Adjust some columns
|
||||
// Adjust some columns.
|
||||
$data->question = $newquestionid;
|
||||
// Map sequence of question_answer ids
|
||||
// Map sequence of question_answer ids.
|
||||
if ($data->answers) {
|
||||
$answersarr = explode(',', $data->answers);
|
||||
} else {
|
||||
@ -82,9 +82,9 @@ class restore_qtype_multichoice_plugin extends restore_qtype_plugin {
|
||||
$answersarr[$key] = $this->get_mappingid('question_answer', $answer);
|
||||
}
|
||||
$data->answers = implode(',', $answersarr);
|
||||
// Insert record
|
||||
// Insert record.
|
||||
$newitemid = $DB->insert_record('question_multichoice', $data);
|
||||
// Create mapping (needed for decoding links)
|
||||
// Create mapping (needed for decoding links).
|
||||
$this->set_mapping('question_multichoice', $oldid, $newitemid);
|
||||
}
|
||||
}
|
||||
@ -124,12 +124,12 @@ class restore_qtype_multichoice_plugin extends restore_qtype_plugin {
|
||||
$orderarr = array();
|
||||
$responsesarr = array();
|
||||
$lists = explode(':', $answer);
|
||||
// if only 1 list, answer is missing the order list, adjust
|
||||
// If only 1 list, answer is missing the order list, adjust.
|
||||
if (count($lists) == 1) {
|
||||
$lists[1] = $lists[0]; // here we have the responses
|
||||
$lists[0] = ''; // here we have the order
|
||||
$lists[1] = $lists[0]; // Here we have the responses.
|
||||
$lists[0] = ''; // Here we have the order.
|
||||
}
|
||||
// Map order
|
||||
// Map order.
|
||||
if (!empty($lists[0])) {
|
||||
foreach (explode(',', $lists[0]) as $id) {
|
||||
if ($newid = $this->get_mappingid('question_answer', $id)) {
|
||||
@ -137,7 +137,7 @@ class restore_qtype_multichoice_plugin extends restore_qtype_plugin {
|
||||
}
|
||||
}
|
||||
}
|
||||
// Map responses
|
||||
// Map responses.
|
||||
if (!empty($lists[1])) {
|
||||
foreach (explode(',', $lists[1]) as $id) {
|
||||
if ($newid = $this->get_mappingid('question_answer', $id)) {
|
||||
@ -145,7 +145,7 @@ class restore_qtype_multichoice_plugin extends restore_qtype_plugin {
|
||||
}
|
||||
}
|
||||
}
|
||||
// Build the final answer, if not order, only responses
|
||||
// Build the final answer, if not order, only responses.
|
||||
$result = '';
|
||||
if (empty($orderarr)) {
|
||||
$result = implode(',', $responsesarr);
|
||||
|
@ -38,14 +38,14 @@ function xmldb_qtype_multichoice_upgrade($oldversion) {
|
||||
|
||||
|
||||
// Moodle v2.2.0 release upgrade line
|
||||
// Put any upgrade step following this
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Moodle v2.3.0 release upgrade line
|
||||
// Put any upgrade step following this
|
||||
// Put any upgrade step following this.
|
||||
|
||||
|
||||
// Moodle v2.4.0 release upgrade line
|
||||
// Put any upgrade step following this
|
||||
// Put any upgrade step following this.
|
||||
|
||||
|
||||
return true;
|
||||
|
@ -40,7 +40,7 @@ class qtype_multichoice_qe2_attempt_updater extends question_qtype_attempt_updat
|
||||
protected $order;
|
||||
|
||||
public function is_blank_answer($state) {
|
||||
// blank multichoice answers are not empty strings, they rather end in a colon
|
||||
// Blank multichoice answers are not empty strings, they rather end in a colon.
|
||||
return empty($state->answer) || substr($state->answer, -1) == ':';
|
||||
}
|
||||
|
||||
|
@ -106,7 +106,7 @@ class qtype_multichoice_edit_form extends question_edit_form {
|
||||
$maxfraction = -1;
|
||||
|
||||
foreach ($answers as $key => $answer) {
|
||||
//check no of choices
|
||||
// Check no of choices.
|
||||
$trimmedanswer = trim($answer['text']);
|
||||
$fraction = (float) $data['fraction'][$key];
|
||||
if ($trimmedanswer === '' && empty($fraction)) {
|
||||
@ -118,7 +118,7 @@ class qtype_multichoice_edit_form extends question_edit_form {
|
||||
|
||||
$answercount++;
|
||||
|
||||
//check grades
|
||||
// Check grades.
|
||||
if ($data['fraction'][$key] > 0) {
|
||||
$totalfraction += $data['fraction'][$key];
|
||||
}
|
||||
@ -135,7 +135,7 @@ class qtype_multichoice_edit_form extends question_edit_form {
|
||||
|
||||
}
|
||||
|
||||
/// Perform sanity checks on fractional grades
|
||||
// Perform sanity checks on fractional grades.
|
||||
if ($data['single']) {
|
||||
if ($maxfraction != 1) {
|
||||
$errors['fraction[0]'] = get_string('errfractionsnomax', 'qtype_multichoice',
|
||||
|
@ -97,11 +97,11 @@ abstract class qtype_multichoice_base extends question_graded_automatically {
|
||||
return $this->check_combined_feedback_file_access($qa, $options, $filearea);
|
||||
|
||||
} else if ($component == 'question' && $filearea == 'answer') {
|
||||
$answerid = reset($args); // itemid is answer id.
|
||||
$answerid = reset($args); // Itemid is answer id.
|
||||
return in_array($answerid, $this->order);
|
||||
|
||||
} else if ($component == 'question' && $filearea == 'answerfeedback') {
|
||||
$answerid = reset($args); // itemid is answer id.
|
||||
$answerid = reset($args); // Itemid is answer id.
|
||||
$response = $this->get_response($qa);
|
||||
$isselected = false;
|
||||
foreach ($this->order as $value => $ansid) {
|
||||
@ -110,7 +110,7 @@ abstract class qtype_multichoice_base extends question_graded_automatically {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// $options->suppresschoicefeedback is a hack specific to the
|
||||
// Param $options->suppresschoicefeedback is a hack specific to the
|
||||
// oumultiresponse question type. It would be good to refactor to
|
||||
// avoid refering to it here.
|
||||
return $options->feedback && empty($options->suppresschoicefeedback) &&
|
||||
|
@ -52,19 +52,19 @@ class qtype_multichoice extends question_type {
|
||||
$oldanswers = $DB->get_records('question_answers',
|
||||
array('question' => $question->id), 'id ASC');
|
||||
|
||||
// following hack to check at least two answers exist
|
||||
// Following hack to check at least two answers exist.
|
||||
$answercount = 0;
|
||||
foreach ($question->answer as $key => $answer) {
|
||||
if ($answer != '') {
|
||||
$answercount++;
|
||||
}
|
||||
}
|
||||
if ($answercount < 2) { // check there are at lest 2 answers for multiple choice
|
||||
if ($answercount < 2) { // Check there are at lest 2 answers for multiple choice.
|
||||
$result->notice = get_string('notenoughanswers', 'qtype_multichoice', '2');
|
||||
return $result;
|
||||
}
|
||||
|
||||
// Insert all the new answers
|
||||
// Insert all the new answers.
|
||||
$totalfraction = 0;
|
||||
$maxfraction = -1;
|
||||
$answers = array();
|
||||
@ -83,7 +83,7 @@ class qtype_multichoice extends question_type {
|
||||
$answer->id = $DB->insert_record('question_answers', $answer);
|
||||
}
|
||||
|
||||
// Doing an import
|
||||
// Doing an import.
|
||||
$answer->answer = $this->import_or_save_files($answerdata,
|
||||
$context, 'question', 'answer', $answer->id);
|
||||
$answer->answerformat = $answerdata['format'];
|
||||
@ -132,7 +132,7 @@ class qtype_multichoice extends question_type {
|
||||
|
||||
$this->save_hints($question, true);
|
||||
|
||||
// Perform sanity checks on fractional grades
|
||||
// Perform sanity checks on fractional grades.
|
||||
if ($options->single) {
|
||||
if ($maxfraction != 1) {
|
||||
$result->noticeyesno = get_string('fractionsnomax', 'qtype_multichoice',
|
||||
|
@ -99,7 +99,7 @@ abstract class qtype_multichoice_renderer_base extends qtype_with_combined_feedb
|
||||
$qa, 'question', 'answer', $ansid)),
|
||||
array('for' => $inputattributes['id']));
|
||||
|
||||
// $options->suppresschoicefeedback is a hack specific to the
|
||||
// Param $options->suppresschoicefeedback is a hack specific to the
|
||||
// oumultiresponse question type. It would be good to refactor to
|
||||
// avoid refering to it here.
|
||||
if ($options->feedback && empty($options->suppresschoicefeedback) &&
|
||||
@ -134,9 +134,9 @@ abstract class qtype_multichoice_renderer_base extends qtype_with_combined_feedb
|
||||
$result .= html_writer::tag('div', $radio . ' ' . $feedbackimg[$key] . $feedback[$key],
|
||||
array('class' => $classes[$key])) . "\n";
|
||||
}
|
||||
$result .= html_writer::end_tag('div'); // answer
|
||||
$result .= html_writer::end_tag('div'); // Answer.
|
||||
|
||||
$result .= html_writer::end_tag('div'); // ablock
|
||||
$result .= html_writer::end_tag('div'); // Ablock.
|
||||
|
||||
if ($qa->get_state() == question_state::$invalid) {
|
||||
$result .= html_writer::nonempty_tag('div',
|
||||
|
@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
@ -45,12 +44,12 @@ class moodle1_qtype_numerical_handler extends moodle1_qtype_handler {
|
||||
*/
|
||||
public function process_question(array $data, array $raw) {
|
||||
|
||||
// convert and write the answers first
|
||||
// Convert and write the answers first.
|
||||
if (isset($data['answers'])) {
|
||||
$this->write_answers($data['answers'], $this->pluginname);
|
||||
}
|
||||
|
||||
// convert and write the numerical units and numerical options
|
||||
// Convert and write the numerical units and numerical options.
|
||||
if (isset($data['numerical'][0]['numerical_units'])) {
|
||||
$numericalunits = $data['numerical'][0]['numerical_units'];
|
||||
} else {
|
||||
@ -62,10 +61,10 @@ class moodle1_qtype_numerical_handler extends moodle1_qtype_handler {
|
||||
$this->write_numerical_units($numericalunits);
|
||||
$this->write_numerical_options($numericaloptions);
|
||||
|
||||
// and finally numerical_records
|
||||
// And finally numerical_records.
|
||||
$this->xmlwriter->begin_tag('numerical_records');
|
||||
foreach ($data['numerical'] as $numericalrecord) {
|
||||
// we do not use write_xml() here because $numericalrecords contains more than we want
|
||||
// We do not use write_xml() here because $numericalrecords contains more than we want.
|
||||
$this->xmlwriter->begin_tag('numerical_record', array('id' => $this->converter->get_nextid()));
|
||||
$this->xmlwriter->full_tag('answer', $numericalrecord['answer']);
|
||||
$this->xmlwriter->full_tag('tolerance', $numericalrecord['tolerance']);
|
||||
|
@ -38,39 +38,39 @@ class backup_qtype_numerical_plugin extends backup_qtype_plugin {
|
||||
*/
|
||||
protected function define_question_plugin_structure() {
|
||||
|
||||
// Define the virtual plugin element with the condition to fulfill
|
||||
// Define the virtual plugin element with the condition to fulfill.
|
||||
$plugin = $this->get_plugin_element(null, '../../qtype', 'numerical');
|
||||
|
||||
// Create one standard named plugin element (the visible container)
|
||||
// Create one standard named plugin element (the visible container).
|
||||
$pluginwrapper = new backup_nested_element($this->get_recommended_name());
|
||||
|
||||
// connect the visible container ASAP
|
||||
// Connect the visible container ASAP.
|
||||
$plugin->add_child($pluginwrapper);
|
||||
|
||||
// This qtype uses standard question_answers, add them here
|
||||
// to the tree before any other information that will use them
|
||||
// to the tree before any other information that will use them.
|
||||
$this->add_question_question_answers($pluginwrapper);
|
||||
|
||||
// This qtype uses standard numerical units, add them here
|
||||
// This qtype uses standard numerical units, add them here.
|
||||
$this->add_question_numerical_units($pluginwrapper);
|
||||
|
||||
// This qtype uses standard numerical options, add them here
|
||||
// This qtype uses standard numerical options, add them here.
|
||||
$this->add_question_numerical_options($pluginwrapper);
|
||||
|
||||
// Now create the qtype own structures
|
||||
// Now create the qtype own structures.
|
||||
$numericalrecords = new backup_nested_element('numerical_records');
|
||||
$numericalrecord = new backup_nested_element('numerical_record', array('id'), array(
|
||||
'answer', 'tolerance'));
|
||||
|
||||
// Now the own qtype tree
|
||||
// Now the own qtype tree.
|
||||
$pluginwrapper->add_child($numericalrecords);
|
||||
$numericalrecords->add_child($numericalrecord);
|
||||
|
||||
// set source to populate the data
|
||||
// Set source to populate the data.
|
||||
$numericalrecord->set_source_table('question_numerical',
|
||||
array('question' => backup::VAR_PARENTID));
|
||||
|
||||
// don't need to annotate ids nor files
|
||||
// Don't need to annotate ids nor files.
|
||||
|
||||
return $plugin;
|
||||
}
|
||||
|
@ -41,19 +41,19 @@ class restore_qtype_numerical_plugin extends restore_qtype_plugin {
|
||||
|
||||
$paths = array();
|
||||
|
||||
// This qtype uses question_answers, add them
|
||||
// This qtype uses question_answers, add them.
|
||||
$this->add_question_question_answers($paths);
|
||||
|
||||
// This qtype uses question_numerical_options and question_numerical_units, add them
|
||||
// This qtype uses question_numerical_options and question_numerical_units, add them.
|
||||
$this->add_question_numerical_options($paths);
|
||||
$this->add_question_numerical_units($paths);
|
||||
|
||||
// Add own qtype stuff
|
||||
// Add own qtype stuff.
|
||||
$elename = 'numerical';
|
||||
$elepath = $this->get_pathfor('/numerical_records/numerical_record');
|
||||
$paths[] = new restore_path_element($elename, $elepath);
|
||||
|
||||
return $paths; // And we return the interesting paths
|
||||
return $paths; // And we return the interesting paths.
|
||||
}
|
||||
|
||||
/**
|
||||
@ -65,7 +65,7 @@ class restore_qtype_numerical_plugin extends restore_qtype_plugin {
|
||||
$data = (object)$data;
|
||||
$oldid = $data->id;
|
||||
|
||||
// Detect if the question is created or mapped
|
||||
// Detect if the question is created or mapped.
|
||||
$oldquestionid = $this->get_old_parentid('question');
|
||||
$newquestionid = $this->get_new_parentid('question');
|
||||
$questioncreated = $this->get_mappingid('question_created', $oldquestionid) ? true : false;
|
||||
@ -73,10 +73,10 @@ class restore_qtype_numerical_plugin extends restore_qtype_plugin {
|
||||
// If the question has been created by restore, we need to create its
|
||||
// question_numerical too.
|
||||
if ($questioncreated) {
|
||||
// Adjust some columns
|
||||
// Adjust some columns.
|
||||
$data->question = $newquestionid;
|
||||
$data->answer = $this->get_mappingid('question_answer', $data->answer);
|
||||
// Insert record
|
||||
// Insert record.
|
||||
$newitemid = $DB->insert_record('question_numerical', $data);
|
||||
}
|
||||
}
|
||||
|
@ -36,14 +36,11 @@ function xmldb_qtype_numerical_upgrade($oldversion) {
|
||||
|
||||
$dbman = $DB->get_manager();
|
||||
|
||||
|
||||
// Moodle v2.3.0 release upgrade line
|
||||
// Put any upgrade step following this
|
||||
|
||||
// Put any upgrade step following this.
|
||||
|
||||
// Moodle v2.4.0 release upgrade line
|
||||
// Put any upgrade step following this
|
||||
|
||||
// Put any upgrade step following this.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -287,7 +287,7 @@ class qtype_numerical_question extends question_graded_automatically {
|
||||
list($value, $unit, $multiplier) = $this->ap->apply_units(
|
||||
$currentanswer, $selectedunit);
|
||||
$answer = $this->get_matching_answer($value, $multiplier);
|
||||
$answerid = reset($args); // itemid is answer id.
|
||||
$answerid = reset($args); // Itemid is answer id.
|
||||
return $options->feedback && $answer && $answerid == $answer->id;
|
||||
|
||||
} else if ($component == 'question' && $filearea == 'hint') {
|
||||
|
@ -75,8 +75,8 @@ class qtype_numerical extends question_type {
|
||||
array('questionid' => $question->id), 'id ASC');
|
||||
|
||||
$this->get_numerical_units($question);
|
||||
// get_numerical_options() need to know if there are units
|
||||
// to set correctly default values
|
||||
// Get_numerical_options() need to know if there are units
|
||||
// to set correctly default values.
|
||||
$this->get_numerical_options($question);
|
||||
|
||||
// If units are defined we strip off the default unit from the answer, if
|
||||
@ -153,7 +153,7 @@ class qtype_numerical extends question_type {
|
||||
global $DB;
|
||||
$context = $question->context;
|
||||
|
||||
// Get old versions of the objects
|
||||
// Get old versions of the objects.
|
||||
$oldanswers = $DB->get_records('question_answers',
|
||||
array('question' => $question->id), 'id ASC');
|
||||
$oldoptions = $DB->get_records('question_numerical',
|
||||
@ -167,7 +167,7 @@ class qtype_numerical extends question_type {
|
||||
$units = $result->units;
|
||||
}
|
||||
|
||||
// Insert all the new answers
|
||||
// Insert all the new answers.
|
||||
foreach ($question->answer as $key => $answerdata) {
|
||||
// Check for, and ingore, completely blank answer from the form.
|
||||
if (trim($answerdata) == '' && $question->fraction[$key] == 0 &&
|
||||
@ -200,7 +200,7 @@ class qtype_numerical extends question_type {
|
||||
$answer->feedbackformat = $question->feedback[$key]['format'];
|
||||
$DB->update_record('question_answers', $answer);
|
||||
|
||||
// Set up the options object
|
||||
// Set up the options object.
|
||||
if (!$options = array_shift($oldoptions)) {
|
||||
$options = new stdClass();
|
||||
}
|
||||
@ -323,7 +323,7 @@ class qtype_numerical extends question_type {
|
||||
$units = array();
|
||||
$unitalreadyinsert = array();
|
||||
foreach ($question->multiplier as $i => $multiplier) {
|
||||
// Discard any unit which doesn't specify the unit or the multiplier
|
||||
// Discard any unit which doesn't specify the unit or the multiplier.
|
||||
if (!empty($question->multiplier[$i]) && !empty($question->unit[$i]) &&
|
||||
!array_key_exists($question->unit[$i], $unitalreadyinsert)) {
|
||||
$unitalreadyinsert[$question->unit[$i]] = 1;
|
||||
@ -655,7 +655,7 @@ class qtype_numerical_answer_processor {
|
||||
|
||||
$numberstring = $matches[0];
|
||||
if ($this->unitsbefore) {
|
||||
// substr returns false when it means '', so cast back to string.
|
||||
// Substr returns false when it means '', so cast back to string.
|
||||
$unit = (string) substr($response, 0, -strlen($numberstring));
|
||||
} else {
|
||||
$unit = (string) substr($response, strlen($numberstring));
|
||||
@ -671,7 +671,7 @@ class qtype_numerical_answer_processor {
|
||||
$multiplier = null;
|
||||
}
|
||||
|
||||
return array($numberstring + 0, $unit, $multiplier); // + 0 to convert to number.
|
||||
return array($numberstring + 0, $unit, $multiplier); // The + 0 is to convert to number.
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -610,7 +610,7 @@ abstract class question_graded_automatically extends question_with_responses
|
||||
return false;
|
||||
}
|
||||
$hint = $qa->get_applicable_hint();
|
||||
$hintid = reset($args); // itemid is hint id.
|
||||
$hintid = reset($args); // Itemid is hint id.
|
||||
return $hintid == $hint->id;
|
||||
}
|
||||
|
||||
|
@ -333,7 +333,7 @@ class question_type {
|
||||
// This default implementation is suitable for most
|
||||
// question types.
|
||||
|
||||
// First, save the basic question itself
|
||||
// First, save the basic question itself.
|
||||
$question->name = trim($form->name);
|
||||
$question->parent = isset($form->parent) ? $form->parent : 0;
|
||||
$question->length = $this->actual_number_of_questions($question);
|
||||
@ -372,7 +372,7 @@ class question_type {
|
||||
|
||||
// If the question is new, create it.
|
||||
if (empty($question->id)) {
|
||||
// Set the unique code
|
||||
// Set the unique code.
|
||||
$question->stamp = make_unique_id_code();
|
||||
$question->createdby = $USER->id;
|
||||
$question->timecreated = time();
|
||||
@ -381,7 +381,7 @@ class question_type {
|
||||
|
||||
// Now, whether we are updating a existing question, or creating a new
|
||||
// one, we have to do the files processing and update the record.
|
||||
/// Question already exists, update.
|
||||
// Question already exists, update.
|
||||
$question->modifiedby = $USER->id;
|
||||
$question->timemodified = time();
|
||||
|
||||
@ -398,13 +398,13 @@ class question_type {
|
||||
}
|
||||
$DB->update_record('question', $question);
|
||||
|
||||
// Now to save all the answers and type-specific options
|
||||
// Now to save all the answers and type-specific options.
|
||||
$form->id = $question->id;
|
||||
$form->qtype = $question->qtype;
|
||||
$form->category = $question->category;
|
||||
$form->questiontext = $question->questiontext;
|
||||
$form->questiontextformat = $question->questiontextformat;
|
||||
// current context
|
||||
// Current context.
|
||||
$form->context = $context;
|
||||
|
||||
$result = $this->save_question_options($form);
|
||||
@ -422,7 +422,7 @@ class question_type {
|
||||
'$result->noticeyesno no longer supported in save_question.');
|
||||
}
|
||||
|
||||
// Give the question a unique version stamp determined by question_hash()
|
||||
// Give the question a unique version stamp determined by question_hash().
|
||||
$DB->set_field('question', 'version', question_hash($question),
|
||||
array('id' => $question->id));
|
||||
|
||||
@ -679,12 +679,12 @@ class question_type {
|
||||
$question->createdby = $questiondata->createdby;
|
||||
$question->modifiedby = $questiondata->modifiedby;
|
||||
|
||||
//Fill extra question fields values
|
||||
// Fill extra question fields values.
|
||||
$extraquestionfields = $this->extra_question_fields();
|
||||
if (is_array($extraquestionfields)) {
|
||||
//omit table name
|
||||
// Omit table name.
|
||||
array_shift($extraquestionfields);
|
||||
foreach($extraquestionfields as $field) {
|
||||
foreach ($extraquestionfields as $field) {
|
||||
$question->$field = $questiondata->options->$field;
|
||||
}
|
||||
}
|
||||
@ -805,7 +805,7 @@ class question_type {
|
||||
* Question type specific information is included.
|
||||
*/
|
||||
public function actual_number_of_questions($question) {
|
||||
// By default, each question is given one number
|
||||
// By default, each question is given one number.
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -885,11 +885,11 @@ class question_type {
|
||||
* @return bool Whether the wizard's last page was submitted or not.
|
||||
*/
|
||||
public function finished_edit_wizard($form) {
|
||||
//In the default case there is only one edit page.
|
||||
// In the default case there is only one edit page.
|
||||
return true;
|
||||
}
|
||||
|
||||
/// IMPORT/EXPORT FUNCTIONS /////////////////
|
||||
// IMPORT/EXPORT FUNCTIONS --------------------------------- .
|
||||
|
||||
/*
|
||||
* Imports question from the Moodle XML format
|
||||
@ -908,7 +908,7 @@ class question_type {
|
||||
return false;
|
||||
}
|
||||
|
||||
//omit table name
|
||||
// Omit table name.
|
||||
array_shift($extraquestionfields);
|
||||
$qo = $format->import_headers($data);
|
||||
$qo->qtype = $question_type;
|
||||
@ -917,7 +917,7 @@ class question_type {
|
||||
$qo->$field = $format->getpath($data, array('#', $field, 0, '#'), '');
|
||||
}
|
||||
|
||||
// run through the answers
|
||||
// Run through the answers.
|
||||
$answers = $data['#']['answer'];
|
||||
$a_count = 0;
|
||||
$extraanswersfields = $this->extra_answer_fields();
|
||||
@ -956,7 +956,7 @@ class question_type {
|
||||
return false;
|
||||
}
|
||||
|
||||
//omit table name
|
||||
// Omit table name.
|
||||
array_shift($extraquestionfields);
|
||||
$expout='';
|
||||
foreach ($extraquestionfields as $field) {
|
||||
|
@ -49,20 +49,20 @@ class restore_qtype_random_plugin extends restore_qtype_plugin {
|
||||
|
||||
$answer = $state->answer;
|
||||
$result = '';
|
||||
// randomxx-yy answer format
|
||||
// Randomxx-yy answer format.
|
||||
if (preg_match('~^random([0-9]+)-(.*)$~', $answer, $matches)) {
|
||||
$questionid = $matches[1];
|
||||
$subanswer = $matches[2];
|
||||
$newquestionid = $this->get_mappingid('question', $questionid);
|
||||
$questionqtype = $DB->get_field('question', 'qtype', array('id' => $newquestionid));
|
||||
// Delegate subanswer recode to proper qtype, faking one question_states record
|
||||
// Delegate subanswer recode to proper qtype, faking one question_states record.
|
||||
$substate = new stdClass();
|
||||
$substate->question = $newquestionid;
|
||||
$substate->answer = $subanswer;
|
||||
$newanswer = $this->step->restore_recode_legacy_answer($substate, $questionqtype);
|
||||
$result = 'random' . $newquestionid . '-' . $newanswer;
|
||||
|
||||
// simple question id format
|
||||
// Simple question id format.
|
||||
} else {
|
||||
$newquestionid = $this->get_mappingid('question', $answer);
|
||||
$result = $newquestionid;
|
||||
|
@ -72,8 +72,8 @@ class qtype_random_edit_form extends question_edit_form {
|
||||
}
|
||||
|
||||
public function validation($fromform, $files) {
|
||||
//validation of category
|
||||
//is not relevant for this question type
|
||||
// Validation of category is not relevant for this question type.
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
|
@ -84,7 +84,7 @@ class qtype_random extends question_type {
|
||||
$categorylist = array($question->category);
|
||||
}
|
||||
list($qcsql, $qcparams) = $DB->get_in_or_equal($categorylist);
|
||||
// TODO use in_or_equal for $otherquestionsinuse and $this->manualqtypes
|
||||
// TODO use in_or_equal for $otherquestionsinuse and $this->manualqtypes.
|
||||
return $DB->record_exists_select('question',
|
||||
"category $qcsql
|
||||
AND parent = 0
|
||||
|
@ -38,23 +38,23 @@ class backup_qtype_randomsamatch_plugin extends backup_qtype_plugin {
|
||||
*/
|
||||
protected function define_question_plugin_structure() {
|
||||
|
||||
// Define the virtual plugin element with the condition to fulfill
|
||||
// Define the virtual plugin element with the condition to fulfill.
|
||||
$plugin = $this->get_plugin_element(null, '../../qtype', 'randomsamatch');
|
||||
|
||||
// Create one standard named plugin element (the visible container)
|
||||
// Create one standard named plugin element (the visible container).
|
||||
$pluginwrapper = new backup_nested_element($this->get_recommended_name());
|
||||
|
||||
// connect the visible container ASAP
|
||||
// Connect the visible container ASAP.
|
||||
$plugin->add_child($pluginwrapper);
|
||||
|
||||
// Now create the qtype own structures
|
||||
// Now create the qtype own structures.
|
||||
$randomsamatch = new backup_nested_element('randomsamatch', array('id'), array(
|
||||
'choose'));
|
||||
|
||||
// Now the own qtype tree
|
||||
// Now the own qtype tree.
|
||||
$pluginwrapper->add_child($randomsamatch);
|
||||
|
||||
// set source to populate the data
|
||||
// Set source to populate the data.
|
||||
$randomsamatch->set_source_table('question_randomsamatch',
|
||||
array('question' => backup::VAR_PARENTID));
|
||||
|
||||
|
@ -46,7 +46,7 @@ class restore_qtype_randomsamatch_plugin extends restore_qtype_plugin {
|
||||
$elepath = $this->get_pathfor('/randomsamatch');
|
||||
$paths[] = new restore_path_element($elename, $elepath);
|
||||
|
||||
return $paths; // And we return the interesting paths
|
||||
return $paths; // And we return the interesting paths.
|
||||
}
|
||||
|
||||
/**
|
||||
@ -58,19 +58,19 @@ class restore_qtype_randomsamatch_plugin extends restore_qtype_plugin {
|
||||
$data = (object)$data;
|
||||
$oldid = $data->id;
|
||||
|
||||
// Detect if the question is created or mapped
|
||||
// Detect if the question is created or mapped.
|
||||
$oldquestionid = $this->get_old_parentid('question');
|
||||
$newquestionid = $this->get_new_parentid('question');
|
||||
$questioncreated = $this->get_mappingid('question_created', $oldquestionid) ? true : false;
|
||||
|
||||
// If the question has been created by restore, we need to create its
|
||||
// question_randomsamatch too
|
||||
// question_randomsamatch too.
|
||||
if ($questioncreated) {
|
||||
// Adjust some columns
|
||||
// Adjust some columns.
|
||||
$data->question = $newquestionid;
|
||||
// Insert record
|
||||
// Insert record.
|
||||
$newitemid = $DB->insert_record('question_randomsamatch', $data);
|
||||
// Create mapping
|
||||
// Create mapping.
|
||||
$this->set_mapping('question_randomsamatch', $oldid, $newitemid);
|
||||
}
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ class qtype_randomsamatch extends question_type {
|
||||
|
||||
// This could be included as a flag in the database. It's already
|
||||
// supported by the code.
|
||||
// Recurse subcategories: 0 = no recursion, 1 = recursion
|
||||
// Recurse subcategories: 0 = no recursion, 1 = recursion .
|
||||
$question->options->subcats = 1;
|
||||
return true;
|
||||
|
||||
@ -95,14 +95,14 @@ class qtype_randomsamatch extends question_type {
|
||||
// quiz. Therfore the following need to be excluded:
|
||||
// 1. All questions that are explicitly assigned to the quiz
|
||||
// 2. All random questions
|
||||
// 3. All questions that are already chosen by an other random question
|
||||
// 3. All questions that are already chosen by an other random question.
|
||||
global $QTYPES, $OUTPUT, $USER;
|
||||
if (!isset($cmoptions->questionsinuse)) {
|
||||
$cmoptions->questionsinuse = $cmoptions->questions;
|
||||
}
|
||||
|
||||
if ($question->options->subcats) {
|
||||
// recurse into subcategories
|
||||
// Recurse into subcategories.
|
||||
$categorylist = question_categorylist($question->category);
|
||||
} else {
|
||||
$categorylist = array($question->category);
|
||||
@ -117,13 +117,13 @@ class qtype_randomsamatch extends question_type {
|
||||
$question->questiontext = "Insufficient selection options are
|
||||
available for this question, therefore it is not available in this
|
||||
quiz. Please inform your teacher.";
|
||||
// Treat this as a description from this point on
|
||||
// Treat this as a description from this point on.
|
||||
$question->qtype = 'description';
|
||||
return true;
|
||||
}
|
||||
|
||||
$saquestions =
|
||||
draw_rand_array($saquestions, $question->options->choose); // from bug 1889
|
||||
draw_rand_array($saquestions, $question->options->choose); // From bug 1889.
|
||||
|
||||
foreach ($saquestions as $key => $wrappedquestion) {
|
||||
if (!$QTYPES[$wrappedquestion->qtype]
|
||||
@ -155,12 +155,12 @@ class qtype_randomsamatch extends question_type {
|
||||
$state->options->subquestions[$key] = clone($wrappedquestion);
|
||||
}
|
||||
|
||||
// Shuffle the answers (Do this always because this is a random question type)
|
||||
// Shuffle the answers (Do this always because this is a random question type).
|
||||
$subquestionids = array_values(array_map(create_function('$val',
|
||||
'return $val->id;'), $state->options->subquestions));
|
||||
$subquestionids = swapshuffle($subquestionids);
|
||||
|
||||
// Create empty responses
|
||||
// Create empty responses.
|
||||
foreach ($subquestionids as $val) {
|
||||
$state->responses[$val] = '';
|
||||
}
|
||||
@ -175,14 +175,14 @@ class qtype_randomsamatch extends question_type {
|
||||
$question->questiontext = "Insufficient selection options are
|
||||
available for this question, therefore it is not available in this
|
||||
quiz. Please inform your teacher.";
|
||||
// Treat this as a description from this point on
|
||||
// Treat this as a description from this point on.
|
||||
$question->qtype = 'description';
|
||||
} else {
|
||||
$responses = explode(',', $state->responses['']);
|
||||
$responses = array_map(create_function('$val',
|
||||
'return explode("-", $val);'), $responses);
|
||||
|
||||
// Restore the previous responses
|
||||
// Restore the previous responses.
|
||||
$state->responses = array();
|
||||
foreach ($responses as $response) {
|
||||
$wqid = $response[0];
|
||||
|
@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
@ -44,12 +43,12 @@ class moodle1_qtype_shortanswer_handler extends moodle1_qtype_handler {
|
||||
*/
|
||||
public function process_question(array $data, array $raw) {
|
||||
|
||||
// convert and write the answers first
|
||||
// Convert and write the answers first.
|
||||
if (isset($data['answers'])) {
|
||||
$this->write_answers($data['answers'], $this->pluginname);
|
||||
}
|
||||
|
||||
// convert and write the shortanswer extra fields
|
||||
// Convert and write the shortanswer extra fields.
|
||||
foreach ($data['shortanswer'] as $shortanswer) {
|
||||
$shortanswer['id'] = $this->converter->get_nextid();
|
||||
$this->write_xml('shortanswer', $shortanswer, array('/shortanswer/id'));
|
||||
|
@ -38,30 +38,30 @@ class backup_qtype_shortanswer_plugin extends backup_qtype_plugin {
|
||||
*/
|
||||
protected function define_question_plugin_structure() {
|
||||
|
||||
// Define the virtual plugin element with the condition to fulfill
|
||||
// Define the virtual plugin element with the condition to fulfill.
|
||||
$plugin = $this->get_plugin_element(null, '../../qtype', 'shortanswer');
|
||||
|
||||
// Create one standard named plugin element (the visible container)
|
||||
// Create one standard named plugin element (the visible container).
|
||||
$pluginwrapper = new backup_nested_element($this->get_recommended_name());
|
||||
|
||||
// connect the visible container ASAP
|
||||
// Connect the visible container ASAP.
|
||||
$plugin->add_child($pluginwrapper);
|
||||
|
||||
// This qtype uses standard question_answers, add them here
|
||||
// to the tree before any other information that will use them
|
||||
// to the tree before any other information that will use them.
|
||||
$this->add_question_question_answers($pluginwrapper);
|
||||
|
||||
// Now create the qtype own structures
|
||||
// Now create the qtype own structures.
|
||||
$shortanswer = new backup_nested_element('shortanswer', array('id'), array('usecase'));
|
||||
|
||||
// Now the own qtype tree
|
||||
// Now the own qtype tree.
|
||||
$pluginwrapper->add_child($shortanswer);
|
||||
|
||||
// set source to populate the data
|
||||
// Set source to populate the data.
|
||||
$shortanswer->set_source_table('qtype_shortanswer_options',
|
||||
array('questionid' => backup::VAR_PARENTID));
|
||||
|
||||
// don't need to annotate ids nor files
|
||||
// Don't need to annotate ids nor files.
|
||||
|
||||
return $plugin;
|
||||
}
|
||||
|
@ -41,16 +41,16 @@ class restore_qtype_shortanswer_plugin extends restore_qtype_plugin {
|
||||
|
||||
$paths = array();
|
||||
|
||||
// This qtype uses question_answers, add them
|
||||
// This qtype uses question_answers, add them.
|
||||
$this->add_question_question_answers($paths);
|
||||
|
||||
// Add own qtype stuff
|
||||
// Add own qtype stuff.
|
||||
$elename = 'shortanswer';
|
||||
// we used get_recommended_name() so this works
|
||||
// We used get_recommended_name() so this works.
|
||||
$elepath = $this->get_pathfor('/shortanswer');
|
||||
$paths[] = new restore_path_element($elename, $elepath);
|
||||
|
||||
return $paths; // And we return the interesting paths
|
||||
return $paths; // And we return the interesting paths.
|
||||
}
|
||||
|
||||
/**
|
||||
@ -62,7 +62,7 @@ class restore_qtype_shortanswer_plugin extends restore_qtype_plugin {
|
||||
$data = (object)$data;
|
||||
$oldid = $data->id;
|
||||
|
||||
// Detect if the question is created or mapped
|
||||
// Detect if the question is created or mapped.
|
||||
$oldquestionid = $this->get_old_parentid('question');
|
||||
$newquestionid = $this->get_new_parentid('question');
|
||||
$questioncreated = $this->get_mappingid('question_created', $oldquestionid) ? true : false;
|
||||
|
@ -36,8 +36,8 @@ function xmldb_qtype_shortanswer_upgrade($oldversion) {
|
||||
|
||||
$dbman = $DB->get_manager();
|
||||
|
||||
// Moodle v2.4.0 release upgrade line
|
||||
// Put any upgrade step following this
|
||||
// Moodle v2.4.0 release upgrade line.
|
||||
// Put any upgrade step following this.
|
||||
|
||||
if ($oldversion < 2013011800) {
|
||||
|
||||
@ -56,14 +56,14 @@ function xmldb_qtype_shortanswer_upgrade($oldversion) {
|
||||
|
||||
if ($oldversion < 2013011801) {
|
||||
|
||||
// Define key question (foreign) to be dropped form question_shortanswer
|
||||
// Define key question (foreign) to be dropped form question_shortanswer.
|
||||
$table = new xmldb_table('question_shortanswer');
|
||||
$key = new xmldb_key('question', XMLDB_KEY_FOREIGN, array('question'), 'question', array('id'));
|
||||
|
||||
// Launch drop key question
|
||||
// Launch drop key question.
|
||||
$dbman->drop_key($table, $key);
|
||||
|
||||
// shortanswer savepoint reached
|
||||
// Shortanswer savepoint reached.
|
||||
upgrade_plugin_savepoint(true, 2013011801, 'qtype', 'shortanswer');
|
||||
}
|
||||
|
||||
@ -82,26 +82,26 @@ function xmldb_qtype_shortanswer_upgrade($oldversion) {
|
||||
|
||||
if ($oldversion < 2013011803) {
|
||||
|
||||
// Define key questionid (foreign-unique) to be added to question_shortanswer
|
||||
// Define key questionid (foreign-unique) to be added to question_shortanswer.
|
||||
$table = new xmldb_table('question_shortanswer');
|
||||
$key = new xmldb_key('questionid', XMLDB_KEY_FOREIGN_UNIQUE, array('questionid'), 'question', array('id'));
|
||||
|
||||
// Launch add key questionid
|
||||
// Launch add key questionid.
|
||||
$dbman->add_key($table, $key);
|
||||
|
||||
// shortanswer savepoint reached
|
||||
// Shortanswer savepoint reached.
|
||||
upgrade_plugin_savepoint(true, 2013011803, 'qtype', 'shortanswer');
|
||||
}
|
||||
|
||||
if ($oldversion < 2013011804) {
|
||||
|
||||
// Define table qtype_shortanswer_options to be renamed to qtype_shortanswer_options
|
||||
// Define table qtype_shortanswer_options to be renamed to qtype_shortanswer_options.
|
||||
$table = new xmldb_table('question_shortanswer');
|
||||
|
||||
// Launch rename table for qtype_shortanswer_options
|
||||
// Launch rename table for qtype_shortanswer_options.
|
||||
$dbman->rename_table($table, 'qtype_shortanswer_options');
|
||||
|
||||
// shortanswer savepoint reached
|
||||
// Shortanswer savepoint reached.
|
||||
upgrade_plugin_savepoint(true, 2013011804, 'qtype', 'shortanswer');
|
||||
}
|
||||
|
||||
|
@ -162,7 +162,7 @@ class qtype_shortanswer_question extends question_graded_by_strategy
|
||||
if ($component == 'question' && $filearea == 'answerfeedback') {
|
||||
$currentanswer = $qa->get_last_qt_var('answer');
|
||||
$answer = $this->get_matching_answer(array('answer' => $currentanswer));
|
||||
$answerid = reset($args); // itemid is answer id.
|
||||
$answerid = reset($args); // Itemid is answer id.
|
||||
return $options->feedback && $answer && $answerid == $answer->id;
|
||||
|
||||
} else if ($component == 'question' && $filearea == 'hint') {
|
||||
|
@ -65,7 +65,7 @@ class qtype_shortanswer extends question_type {
|
||||
|
||||
$maxfraction = -1;
|
||||
|
||||
// Insert all the new answers
|
||||
// Insert all the new answers.
|
||||
foreach ($question->answer as $key => $answerdata) {
|
||||
// Check for, and ignore, completely blank answer from the form.
|
||||
if (trim($answerdata) == '' && $question->fraction[$key] == 0 &&
|
||||
@ -97,7 +97,7 @@ class qtype_shortanswer extends question_type {
|
||||
|
||||
$parentresult = parent::save_question_options($question);
|
||||
if ($parentresult !== null) {
|
||||
// Parent function returns null if all is OK
|
||||
// Parent function returns null if all is OK.
|
||||
return $parentresult;
|
||||
}
|
||||
|
||||
|
@ -103,12 +103,12 @@ class qtype_shortanswer_question_test extends advanced_testcase {
|
||||
$this->assertTrue((bool)qtype_shortanswer_question::compare_string_with_wildcard(
|
||||
'\{}/', '\{}/', true));
|
||||
|
||||
// See http://moodle.org/mod/forum/discuss.php?d=120557
|
||||
// See http://moodle.org/mod/forum/discuss.php?d=120557.
|
||||
$this->assertTrue((bool)qtype_shortanswer_question::compare_string_with_wildcard(
|
||||
'ITÁLIE', 'Itálie', true));
|
||||
|
||||
if (function_exists('normalizer_normalize')) {
|
||||
// Test ambiguous unicode representations
|
||||
// Test ambiguous unicode representations.
|
||||
$this->assertTrue((bool)qtype_shortanswer_question::compare_string_with_wildcard(
|
||||
'départ', 'DÉPART', true));
|
||||
$this->assertFalse((bool)qtype_shortanswer_question::compare_string_with_wildcard(
|
||||
|
@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
@ -44,12 +43,12 @@ class moodle1_qtype_truefalse_handler extends moodle1_qtype_handler {
|
||||
*/
|
||||
public function process_question(array $data, array $raw) {
|
||||
|
||||
// convert and write the answers first
|
||||
// Convert and write the answers first.
|
||||
if (isset($data['answers'])) {
|
||||
$this->write_answers($data['answers'], $this->pluginname);
|
||||
}
|
||||
|
||||
// convert and write the truefalse extra fields
|
||||
// Convert and write the truefalse extra fields.
|
||||
foreach ($data['truefalse'] as $truefalse) {
|
||||
$truefalse['id'] = $this->converter->get_nextid();
|
||||
$this->write_xml('truefalse', $truefalse, array('/truefalse/id'));
|
||||
|
@ -38,31 +38,31 @@ class backup_qtype_truefalse_plugin extends backup_qtype_plugin {
|
||||
*/
|
||||
protected function define_question_plugin_structure() {
|
||||
|
||||
// Define the virtual plugin element with the condition to fulfill
|
||||
// Define the virtual plugin element with the condition to fulfill.
|
||||
$plugin = $this->get_plugin_element(null, '../../qtype', 'truefalse');
|
||||
|
||||
// Create one standard named plugin element (the visible container)
|
||||
// Create one standard named plugin element (the visible container).
|
||||
$pluginwrapper = new backup_nested_element($this->get_recommended_name());
|
||||
|
||||
// connect the visible container ASAP
|
||||
// Connect the visible container ASAP.
|
||||
$plugin->add_child($pluginwrapper);
|
||||
|
||||
// This qtype uses standard question_answers, add them here
|
||||
// to the tree before any other information that will use them
|
||||
// to the tree before any other information that will use them.
|
||||
$this->add_question_question_answers($pluginwrapper);
|
||||
|
||||
// Now create the qtype own structures
|
||||
// Now create the qtype own structures.
|
||||
$truefalse = new backup_nested_element('truefalse', array('id'), array(
|
||||
'trueanswer', 'falseanswer'));
|
||||
|
||||
// Now the own qtype tree
|
||||
// Now the own qtype tree.
|
||||
$pluginwrapper->add_child($truefalse);
|
||||
|
||||
// set source to populate the data
|
||||
// Set source to populate the data.
|
||||
$truefalse->set_source_table('question_truefalse',
|
||||
array('question' => backup::VAR_PARENTID));
|
||||
|
||||
// don't need to annotate ids nor files
|
||||
// Don't need to annotate ids nor files.
|
||||
|
||||
return $plugin;
|
||||
}
|
||||
|
@ -41,15 +41,15 @@ class restore_qtype_truefalse_plugin extends restore_qtype_plugin {
|
||||
|
||||
$paths = array();
|
||||
|
||||
// This qtype uses question_answers, add them
|
||||
// This qtype uses question_answers, add them.
|
||||
$this->add_question_question_answers($paths);
|
||||
|
||||
// Add own qtype stuff
|
||||
// Add own qtype stuff.
|
||||
$elename = 'truefalse';
|
||||
$elepath = $this->get_pathfor('/truefalse'); // we used get_recommended_name() so this works
|
||||
$elepath = $this->get_pathfor('/truefalse'); // We used get_recommended_name() so this works.
|
||||
$paths[] = new restore_path_element($elename, $elepath);
|
||||
|
||||
return $paths; // And we return the interesting paths
|
||||
return $paths; // And we return the interesting paths.
|
||||
}
|
||||
|
||||
/**
|
||||
@ -61,20 +61,20 @@ class restore_qtype_truefalse_plugin extends restore_qtype_plugin {
|
||||
$data = (object)$data;
|
||||
$oldid = $data->id;
|
||||
|
||||
// Detect if the question is created or mapped
|
||||
// Detect if the question is created or mapped.
|
||||
$oldquestionid = $this->get_old_parentid('question');
|
||||
$newquestionid = $this->get_new_parentid('question');
|
||||
$questioncreated = $this->get_mappingid('question_created', $oldquestionid) ? true : false;
|
||||
|
||||
// If the question has been created by restore, we need to create its question_truefalse too
|
||||
// If the question has been created by restore, we need to create its question_truefalse too.
|
||||
if ($questioncreated) {
|
||||
// Adjust some columns
|
||||
// Adjust some columns.
|
||||
$data->question = $newquestionid;
|
||||
$data->trueanswer = $this->get_mappingid('question_answer', $data->trueanswer);
|
||||
$data->falseanswer = $this->get_mappingid('question_answer', $data->falseanswer);
|
||||
// Insert record
|
||||
// Insert record.
|
||||
$newitemid = $DB->insert_record('question_truefalse', $data);
|
||||
// Create mapping
|
||||
// Create mapping.
|
||||
$this->set_mapping('question_truefalse', $oldid, $newitemid);
|
||||
}
|
||||
}
|
||||
|
@ -80,13 +80,13 @@ class qtype_truefalse_edit_form extends question_edit_form {
|
||||
$question->feedbacktrue = array();
|
||||
$question->feedbacktrue['format'] = $trueanswer->feedbackformat;
|
||||
$question->feedbacktrue['text'] = file_prepare_draft_area(
|
||||
$draftid, // draftid
|
||||
$draftid, // Draftid
|
||||
$this->context->id, // context
|
||||
'question', // component
|
||||
'answerfeedback', // filarea
|
||||
!empty($answerid) ? (int) $answerid : null, // itemid
|
||||
$this->fileoptions, // options
|
||||
$trueanswer->feedback // text
|
||||
$trueanswer->feedback // text.
|
||||
);
|
||||
$question->feedbacktrue['itemid'] = $draftid;
|
||||
}
|
||||
@ -100,13 +100,13 @@ class qtype_truefalse_edit_form extends question_edit_form {
|
||||
$question->feedbackfalse = array();
|
||||
$question->feedbackfalse['format'] = $falseanswer->feedbackformat;
|
||||
$question->feedbackfalse['text'] = file_prepare_draft_area(
|
||||
$draftid, // draftid
|
||||
$draftid, // Draftid
|
||||
$this->context->id, // context
|
||||
'question', // component
|
||||
'answerfeedback', // filarea
|
||||
!empty($answerid) ? (int) $answerid : null, // itemid
|
||||
$this->fileoptions, // options
|
||||
$falseanswer->feedback // text
|
||||
$falseanswer->feedback // text.
|
||||
);
|
||||
$question->feedbackfalse['itemid'] = $draftid;
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ class qtype_truefalse_question extends question_graded_automatically {
|
||||
|
||||
public function check_file_access($qa, $options, $component, $filearea, $args, $forcedownload) {
|
||||
if ($component == 'question' && $filearea == 'answerfeedback') {
|
||||
$answerid = reset($args); // itemid is answer id.
|
||||
$answerid = reset($args); // Itemid is answer id.
|
||||
$response = $qa->get_last_qt_var('answer', '');
|
||||
return $options->feedback && (
|
||||
($answerid == $this->trueanswerid && $response) ||
|
||||
|
@ -41,7 +41,7 @@ class qtype_truefalse extends question_type {
|
||||
$result = new stdClass();
|
||||
$context = $question->context;
|
||||
|
||||
// Fetch old answer ids so that we can reuse them
|
||||
// Fetch old answer ids so that we can reuse them.
|
||||
$oldanswers = $DB->get_records('question_answers',
|
||||
array('question' => $question->id), 'id ASC');
|
||||
|
||||
@ -88,10 +88,10 @@ class qtype_truefalse extends question_type {
|
||||
$DB->delete_records('question_answers', array('id' => $oldanswer->id));
|
||||
}
|
||||
|
||||
// Save question options in question_truefalse table
|
||||
// Save question options in question_truefalse table.
|
||||
if ($options = $DB->get_record('question_truefalse', array('question' => $question->id))) {
|
||||
// No need to do anything, since the answer IDs won't have changed
|
||||
// But we'll do it anyway, just for robustness
|
||||
// But we'll do it anyway, just for robustness.
|
||||
$options->trueanswer = $trueid;
|
||||
$options->falseanswer = $falseid;
|
||||
$DB->update_record('question_truefalse', $options);
|
||||
@ -114,13 +114,13 @@ class qtype_truefalse extends question_type {
|
||||
public function get_question_options($question) {
|
||||
global $DB, $OUTPUT;
|
||||
// Get additional information from database
|
||||
// and attach it to the question object
|
||||
// and attach it to the question object.
|
||||
if (!$question->options = $DB->get_record('question_truefalse',
|
||||
array('question' => $question->id))) {
|
||||
echo $OUTPUT->notification('Error: Missing question options!');
|
||||
return false;
|
||||
}
|
||||
// Load the answers
|
||||
// Load the answers.
|
||||
if (!$question->options->answers = $DB->get_records('question_answers',
|
||||
array('question' => $question->id), 'id ASC')) {
|
||||
echo $OUTPUT->notification('Error: Missing question answers for truefalse question ' .
|
||||
|
@ -59,7 +59,7 @@ class qtype_truefalse_renderer extends qtype_renderer {
|
||||
$falseattributes['disabled'] = 'disabled';
|
||||
}
|
||||
|
||||
// Work out which radio button to select (if any)
|
||||
// Work out which radio button to select (if any).
|
||||
$truechecked = false;
|
||||
$falsechecked = false;
|
||||
$responsearray = array();
|
||||
@ -108,9 +108,9 @@ class qtype_truefalse_renderer extends qtype_renderer {
|
||||
array('class' => 'r0' . $trueclass));
|
||||
$result .= html_writer::tag('div', $radiofalse . ' ' . $falsefeedbackimg,
|
||||
array('class' => 'r1' . $falseclass));
|
||||
$result .= html_writer::end_tag('div'); // answer
|
||||
$result .= html_writer::end_tag('div'); // Answer.
|
||||
|
||||
$result .= html_writer::end_tag('div'); // ablock
|
||||
$result .= html_writer::end_tag('div'); // Ablock.
|
||||
|
||||
if ($qa->get_state() == question_state::$invalid) {
|
||||
$result .= html_writer::nonempty_tag('div',
|
||||
|
@ -65,11 +65,11 @@ class qtype_truefalse_question_test extends advanced_testcase {
|
||||
public function test_get_correct_response() {
|
||||
$question = test_question_maker::make_question('truefalse', 'true');
|
||||
|
||||
// true
|
||||
// True.
|
||||
$this->assertSame(array('answer' => 1),
|
||||
$question->get_correct_response());
|
||||
|
||||
// false
|
||||
// False.
|
||||
$question->rightanswer = false;
|
||||
$this->assertSame(array('answer' => 0),
|
||||
$question->get_correct_response());
|
||||
|
@ -966,7 +966,7 @@ class qtype_truefalse_attempt_upgrader_test extends question_attempt_upgrader_te
|
||||
$this->compare_qas($expectedqa, $qa);
|
||||
}
|
||||
|
||||
public function test_truefalse_adaptive_qsession3() {
|
||||
public function test_truefalse_adaptive_qsession3() {
|
||||
$quiz = (object) array(
|
||||
'id' => '1',
|
||||
'course' => '2',
|
||||
|
Loading…
x
Reference in New Issue
Block a user