Skip to content

Commit

Permalink
MDL-43387 mod_lesson: add an editor for essay grading comments
Browse files Browse the repository at this point in the history
  • Loading branch information
Jean-Michel Vedrine committed Feb 1, 2015
1 parent 4c27f52 commit ebf5ad4
Show file tree
Hide file tree
Showing 11 changed files with 191 additions and 29 deletions.
1 change: 1 addition & 0 deletions mod/lesson/backup/moodle2/backup_lesson_stepslib.php
Expand Up @@ -193,6 +193,7 @@ protected function define_structure() {
$page->annotate_files('mod_lesson', 'page_contents', 'id');
$answer->annotate_files('mod_lesson', 'page_answers', 'id');
$answer->annotate_files('mod_lesson', 'page_responses', 'id');
$attempt->annotate_files('mod_lesson', 'essay_responses', 'id');

// Prepare and return the structure we have just created for the lesson module.
return $this->prepare_activity_structure($lesson);
Expand Down
2 changes: 2 additions & 0 deletions mod/lesson/backup/moodle2/restore_lesson_stepslib.php
Expand Up @@ -131,6 +131,7 @@ protected function process_lesson_attempt($data) {
$data->timeseen = $this->apply_date_offset($data->timeseen);

$newitemid = $DB->insert_record('lesson_attempts', $data);
$this->set_mapping('lesson_attempt', $oldid, $newitemid, true); // Has related fileareas.
}

protected function process_lesson_grade($data) {
Expand Down Expand Up @@ -209,6 +210,7 @@ protected function after_execute() {
$this->add_related_files('mod_lesson', 'page_contents', 'lesson_page');
$this->add_related_files('mod_lesson', 'page_answers', 'lesson_answer');
$this->add_related_files('mod_lesson', 'page_responses', 'lesson_answer');
$this->add_related_files('mod_lesson', 'essay_responses', 'lesson_attempt');

// Remap all the restored prevpageid and nextpageid now that we have all the pages and their mappings
$rs = $DB->get_recordset('lesson_pages', array('lessonid' => $this->task->get_activityid()),
Expand Down
33 changes: 24 additions & 9 deletions mod/lesson/essay.php
Expand Up @@ -25,6 +25,7 @@

require_once('../../config.php');
require_once($CFG->dirroot.'/mod/lesson/locallib.php');
require_once($CFG->dirroot.'/mod/lesson/pagetypes/essay.php');
require_once($CFG->dirroot.'/mod/lesson/essay_form.php');
require_once($CFG->libdir.'/eventslib.php');

Expand Down Expand Up @@ -99,7 +100,13 @@
print_error('cannotfinduser', 'lesson');
}

$mform = new essay_grading_form(null, array('scoreoptions'=>$scoreoptions, 'user'=>$user));
$editoroptions = array('noclean' => true, 'maxfiles' => EDITOR_UNLIMITED_FILES,
'maxbytes' => $CFG->maxbytes, 'context' => $context);
$essayinfo = lesson_page_type_essay::extract_useranswer($attempt->useranswer);
$essayinfo = file_prepare_standard_editor($essayinfo, 'response', $editoroptions, $context,
'mod_lesson', 'essay_responses', $attempt->id);
$mform = new essay_grading_form(null, array('scoreoptions' => $scoreoptions, 'user' => $user));
$mform->set_data($essayinfo);
if ($mform->is_cancelled()) {
redirect("$CFG->wwwroot/mod/lesson/essay.php?id=$cm->id");
}
Expand All @@ -108,12 +115,12 @@
print_error('cannotfindgrade', 'lesson');
}

$essayinfo = new stdClass;
$essayinfo = unserialize($attempt->useranswer);

$essayinfo->graded = 1;
$essayinfo->score = $form->score;
$essayinfo->response = clean_param($form->response, PARAM_RAW);
$form = file_postupdate_standard_editor($form, 'response', $editoroptions, $context,
'mod_lesson', 'essay_responses', $attempt->id);
$essayinfo->response = $form->response;
$essayinfo->responseformat = $form->responseformat;
$essayinfo->sent = 0;
if (!$lesson->custom && $essayinfo->score == 1) {
$attempt->correct = 1;
Expand Down Expand Up @@ -208,7 +215,7 @@
}

foreach ($attempts as $attempt) {
$essayinfo = unserialize($attempt->useranswer);
$essayinfo = lesson_page_type_essay::extract_useranswer($attempt->useranswer);
if ($essayinfo->graded && !$essayinfo->sent) {
// Holds values for the essayemailsubject string for the email message
$a = new stdClass;
Expand All @@ -232,7 +239,10 @@
$a->question = format_text($currentpage->contents, $currentpage->contentsformat, $formattextdefoptions);
$a->response = format_text($essayinfo->answer, $essayinfo->answerformat,
array('context' => $context, 'para' => true));
$a->comment = s($essayinfo->response);
$a->comment = $essayinfo->response;
$a->comment = file_rewrite_pluginfile_urls($a->comment, 'pluginfile.php', $context->id,
'mod_lesson', 'essay_responses', $attempt->id);
$a->comment = format_text($a->comment, $essayinfo->responseformat, $formattextdefoptions);

// Fetch message HTML and plain text formats
$message = get_string('essayemailmessage2', 'lesson', $a);
Expand Down Expand Up @@ -353,7 +363,7 @@
}

// Start processing the attempt
$essayinfo = unserialize($essay->useranswer);
$essayinfo = lesson_page_type_essay::extract_useranswer($essay->useranswer);

// link for each essay
$url = new moodle_url('/mod/lesson/essay.php', array('id'=>$cm->id,'mode'=>'grade','attemptid'=>$essay->id,'sesskey'=>sesskey()));
Expand Down Expand Up @@ -397,7 +407,7 @@

// Grading form
// Expects the following to be set: $attemptid, $answer, $user, $page, $attempt
$essayinfo = unserialize($attempt->useranswer);
$essayinfo = lesson_page_type_essay::extract_useranswer($attempt->useranswer);
$currentpage = $lesson->load_page($attempt->pageid);

$mform = new essay_grading_form(null, array('scoreoptions'=>$scoreoptions, 'user'=>$user));
Expand All @@ -409,6 +419,11 @@
$data->studentanswer = format_text($essayinfo->answer, $essayinfo->answerformat,
array('context' => $context, 'para' => true));
$data->response = $essayinfo->response;
$data->responseformat = $essayinfo->responseformat;
$editoroptions = array('noclean' => true, 'maxfiles' => EDITOR_UNLIMITED_FILES,
'maxbytes' => $CFG->maxbytes, 'context' => $context);
$data = file_prepare_standard_editor($data, 'response', $editoroptions, $context,
'mod_lesson', 'essay_responses', $attempt->id);
$mform->set_data($data);

$mform->display();
Expand Down
7 changes: 5 additions & 2 deletions mod/lesson/essay_form.php
Expand Up @@ -39,6 +39,8 @@
class essay_grading_form extends moodleform {

public function definition() {
global $CFG;

$mform = $this->_form;

$mform->addElement('header', 'formheader', get_string('question', 'lesson'));
Expand All @@ -55,8 +57,9 @@ public function definition() {
$mform->addElement('static', 'question', get_string('question', 'lesson'));
$mform->addElement('static', 'studentanswer', get_string('studentresponse', 'lesson', fullname($this->_customdata['user'], true)));

$mform->addElement('textarea', 'response', get_string('comments', 'lesson'), array('rows'=>'15', 'cols'=>'60'));
$mform->setType('response', PARAM_TEXT);
$editoroptions = array('noclean' => true, 'maxfiles' => EDITOR_UNLIMITED_FILES, 'maxbytes' => $CFG->maxbytes);
$mform->addElement('editor', 'response_editor', get_string('comments', 'lesson'), null, $editoroptions);
$mform->setType('response', PARAM_RAW);

$mform->addElement('select', 'score', get_string('essayscore', 'lesson'), $this->_customdata['scoreoptions']);
$mform->setType('score', PARAM_INT);
Expand Down
1 change: 1 addition & 0 deletions mod/lesson/lang/en/lesson.php
Expand Up @@ -171,6 +171,7 @@
$string['essayemailmessage'] = '<p>Essay prompt:<blockquote>{$a->question}</blockquote></p><p>Your response:<blockquote><em>{$a->response}</em></blockquote></p><p>{$a->teacher}\'s comments:<blockquote><em>{$a->comment}</em></blockquote></p><p>You have received {$a->earned} out of {$a->outof} for this essay question.</p><p>Your grade for the lesson has been changed to {$a->newgrade}&#37;.</p>';
$string['essayemailmessage2'] = '<p>Essay prompt:<blockquote>{$a->question}</blockquote></p><p>Your response:<blockquote><em>{$a->response}</em></blockquote></p><p>Grader\'s comments:<blockquote><em>{$a->comment}</em></blockquote></p><p>You have received {$a->earned} out of {$a->outof} for this essay question.</p><p>Your grade for the lesson has been changed to {$a->newgrade}&#37;.</p>';
$string['essayemailsubject'] = 'Your grade for {$a} question';
$string['essayresponses'] = 'Essay responses';
$string['essays'] = 'Essays';
$string['essayscore'] = 'Essay score';
$string['eventessayassessed'] = 'Essay assessed';
Expand Down
22 changes: 22 additions & 0 deletions mod/lesson/lib.php
Expand Up @@ -682,6 +682,20 @@ function lesson_reset_userdata($data) {
WHERE l.course=:course";

$params = array ("course" => $data->courseid);
$lessons = $DB->get_records_sql($lessonssql, $params);

// Get rid of attempts files.
$fs = get_file_storage();
if ($lessons) {
foreach ($lessons as $lessonid => $unused) {
if (!$cm = get_coursemodule_from_instance('lesson', $lessonid)) {
continue;
}
$context = context_module::instance($cm->id);
$fs->delete_area_files($context->id, 'mod_lesson', 'essay_responses');
}
}

$DB->delete_records_select('lesson_timer', "lessonid IN ($lessonssql)", $params);
$DB->delete_records_select('lesson_high_scores', "lessonid IN ($lessonssql)", $params);
$DB->delete_records_select('lesson_grades', "lessonid IN ($lessonssql)", $params);
Expand Down Expand Up @@ -897,6 +911,13 @@ function lesson_pluginfile($course, $cm, $context, $filearea, $args, $forcedownl
}
$fullpath = "/$context->id/mod_lesson/$filearea/$itemid/".implode('/', $args);

} else if ($filearea === 'essay_responses') {
$itemid = (int)array_shift($args);
if (!$attempt = $DB->get_record('lesson_attempts', array('id' => $itemid))) {
return false;
}
$fullpath = "/$context->id/mod_lesson/$filearea/$itemid/".implode('/', $args);

} else if ($filearea === 'mediafile') {
if (count($args) > 1) {
// Remove the itemid when it appears to be part of the arguments. If there is only one argument
Expand Down Expand Up @@ -931,6 +952,7 @@ function lesson_get_file_areas() {
$areas['mediafile'] = get_string('mediafile', 'mod_lesson');
$areas['page_answers'] = get_string('pageanswers', 'mod_lesson');
$areas['page_responses'] = get_string('pageresponses', 'mod_lesson');
$areas['essay_responses'] = get_string('essayresponses', 'mod_lesson');
return $areas;
}

Expand Down
29 changes: 22 additions & 7 deletions mod/lesson/locallib.php
Expand Up @@ -1870,17 +1870,26 @@ final public static function load($id, lesson $lesson) {
*/
final public function delete() {
global $DB;
// first delete all the associated records...

$cm = get_coursemodule_from_instance('lesson', $this->lesson->id, $this->lesson->course);
$context = context_module::instance($cm->id);

// Delete files associated with attempts.
$fs = get_file_storage();
if ($attempts = $DB->get_records('lesson_attempts', array("pageid" => $this->properties->id))) {
foreach ($attempts as $attempt) {
$fs->delete_area_files($context->id, 'mod_lesson', 'essay_responses', $attempt->id);
}
}

// Then delete all the associated records...
$DB->delete_records("lesson_attempts", array("pageid" => $this->properties->id));
// ...now delete the answers...
$DB->delete_records("lesson_answers", array("pageid" => $this->properties->id));
// ..and the page itself
$DB->delete_records("lesson_pages", array("id" => $this->properties->id));

// Delete files associated with this page.
$cm = get_coursemodule_from_instance('lesson', $this->lesson->id, $this->lesson->course);
$context = context_module::instance($cm->id);
$fs = get_file_storage();
$fs->delete_area_files($context->id, 'mod_lesson', 'page_contents', $this->properties->id);
$fs->delete_area_files($context->id, 'mod_lesson', 'page_answers', $this->properties->id);
$fs->delete_area_files($context->id, 'mod_lesson', 'page_responses', $this->properties->id);
Expand Down Expand Up @@ -2088,8 +2097,7 @@ final public function record_attempt($context) {
$options->para = true;
$options->overflowdiv = true;
$options->context = $context;
$result->response = file_rewrite_pluginfile_urls($result->response, 'pluginfile.php', $context->id,
'mod_lesson', 'page_responses', $result->answerid);

$result->feedback = $OUTPUT->box(format_text($this->get_contents(), $this->properties->contentsformat, $options), 'generalbox boxaligncenter');
if (isset($result->studentanswerformat)) {
// This is the student's answer so it should be cleaned.
Expand All @@ -2100,7 +2108,14 @@ final public function record_attempt($context) {
}
$result->feedback .= '<div class="correctanswer generalbox"><em>'
. get_string("youranswer", "lesson").'</em> : ' . $studentanswer;
$result->feedback .= $OUTPUT->box($result->response, $class); // Already converted to HTML.
if (isset($result->responseformat)) {
$result->response = file_rewrite_pluginfile_urls($result->response, 'pluginfile.php', $context->id,
'mod_lesson', 'page_responses', $result->answerid);
$result->feedback .= $OUTPUT->box(format_text($result->response, $result->responseformat, $options)
, $class);
} else {
$result->feedback .= $OUTPUT->box($result->response, $class);
}
$result->feedback .= '</div>';
}
}
Expand Down
40 changes: 32 additions & 8 deletions mod/lesson/pagetypes/essay.php
Expand Up @@ -47,6 +47,23 @@ public function get_typestring() {
public function get_idstring() {
return $this->typeidstring;
}

/**
* Unserialize attempt useranswer and add missing responseformat if needed
* for compatibility with old records.
*
* @param string $useranswer serialized object
* @return object
*/
static public function extract_useranswer($useranswer) {
$essayinfo = unserialize($useranswer);
if (!isset($essayinfo->responseformat)) {
$essayinfo->response = text_to_html($essayinfo->response, false, false);
$essayinfo->responseformat = FORMAT_HTML;
}
return $essayinfo;
}

public function display($renderer, $attempt) {
global $PAGE, $CFG, $USER;

Expand All @@ -56,7 +73,7 @@ public function display($renderer, $attempt) {
$data->id = $PAGE->cm->id;
$data->pageid = $this->properties->id;
if (isset($USER->modattempts[$this->lesson->id])) {
$essayinfo = unserialize($attempt->useranswer);
$essayinfo = self::extract_useranswer($attempt->useranswer);
$data->answer = $essayinfo->answer;
}
$mform->set_data($data);
Expand Down Expand Up @@ -99,7 +116,7 @@ public function check_answer() {
$studentanswerformat = $data->answer['format'];
} else {
$studentanswer = $data->answer;
$studentanswerformat = FORMAT_MOODLE;
$studentanswerformat = FORMAT_HTML;
}

if (trim($studentanswer) === '') {
Expand All @@ -119,7 +136,8 @@ public function check_answer() {
$userresponse->score = 0;
$userresponse->answer = $studentanswer;
$userresponse->answerformat = $studentanswerformat;
$userresponse->response = "";
$userresponse->response = '';
$userresponse->responseformat = FORMAT_HTML;
$result->userresponse = serialize($userresponse);
$result->studentanswerformat = $studentanswerformat;
$result->studentanswer = $studentanswer;
Expand Down Expand Up @@ -161,7 +179,7 @@ public function stats(array &$pagestats, $tries) {
// else, user attempted the question less than the max, so grab the last one
$temp = end($tries);
}
$essayinfo = unserialize($temp->useranswer);
$essayinfo = self::extract_useranswer($temp->useranswer);
if ($essayinfo->graded) {
if (isset($pagestats[$temp->pageid])) {
$essaystats = $pagestats[$temp->pageid];
Expand All @@ -178,15 +196,21 @@ public function stats(array &$pagestats, $tries) {
return true;
}
public function report_answers($answerpage, $answerdata, $useranswer, $pagestats, &$i, &$n) {
$formattextdefoptions = new stdClass();
$formattextdefoptions->noclean = true;
$formattextdefoptions->para = false;
$formattextdefoptions->context = $answerpage->context;
$answers = $this->get_answers();

foreach ($answers as $answer) {
if ($useranswer != null) {
$essayinfo = unserialize($useranswer->useranswer);
$essayinfo = self::extract_useranswer($useranswer->useranswer);
if ($essayinfo->response == null) {
$answerdata->response = get_string("nocommentyet", "lesson");
} else {
$answerdata->response = s($essayinfo->response);
$essayinfo->response = file_rewrite_pluginfile_urls($essayinfo->response, 'pluginfile.php',
$answerpage->context->id, 'mod_lesson', 'essay_responses', $useranswer->id);
$answerdata->response = format_text($essayinfo->response, $essayinfo->responseformat, $formattextdefoptions);
}
if (isset($pagestats[$this->properties->id])) {
$percent = $pagestats[$this->properties->id]->totalscore / $pagestats[$this->properties->id]->total * 100;
Expand Down Expand Up @@ -239,7 +263,7 @@ public function requires_manual_grading() {
return true;
}
public function get_earnedscore($answers, $attempt) {
$essayinfo = unserialize($attempt->useranswer);
$essayinfo = self::extract_useranswer($attempt->useranswer);
return $essayinfo->score;
}
}
Expand Down Expand Up @@ -273,7 +297,7 @@ public function definition() {
if (isset($USER->modattempts[$lessonid]->useranswer) && !empty($USER->modattempts[$lessonid]->useranswer)) {
$attrs = array('disabled' => 'disabled');
$hasattempt = true;
$useranswertemp = unserialize($USER->modattempts[$lessonid]->useranswer);
$useranswertemp = lesson_page_type_essay::extract_useranswer($USER->modattempts[$lessonid]->useranswer);
$useranswer = htmlspecialchars_decode($useranswertemp->answer, ENT_QUOTES);
$useranswerraw = $useranswertemp->answer;
}
Expand Down
5 changes: 3 additions & 2 deletions mod/lesson/report.php
Expand Up @@ -252,7 +252,7 @@
$bestgradefound = false;
// $tries holds all the tries/retries a student has done
$tries = $studentdata[$student->id];
$studentname = "{$student->lastname},&nbsp;$student->firstname";
$studentname = fullname($student, true);
foreach ($tries as $try) {
// start to build up the checkbox and link
if (has_capability('mod/lesson:edit', $context)) {
Expand All @@ -261,7 +261,8 @@
$temp = '';
}

$temp .= "<a href=\"report.php?id=$cm->id&amp;action=reportdetail&amp;userid=".$try['userid'].'&amp;try='.$try['try'].'">';
$temp .= "<a href=\"report.php?id=$cm->id&amp;action=reportdetail&amp;userid=".$try['userid']
.'&amp;try='.$try['try'].'" class="lesson-attempt-link">';
if ($try["grade"] !== null) { // if null then not done yet
// this is what the link does when the user has completed the try
$timetotake = $try["timeend"] - $try["timestart"];
Expand Down

0 comments on commit ebf5ad4

Please sign in to comment.