MDL-79863 qtype_ordering: qtype/ordering use standard methods to add feedback in edit form

This commit is contained in:
Gordon Bateson 2015-01-14 19:09:21 +09:00 committed by Mathew May
parent fddcb15d8e
commit e1439562b3
8 changed files with 161 additions and 108 deletions

View File

@ -50,15 +50,18 @@ class backup_qtype_ordering_plugin extends backup_qtype_plugin {
$this->add_question_question_answers($pluginwrapper);
// Now create the qtype own structures
$fields = array('logical', 'studentsee', 'correctfeedback', 'incorrectfeedback', 'partiallycorrectfeedback');
$fields = array('logical', 'studentsee',
'correctfeedback', 'correctfeedbackformat',
'incorrectfeedback', 'incorrectfeedbackformat',
'partiallycorrectfeedback', 'partiallycorrectfeedbackformat');
$ordering = new backup_nested_element('ordering', array('id'), $fields);
// Now the own qtype tree
$pluginwrapper->add_child($ordering);
// set source to populate the data
$params = array('question' => backup::VAR_PARENTID);
$ordering->set_source_table('question_ordering', $params);
$params = array('questionid' => backup::VAR_PARENTID);
$ordering->set_source_table('qtype_ordering_options', $params);
// don't need to annotate ids nor files

View File

@ -60,20 +60,16 @@ class restore_qtype_ordering_plugin extends restore_qtype_plugin {
$oldid = $data->id;
// 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;
$oldquestionid = $this->get_old_parentid('questionid');
$newquestionid = $this->get_new_parentid('questionid');
// If the question has been created by restore, we need to create its question_ordering too
if ($questioncreated) {
// 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
$newitemid = $DB->insert_record('question_ordering', $data);
// Create mapping
$this->set_mapping('question_ordering', $oldid, $newitemid);
// If the question has been created by restore,
// we need to create a "qtype_ordering_options" record
// and create a mapping from the $oldid to the $newid
if ($this->get_mappingid('question_created', $oldquestionid)) {
$data->questionid = $newquestionid;
$newid = $DB->insert_record('qtype_ordering_options', $data);
$this->set_mapping('qtype_ordering_options', $oldid, $newid);
}
}

View File

@ -61,6 +61,75 @@ function xmldb_qtype_ordering_upgrade($oldversion) {
upgrade_plugin_savepoint(true, $newversion, 'qtype', 'ordering');
}
$newversion = 2015011408;
if ($oldversion < $newversion) {
// rename "ordering" table for Moodle >= 2.5
$oldname = 'question_ordering';
$newname = 'qtype_ordering_options';
$oldtable = new xmldb_table($oldname);
if ($dbman->table_exists($oldtable)) {
if ($dbman->table_exists($newname)) {
$dbman->drop_table($oldtable);
} else {
$dbman->rename_table($oldtable, $newname);
}
}
// remove index on question(id) field
// (because we want to modify the field)
$table = new xmldb_table('qtype_ordering_options');
$fields = array('question', 'questionid');
foreach ($fields as $field) {
if ($dbman->field_exists($table, $field)) {
$index = new xmldb_index('quesorde_que_ix', XMLDB_INDEX_NOTUNIQUE, array($field));
if ($dbman->index_exists($table, $index)) {
$dbman->drop_index($table, $index);
}
}
}
// add "feedbackformat" fields
$table = new xmldb_table('qtype_ordering_options');
$fields = array(
'questionid' => new xmldb_field('question', XMLDB_TYPE_INTEGER, '11', null, XMLDB_NOTNULL, null, '0', 'id'),
'correctfeedbackformat' => new xmldb_field('correctfeedbackformat', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, '0', 'correctfeedback'),
'incorrectfeedbackformat' => new xmldb_field('incorrectfeedbackformat', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, '0', 'incorrectfeedback'),
'partiallycorrectfeedbackformat' => new xmldb_field('partiallycorrectfeedbackformat', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, '0', 'partiallycorrectfeedback')
);
foreach ($fields as $newname => $field) {
$oldexists = $dbman->field_exists($table, $field);
$newexists = $dbman->field_exists($table, $newname);
if ($field->getName()==$newname) {
// same field name
} else if ($oldexists) {
if ($newexists) {
$dbman->drop_field($table, $field);
} else {
$dbman->rename_field($table, $field, $newname);
$newexists = true;
}
$oldexists = false;
}
$field->setName($newname);
if ($newexists) {
$dbman->change_field_type($table, $field);
} else {
$dbman->add_field($table, $field);
}
}
// restore index on questionid field
$table = new xmldb_table('qtype_ordering_options');
$index = new xmldb_index('quesorde_que_ix', XMLDB_INDEX_NOTUNIQUE, array('questionid'));
if (! $dbman->index_exists($table, $index)) {
$dbman->add_index($table, $index);
}
upgrade_plugin_savepoint(true, $newversion, 'qtype', 'ordering');
}
return true;
}

View File

@ -50,76 +50,62 @@ class qtype_ordering_edit_form extends question_edit_form {
*/
public function definition_inner($mform) {
$options = array(
0 => get_string('ordering_exactorder', 'qtype_ordering'), // = all ?
1 => get_string('ordering_relativeorder', 'qtype_ordering'), // = random subset
2 => get_string('ordering_contiguous', 'qtype_ordering') // = contiguous subset
0 => get_string('exactorder', 'qtype_ordering'), // = all ?
1 => get_string('relativeorder', 'qtype_ordering'), // = random subset
2 => get_string('contiguous', 'qtype_ordering') // = contiguous subset
);
$mform->addElement('select', 'logical', get_string('ordering_logicalpossibilities', 'qtype_ordering'), $options);
$mform->addElement('select', 'logical', get_string('logicalpossibilities', 'qtype_ordering'), $options);
$mform->setDefault('logical', 0);
$options = array(0 => 'All');
for ($i=3; $i <= 20; $i++) {
$options[] = $i;
}
$mform->addElement('select', 'studentsee', get_string('ordering_itemsforstudent', 'qtype_ordering'), $options);
$mform->addElement('select', 'studentsee', get_string('itemsforstudent', 'qtype_ordering'), $options);
$mform->setDefault('studentsee', 0);
$repeated = array();
$repeated[] =& $mform->createElement('header', 'choicehdr', get_string('ordering_choiceno', 'qtype_ordering', '{no}'));
$repeated[] =& $mform->createElement('textarea', 'answer', get_string('ordering_answer', 'qtype_ordering'), 'rows="3" cols="50"');
$elements = array();
$elements[] =& $mform->createElement('header', 'choicehdr', get_string('choiceno', 'qtype_ordering', '{no}'));
$elements[] =& $mform->createElement('textarea', 'answer', get_string('answer', 'qtype_ordering'), 'rows="3" cols="50"');
if (empty($this->question->options)){
$countanswers = 0;
$count = 0;
} else {
$countanswers = count($this->question->options->answers);
$count = count($this->question->options->answers);
}
if (self::NUM_ANS_START > ($countanswers + self::NUM_ANS_ADD)) {
$repeatsatstart = self::NUM_ANS_START;
} else {
$repeatsatstart = ($countanswers + self::NUM_ANS_ADD);
}
$repeatedoptions = array();
$repeatedoptions['fraction']['default'] = 0;
$start = max(self::NUM_ANS_START, $count + self::NUM_ANS_ADD);
$options = array('fraction' => array('default' => 0));
$mform->setType('answer', PARAM_NOTAGS);
$this->repeat_elements($repeated, $repeatsatstart, $repeatedoptions, 'noanswers', 'addanswers', self::NUM_ANS_ADD, get_string('ordering_addmoreanswers', 'qtype_ordering'));
$mform->addElement('header', 'overallfeedbackhdr', get_string('overallfeedback', 'qtype_ordering'));
$mform->addElement('htmleditor', 'correctfeedback', get_string('correctfeedback', 'qtype_ordering'));
$mform->setType('correctfeedback', PARAM_RAW);
$mform->addElement('htmleditor', 'partiallycorrectfeedback', get_string('partiallycorrectfeedback', 'qtype_ordering'));
$mform->setType('partiallycorrectfeedback', PARAM_RAW);
$mform->addElement('htmleditor', 'incorrectfeedback', get_string('incorrectfeedback', 'qtype_ordering'));
$mform->setType('incorrectfeedback', PARAM_RAW);
$label = get_string('addmoreanswers', 'qtype_ordering');
$this->repeat_elements($elements, $start, $options, 'noanswers', 'addanswers', self::NUM_ANS_ADD, $label);
$this->add_combined_feedback_fields();
}
public function data_preprocessing($question) {
$question = parent::data_preprocessing($question);
//$question = $this->data_preprocessing_answers($question, true);
//$question = $this->data_preprocessing_combined_feedback($question, true);
//$question = $this->data_preprocessing_hints($question, true, true);
$question = $this->data_preprocessing_combined_feedback($question);
if (!empty($question->options)){
$answers = $question->options->answers;
if (count($answers)) {
$key = 0;
foreach ($answers as $answerkey => $answer){
$default_values['answer['.$key.']'] = $answer->answer;
$default_values['fraction['.$key.']'] = $answerkey + 1;
//$default_values['feedback['.$key.']'] = $answer->feedback;
$key++;
if (isset($question->options->answers)) {
$i = 0;
foreach ($question->options->answers as $answer) {
if (trim($answer->answer)=='') {
continue; // skip empty answers
}
if ($i==0) {
$question->answer = array();
$question->fraction = array();
$question->logical = $question->options->logical;
$question->studentsee = $question->options->studentsee;
}
$question->answer[$i] = $answer->answer;
$question->fraction[$i] = ($i + 1);
$i++;
}
$default_values['studentsee'] = $question->options->studentsee;
$default_values['logical'] = $question->options->logical;
$question = (object)((array)$question + $default_values);
}
return $question;
@ -130,18 +116,15 @@ class qtype_ordering_edit_form extends question_edit_form {
$answercount = 0;
foreach ($data['answer'] as $answer){
$answer = trim($answer);
if ($answer || $answer==='0'){
if (trim($answer)=='') {
continue; // skip empty answer
}
$answercount++;
}
}
if ($answercount==0){
$errors['answer[0]'] = get_string('ordering_notenoughanswers', 'qtype_ordering', 2);
$errors['answer[1]'] = get_string('ordering_notenoughanswers', 'qtype_ordering', 2);
} elseif ($answercount==1){
$errors['answer[1]'] = get_string('ordering_notenoughanswers', 'qtype_ordering', 2);
switch ($answercount) {
case 0: $errors['answer[0]'] = get_string('notenoughanswers', 'qtype_ordering', 2);
case 1: $errors['answer[1]'] = get_string('notenoughanswers', 'qtype_ordering', 2);
}
return $errors;

View File

@ -20,31 +20,30 @@ $string['addingordering'] = 'Adding a Ordering';
$string['orderingsummary'] = 'Ordering summary';
$string['ordering'] = 'Ordering';
$string['ordering_exactorder'] = 'Exact order';
$string['ordering_relativeorder'] = 'Relative order';
$string['ordering_contiguous'] = 'Contiguous';
$string['exactorder'] = 'Exact order';
$string['relativeorder'] = 'Relative order';
$string['contiguous'] = 'Contiguous';
$string['ordering_logicalpossibilities'] = 'Logical possibilities';
$string['ordering_addmoreanswers'] = 'Blank for {no} more answers';
$string['logicalpossibilities'] = 'Logical possibilities';
$string['addmoreanswers'] = 'Blank for {no} more answers';
$string['ordering_choiceno'] = 'Answer {$a}';
$string['ordering_choices'] = 'Available answers';
$string['ordering_answer'] = 'Answer';
$string['choiceno'] = 'Answer {$a}';
$string['choices'] = 'Available answers';
$string['answer'] = 'Answer';
$string['ordering_itemsforstudent'] = 'How many items the student will see';
$string['itemsforstudent'] = 'How many items the student will see';
$string['correctorder'] = 'The correct order for these items is as follows:';
$string['noresponsedetails'] = 'Sorry, no details of the response to this question are available.';
$string['correctfeedback'] = 'Correct answer';
$string['incorrectfeedback'] = 'Incorrect answer';
$string['overallfeedback'] = 'Overall Feedback';
$string['partiallycorrectfeedback'] = 'Partially correct answer ({$a})';
$string['ordering_notenoughanswers'] = 'not enough answers';
//$string['correctfeedback'] = 'Correct answer';
//$string['incorrectfeedback'] = 'Incorrect answer';
//$string['overallfeedback'] = 'Overall Feedback';
//$string['partiallycorrectfeedback'] = 'Partially correct answer';
$string['notenoughanswers'] = 'not enough answers';
$string['ordering_comment'] = 'Drag and drop the items into the correct order.';
$string['comment'] = 'Drag and drop the items into the correct order.';
// TODO add any other requred strings.
$string['ordering_help'] = 'Ordering help';
$string['help'] = 'Ordering help';
$string['defaultquestionname'] = 'Put the following events into the correct order.';
?>

View File

@ -76,17 +76,20 @@ class qtype_ordering_question extends question_graded_automatically {
public function get_ordering_options() {
global $DB;
if ($this->options===null) {
$this->options = $DB->get_record('question_ordering', array('question' => $this->id));
$this->options = $DB->get_record('qtype_ordering_options', array('questionid' => $this->id));
if ($this->options==false) {
$this->options = (object)array(
'question' => $this->id,
'questionid' => $this->id,
'logical' => 0, // require all answers
'studentsee' => 0,
'correctfeedback' => '',
'correctfeedbackformat' => 0,
'incorrectfeedback' => '',
'incorrectfeedbackformat' => 0,
'partiallycorrectfeedback' => ''
'partiallycorrectfeedbackformat' => 0
);
$this->options->id = $DB->insert_record('question_ordering', $options);
$this->options->id = $DB->insert_record('qtype_ordering', $options);
}
}
return $this->options;

View File

@ -78,6 +78,7 @@ class qtype_ordering extends question_type {
global $DB;
$result = new stdClass();
$context = $question->context;
// remove empty answers
$question->answer = array_filter($question->answer, array($this, 'is_not_blank'));
@ -88,7 +89,7 @@ class qtype_ordering extends question_type {
// check at least two answers exist
if ($countanswers < 2) {
$result->notice = get_string('ordering_notenoughanswers', 'qtype_ordering', '2');
$result->notice = get_string('notenoughanswers', 'qtype_ordering', '2');
return $result;
}
@ -127,23 +128,22 @@ class qtype_ordering extends question_type {
// create $options for this ordering question
$options = (object)array(
'question' => $question->id,
'questionid' => $question->id,
'logical' => $question->logical,
'studentsee' => $question->studentsee,
'correctfeedback' => $question->correctfeedback,
'incorrectfeedback' => $question->incorrectfeedback,
'partiallycorrectfeedback' => $question->partiallycorrectfeedback
'studentsee' => $question->studentsee
);
$options = $this->save_combined_feedback_helper($options, $question, $context, true);
// add/update $options for this ordering question
if ($options->id = $DB->get_field('question_ordering', 'id', array('question' => $question->id))) {
if (! $DB->update_record('question_ordering', $options)) {
$result->error = get_string('cannotupdaterecord', 'error', 'question_ordering (id='.$options->id.')');
if ($options->id = $DB->get_field('qtype_ordering_options', 'id', array('questionid' => $question->id))) {
if (! $DB->update_record('qtype_ordering_options', $options)) {
$result->error = get_string('cannotupdaterecord', 'error', 'qtype_ordering_options (id='.$options->id.')');
return $result;
}
} else {
if (! $options->id = $DB->insert_record('question_ordering', $options)) {
$result->error = get_string('cannotinsertrecord', 'error', 'question_ordering');
unset($options->id);
if (! $options->id = $DB->insert_record('qtype_ordering_options', $options)) {
$result->error = get_string('cannotinsertrecord', 'error', 'qtype_ordering_options');
return $result;
}
}
@ -165,7 +165,7 @@ class qtype_ordering extends question_type {
global $DB, $OUTPUT;
// load the options
if (! $question->options = $DB->get_record('question_ordering', array('question' => $question->id))) {
if (! $question->options = $DB->get_record('qtype_ordering_options', array('questionid' => $question->id))) {
echo $OUTPUT->notification('Error: Missing question options!');
return false;
}
@ -185,7 +185,7 @@ class qtype_ordering extends question_type {
public function delete_question($questionid, $contextid) {
global $DB;
$DB->delete_records('question_ordering', array('question' => $questionid));
$DB->delete_records('qtype_ordering_options', array('questionid' => $questionid));
parent::delete_question($questionid, $contextid);
}

View File

@ -30,6 +30,6 @@ defined('MOODLE_INTERNAL') || die();
$plugin->cron = 0;
$plugin->component = 'qtype_ordering';
$plugin->maturity = MATURITY_STABLE; // ALPHA=50, BETA=100, RC=150, STABLE=200
$plugin->release = '2014-12-19 (07)';
$plugin->version = 2014121907;
$plugin->release = '2015-01-14 (08)';
$plugin->version = 2015011408;
$plugin->requires = 2010112400; // Moodle 2.0