Permalink
Browse files

MDL-10516 Pre-populated answer (template) in essay questions

  • Loading branch information...
1 parent eed5bb7 commit 60527d0c340a34079823c6a586f68c9d792e36ee Jean-Michel Vedrine committed with damyon Feb 10, 2013
@@ -729,6 +729,10 @@ public function import_essay($question) {
array('#', 'attachments', 0, '#'), 0);
$qo->graderinfo = $this->import_text_with_files($question,
array('#', 'graderinfo', 0), '', $this->get_format($qo->questiontextformat));
+ $qo->responsetemplate['text'] = $this->getpath($question,
+ array('#', 'responsetemplate', 0, '#', 'text', 0, '#'), '', true);
+ $qo->responsetemplate['format'] = $this->trans_format($this->getpath($question,
+ array('#', 'responsetemplate', 0, '@', 'format'), $this->get_format($qo->questiontextformat)));
return $qo;
}
@@ -1261,6 +1265,10 @@ public function writequestion($question) {
$expout .= $this->write_files($fs->get_area_files($contextid, 'qtype_essay',
'graderinfo', $question->id));
$expout .= " </graderinfo>\n";
+ $expout .= " <responsetemplate " .
+ $this->format($question->options->responsetemplateformat) . ">\n";
+ $expout .= $this->writetext($question->options->responsetemplate, 3);
+ $expout .= " </responsetemplate>\n";
break;
case 'calculated':
@@ -360,6 +360,8 @@ public function test_import_essay_20() {
$expectedq->attachments = 0;
$expectedq->graderinfo['text'] = '';
$expectedq->graderinfo['format'] = FORMAT_MOODLE;
+ $expectedq->responsetemplate['text'] = '';
+ $expectedq->responsetemplate['format'] = FORMAT_MOODLE;
$this->assert(new question_check_specified_fields_expectation($expectedq), $q);
}
@@ -384,6 +386,9 @@ public function test_import_essay_21() {
<graderinfo format="html">
<text><![CDATA[<p>Grade <b>generously</b>!</p>]]></text>
</graderinfo>
+ <responsetemplate format="html">
+ <text><![CDATA[<p>Here is something <b>really</b> interesting.</p>]]></text>
+ </responsetemplate>
</question>';
$xmldata = xmlize($xml);
@@ -404,6 +409,8 @@ public function test_import_essay_21() {
$expectedq->attachments = -1;
$expectedq->graderinfo['text'] = '<p>Grade <b>generously</b>!</p>';
$expectedq->graderinfo['format'] = FORMAT_HTML;
+ $expectedq->responsetemplate['text'] = '<p>Here is something <b>really</b> interesting.</p>';
+ $expectedq->responsetemplate['format'] = FORMAT_HTML;
$this->assert(new question_check_specified_fields_expectation($expectedq), $q);
}
@@ -430,7 +437,8 @@ public function test_export_essay() {
$qdata->options->attachments = -1;
$qdata->options->graderinfo = '<p>Grade <b>generously</b>!</p>';
$qdata->options->graderinfoformat = FORMAT_HTML;
-
+ $qdata->options->responsetemplate = '<p>Here is something <b>really</b> interesting.</p>';
+ $qdata->options->responsetemplateformat = FORMAT_HTML;
$exporter = new qformat_xml();
$xml = $exporter->writequestion($qdata);
@@ -454,6 +462,9 @@ public function test_export_essay() {
<graderinfo format="html">
<text><![CDATA[<p>Grade <b>generously</b>!</p>]]></text>
</graderinfo>
+ <responsetemplate format="html">
+ <text><![CDATA[<p>Here is something <b>really</b> interesting.</p>]]></text>
+ </responsetemplate>
</question>
';
@@ -42,12 +42,14 @@ public function get_question_subpaths() {
public function process_question(array $data, array $raw) {
// data added on the upgrade step 2011031000
$this->write_xml('essay', array(
- 'id' => $this->converter->get_nextid(),
- 'responseformat' => 'editor',
- 'responsefieldlines' => 15,
- 'attachments' => 0,
- 'graderinfo' => '',
- 'graderinfoformat' => FORMAT_MOODLE
+ 'id' => $this->converter->get_nextid(),
+ 'responseformat' => 'editor',
+ 'responsefieldlines' => 15,
+ 'attachments' => 0,
+ 'graderinfo' => '',
+ 'graderinfoformat' => FORMAT_MOODLE,
+ 'responsetemplate' => '',
+ 'responsetemplateformat' => FORMAT_MOODLE
), array('/essay/id'));
}
}
@@ -50,7 +50,8 @@ protected function define_question_plugin_structure() {
// Now create the qtype own structures
$essay = new backup_nested_element('essay', array('id'), array(
'responseformat', 'responsefieldlines', 'attachments',
- 'graderinfo', 'graderinfoformat'));
+ 'graderinfo', 'graderinfoformat', 'responsetemplate',
+ 'responsetemplateformat'));
// Now the own qtype tree
$pluginwrapper->add_child($essay);
@@ -52,6 +52,13 @@ public function process_essay($data) {
$data = (object)$data;
$oldid = $data->id;
+ if (!isset($data->responsetemplate)) {
+ $data->responsetemplate = '';
+ }
+ if (!isset($data->responsetemplateformat)) {
+ $data->responsetemplateformat = FORMAT_HTML;
+ }
+
// Detect if the question is created or mapped
$questioncreated = $this->get_mappingid('question_created',
$this->get_old_parentid('question')) ? true : false;
@@ -100,6 +107,8 @@ protected function after_execute_question() {
$defaultoptions->attachments = 0;
$defaultoptions->graderinfo = '';
$defaultoptions->graderinfoformat = FORMAT_HTML;
+ $defaultoptions->responsetemplate = '';
+ $defaultoptions->responsetemplateformat = FORMAT_HTML;
$DB->insert_record('qtype_essay_options', $defaultoptions);
}
}
@@ -13,6 +13,8 @@
<FIELD NAME="attachments" TYPE="int" LENGTH="4" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Whether, and how many, attachments a student is allowed to include with their response. -1 means unlimited."/>
<FIELD NAME="graderinfo" TYPE="text" NOTNULL="false" SEQUENCE="false" COMMENT="Information shown to people with permission to manually grade the question, when they are grading."/>
<FIELD NAME="graderinfoformat" TYPE="int" LENGTH="4" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="The text format for graderinfo."/>
+ <FIELD NAME="responsetemplate" TYPE="text" NOTNULL="false" SEQUENCE="false" COMMENT="The template to pre-populate student's response field during attempt."/>
+ <FIELD NAME="responsetemplateformat" TYPE="int" LENGTH="4" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="The text format for responsetemplate."/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
@@ -117,6 +117,28 @@ function xmldb_qtype_essay_upgrade($oldversion) {
upgrade_plugin_savepoint(true, 2013011800, 'qtype', 'essay');
}
+ if ($oldversion < 2013021700) {
+ // Create new fields responsetemplate and responsetemplateformat in qtyep_essay_options table.
+ $table = new xmldb_table('qtype_essay_options');
+ $field = new xmldb_field('responsetemplate', XMLDB_TYPE_TEXT, null, null,
+ null, null, null, 'graderinfoformat');
+ if (!$dbman->field_exists($table, $field)) {
+ $dbman->add_field($table, $field);
+ }
+
+ $field = new xmldb_field('responsetemplateformat', XMLDB_TYPE_INTEGER, '2',
+ null, XMLDB_NOTNULL, null, '0', 'responsetemplate');
+ if (!$dbman->field_exists($table, $field)) {
+ $dbman->add_field($table, $field);
+ }
+
+ $DB->execute("UPDATE {qtype_essay_options} SET responsetemplate = '',
+ responsetemplateformat = " . FORMAT_HTML . " WHERE responsetemplate IS NULL");
+
+ // Essay savepoint reached.
+ upgrade_plugin_savepoint(true, 2013021700, 'qtype', 'essay');
+ }
+
return true;
}
@@ -50,6 +50,10 @@ protected function definition_inner($mform) {
get_string('allowattachments', 'qtype_essay'), $qtype->attachment_options());
$mform->setDefault('attachments', 0);
+ $mform->addElement('editor', 'responsetemplate', get_string('responsetemplate', 'qtype_essay'),
+ array('rows' => 10), array_merge($this->editoroptions, array('maxfiles' => 0)));
+ $mform->addHelpButton('responsetemplate', 'responsetemplate', 'qtype_essay');
+
$mform->addElement('editor', 'graderinfo', get_string('graderinfo', 'qtype_essay'),
array('rows' => 10), $this->editoroptions);
}
@@ -79,6 +83,11 @@ protected function data_preprocessing($question) {
$question->graderinfo['format'] = $question->options->graderinfoformat;
$question->graderinfo['itemid'] = $draftid;
+ $question->responsetemplate = array(
+ 'text' => $question->options->responsetemplate,
+ 'format' => $question->options->responsetemplateformat,
+ );
+
return $question;
}
@@ -38,3 +38,5 @@
$string['pluginnamesummary'] = 'Allows a response of a few sentences or paragraphs. This must then be graded manually.';
$string['responsefieldlines'] = 'Input box size';
$string['responseformat'] = 'Response format';
+$string['responsetemplate'] = 'Response template';
+$string['responsetemplate_help'] = 'Any text entered here will be displayed in the response input box when a new attempt at the question starts.';
@@ -39,6 +39,8 @@ class qtype_essay_question extends question_with_responses {
public $attachments;
public $graderinfo;
public $graderinfoformat;
+ public $responsetemplate;
+ public $responsetemplateformat;
public function make_behaviour(question_attempt $qa, $preferredbehaviour) {
question_engine::load_behaviour_class('manualgraded');
@@ -86,8 +88,17 @@ public function is_complete_response(array $response) {
}
public function is_same_response(array $prevresponse, array $newresponse) {
- return question_utils::arrays_same_at_key_missing_is_blank(
- $prevresponse, $newresponse, 'answer') && ($this->attachments == 0 ||
+ if (array_key_exists('answer', $prevresponse) && $prevresponse['answer'] !== $this->responsetemplate) {
+ $value1 = $prevresponse['answer'];
+ } else {
+ $value1 = '';
+ }
+ if (array_key_exists('answer', $newresponse) && $newresponse['answer'] !== $this->responsetemplate) {
+ $value2 = $newresponse['answer'];
+ } else {
+ $value2 = '';
+ }
+ return $value1 === $value2 && ($this->attachments == 0 ||
question_utils::arrays_same_at_key_missing_is_blank(
$prevresponse, $newresponse, 'attachments'));
}
@@ -68,6 +68,8 @@ public function save_question_options($formdata) {
$options->graderinfo = $this->import_or_save_files($formdata->graderinfo,
$context, 'qtype_essay', 'graderinfo', $formdata->id);
$options->graderinfoformat = $formdata->graderinfo['format'];
+ $options->responsetemplate = $formdata->responsetemplate['text'];
+ $options->responsetemplateformat = $formdata->responsetemplate['format'];
$DB->update_record('qtype_essay_options', $options);
}
@@ -78,6 +80,8 @@ protected function initialise_question_instance(question_definition $question, $
$question->attachments = $questiondata->options->attachments;
$question->graderinfo = $questiondata->options->graderinfo;
$question->graderinfoformat = $questiondata->options->graderinfoformat;
+ $question->responsetemplate = $questiondata->options->responsetemplate;
+ $question->responsetemplateformat = $questiondata->options->responsetemplateformat;
}
public function delete_question($questionid, $contextid) {
@@ -42,6 +42,12 @@ public function formulation_and_controls(question_attempt $qa,
// Answer field.
$step = $qa->get_last_step_with_qt_var('answer');
+
+ if (!$step->has_qt_var('answer') && empty($options->readonly)) {
+ // Question has never been answered, fill it with response template.
+ $step = new question_attempt_step(array('answer'=>$question->responsetemplate));
+ }
+
if (empty($options->readonly)) {
$answer = $responseoutput->response_area_input('answer', $qa,
$step, $question->responsefieldlines, $options->context);
@@ -34,7 +34,7 @@
*/
class qtype_essay_test_helper extends question_test_helper {
public function get_test_questions() {
- return array('editor', 'editorfilepicker', 'plain', 'monospaced');
+ return array('editor', 'editorfilepicker', 'plain', 'monospaced', 'responsetemplate');
}
/**
@@ -97,4 +97,11 @@ public function make_essay_question_monospaced() {
$q->responseformat = 'monospaced';
return $q;
}
+
+ public function make_essay_question_responsetemplate() {
+ $q = $this->initialise_essay_question();
+ $q->responsetemplate = 'Once upon a time';
+ $q->responsetemplateformat = FORMAT_HTML;
+ return $q;
+ }
}
@@ -49,4 +49,92 @@ public function test_summarise_response() {
$this->assertEquals($longstring,
$essay->summarise_response(array('answer' => $longstring)));
}
+
+ public function test_is_same_response() {
+ $essay = test_question_maker::make_an_essay_question();
+
+ $essay->responsetemplate = '';
+
+ $essay->start_attempt(new question_attempt_step(), 1);
+
+ $this->assertTrue($essay->is_same_response(
+ array(),
+ array('answer' => '')));
+
+ $this->assertTrue($essay->is_same_response(
+ array('answer' => ''),
+ array('answer' => '')));
+
+ $this->assertTrue($essay->is_same_response(
+ array('answer' => ''),
+ array()));
+
+ $this->assertFalse($essay->is_same_response(
+ array('answer' => 'Hello'),
+ array()));
+
+ $this->assertFalse($essay->is_same_response(
+ array('answer' => 'Hello'),
+ array('answer' => '')));
+
+ $this->assertFalse($essay->is_same_response(
+ array('answer' => 0),
+ array('answer' => '')));
+
+ $this->assertFalse($essay->is_same_response(
+ array('answer' => ''),
+ array('answer' => 0)));
+
+ $this->assertFalse($essay->is_same_response(
+ array('answer' => '0'),
+ array('answer' => '')));
+
+ $this->assertFalse($essay->is_same_response(
+ array('answer' => ''),
+ array('answer' => '0')));
+ }
+
+ public function test_is_same_response_with_template() {
+ $essay = test_question_maker::make_an_essay_question();
+
+ $essay->responsetemplate = 'Once upon a time';
+
+ $essay->start_attempt(new question_attempt_step(), 1);
+
+ $this->assertTrue($essay->is_same_response(
+ array(),
+ array('answer' => 'Once upon a time')));
+
+ $this->assertTrue($essay->is_same_response(
+ array('answer' => ''),
+ array('answer' => 'Once upon a time')));
+
+ $this->assertTrue($essay->is_same_response(
+ array('answer' => 'Once upon a time'),
+ array('answer' => '')));
+
+ $this->assertTrue($essay->is_same_response(
+ array('answer' => ''),
+ array()));
+
+ $this->assertTrue($essay->is_same_response(
+ array('answer' => 'Once upon a time'),
+ array()));
+
+ $this->assertFalse($essay->is_same_response(
+ array('answer' => 0),
+ array('answer' => '')));
+
+ $this->assertFalse($essay->is_same_response(
+ array('answer' => ''),
+ array('answer' => 0)));
+
+ $this->assertFalse($essay->is_same_response(
+ array('answer' => '0'),
+ array('answer' => '')));
+
+ $this->assertFalse($essay->is_same_response(
+ array('answer' => ''),
+ array('answer' => '0')));
+ }
}
Oops, something went wrong.

0 comments on commit 60527d0

Please sign in to comment.