Commit | Line | Data |
---|---|---|
86342d63 | 1 | <?php |
0a4abb73 SH |
2 | |
3 | // This file is part of Moodle - http://moodle.org/ | |
4 | // | |
5 | // Moodle is free software: you can redistribute it and/or modify | |
6 | // it under the terms of the GNU General Public License as published by | |
7 | // the Free Software Foundation, either version 3 of the License, or | |
8 | // (at your option) any later version. | |
9 | // | |
10 | // Moodle is distributed in the hope that it will be useful, | |
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | // GNU General Public License for more details. | |
14 | // | |
15 | // You should have received a copy of the GNU General Public License | |
16 | // along with Moodle. If not, see <http://www.gnu.org/licenses/>. | |
17 | ||
f15eb92c | 18 | /** |
19 | * Provides the interface for grading essay questions | |
20 | * | |
cc3dbaaa PS |
21 | * @package mod |
22 | * @subpackage lesson | |
23 | * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com} | |
24 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
f15eb92c | 25 | **/ |
26 | ||
0a4abb73 SH |
27 | require_once('../../config.php'); |
28 | require_once($CFG->dirroot.'/mod/lesson/locallib.php'); | |
29 | require_once($CFG->dirroot.'/mod/lesson/essay_form.php'); | |
30 | require_once($CFG->libdir.'/eventslib.php'); | |
31 | ||
32 | $id = required_param('id', PARAM_INT); // Course Module ID | |
33 | $mode = optional_param('mode', 'display', PARAM_ALPHA); | |
b3daa926 | 34 | |
0e35ba6f | 35 | $cm = get_coursemodule_from_id('lesson', $id, 0, false, MUST_EXIST); |
74df2951 | 36 | $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST); |
b3daa926 PS |
37 | $lesson = new lesson($DB->get_record('lesson', array('id' => $cm->instance), '*', MUST_EXIST)); |
38 | ||
0a4abb73 | 39 | require_login($course, false, $cm); |
5918e371 | 40 | $context = context_module::instance($cm->id); |
0a4abb73 SH |
41 | require_capability('mod/lesson:edit', $context); |
42 | ||
a6855934 | 43 | $url = new moodle_url('/mod/lesson/essay.php', array('id'=>$id)); |
0a4abb73 SH |
44 | if ($mode !== 'display') { |
45 | $url->param('mode', $mode); | |
46 | } | |
47 | $PAGE->set_url($url); | |
86342d63 | 48 | |
4bb7783e RW |
49 | $attempt = new stdClass(); |
50 | $user = new stdClass(); | |
51 | $attemptid = optional_param('attemptid', 0, PARAM_INT); | |
52 | ||
53 | if ($attemptid > 0) { | |
54 | $attempt = $DB->get_record('lesson_attempts', array('id' => $attemptid)); | |
55 | $answer = $DB->get_record('lesson_answers', array('lessonid' => $lesson->id, 'pageid' => $attempt->pageid)); | |
56 | $user = $DB->get_record('user', array('id' => $attempt->userid)); | |
57 | $scoreoptions = array(); | |
58 | if ($lesson->custom) { | |
59 | $i = $answer->score; | |
60 | while ($i >= 0) { | |
61 | $scoreoptions[$i] = (string)$i; | |
62 | $i--; | |
63 | } | |
64 | } else { | |
65 | $scoreoptions[0] = get_string('nocredit', 'lesson'); | |
66 | $scoreoptions[1] = get_string('credit', 'lesson'); | |
b38f0baa | 67 | } |
b38f0baa | 68 | } |
4bb7783e | 69 | |
f15eb92c | 70 | /// Handle any preprocessing before header is printed - based on $mode |
0a4abb73 SH |
71 | switch ($mode) { |
72 | case 'grade': | |
73 | // Grading form - get the necessary data | |
74 | require_sesskey(); | |
75 | ||
4bb7783e | 76 | if (empty($attempt)) { |
0a4abb73 SH |
77 | print_error('cannotfindattempt', 'lesson'); |
78 | } | |
4bb7783e | 79 | if (empty($user)) { |
0a4abb73 SH |
80 | print_error('cannotfinduser', 'lesson'); |
81 | } | |
4bb7783e | 82 | if (empty($answer)) { |
0a4abb73 SH |
83 | print_error('cannotfindanswer', 'lesson'); |
84 | } | |
85 | break; | |
86 | ||
87 | case 'update': | |
88 | require_sesskey(); | |
4bb7783e RW |
89 | |
90 | if (empty($attempt)) { | |
91 | print_error('cannotfindattempt', 'lesson'); | |
92 | } | |
93 | if (empty($user)) { | |
94 | print_error('cannotfinduser', 'lesson'); | |
95 | } | |
96 | ||
b38f0baa AB |
97 | $mform = new essay_grading_form(null, array('scoreoptions'=>$scoreoptions, 'user'=>$user)); |
98 | if ($mform->is_cancelled()) { | |
99 | redirect("$CFG->wwwroot/mod/lesson/essay.php?id=$cm->id"); | |
100 | } | |
0a4abb73 | 101 | if ($form = $mform->get_data()) { |
0a4abb73 SH |
102 | if (!$grades = $DB->get_records('lesson_grades', array("lessonid"=>$lesson->id, "userid"=>$attempt->userid), 'completed', '*', $attempt->retry, 1)) { |
103 | print_error('cannotfindgrade', 'lesson'); | |
f15eb92c | 104 | } |
86342d63 | 105 | |
0a4abb73 SH |
106 | $essayinfo = new stdClass; |
107 | $essayinfo = unserialize($attempt->useranswer); | |
f15eb92c | 108 | |
0a4abb73 | 109 | $essayinfo->graded = 1; |
4bb7783e | 110 | $essayinfo->score = $form->score; |
0a4abb73 SH |
111 | $essayinfo->response = clean_param($form->response, PARAM_RAW); |
112 | $essayinfo->sent = 0; | |
113 | if (!$lesson->custom && $essayinfo->score == 1) { | |
114 | $attempt->correct = 1; | |
115 | } else { | |
116 | $attempt->correct = 0; | |
117 | } | |
f15eb92c | 118 | |
0a4abb73 | 119 | $attempt->useranswer = serialize($essayinfo); |
f15eb92c | 120 | |
0a4abb73 | 121 | $DB->update_record('lesson_attempts', $attempt); |
f15eb92c | 122 | |
0a4abb73 SH |
123 | // Get grade information |
124 | $grade = current($grades); | |
125 | $gradeinfo = lesson_grade($lesson, $attempt->retry, $attempt->userid); | |
86342d63 | 126 | |
0a4abb73 | 127 | // Set and update |
39790bd8 | 128 | $updategrade = new stdClass(); |
0a4abb73 SH |
129 | $updategrade->id = $grade->id; |
130 | $updategrade->grade = $gradeinfo->grade; | |
131 | $DB->update_record('lesson_grades', $updategrade); | |
132 | // Log it | |
133 | add_to_log($course->id, 'lesson', 'update grade', "essay.php?id=$cm->id", $lesson->name, $cm->id); | |
86342d63 | 134 | |
0a4abb73 | 135 | $lesson->add_message(get_string('changessaved'), 'notifysuccess'); |
86342d63 | 136 | |
0a4abb73 SH |
137 | // update central gradebook |
138 | lesson_update_grades($lesson, $grade->userid); | |
92bcca38 | 139 | |
a6855934 | 140 | redirect(new moodle_url('/mod/lesson/essay.php', array('id'=>$cm->id))); |
0a4abb73 SH |
141 | } else { |
142 | print_error('invalidformdata'); | |
143 | } | |
144 | break; | |
145 | case 'email': | |
146 | // Sending an email(s) to a single user or all | |
147 | require_sesskey(); | |
92bcca38 | 148 | |
0a4abb73 SH |
149 | // Get our users (could be singular) |
150 | if ($userid = optional_param('userid', 0, PARAM_INT)) { | |
151 | $queryadd = " AND userid = ?"; | |
152 | if (! $users = $DB->get_records('user', array('id' => $userid))) { | |
153 | print_error('cannotfinduser', 'lesson'); | |
f15eb92c | 154 | } |
0a4abb73 SH |
155 | } else { |
156 | $queryadd = ''; | |
157 | $params = array ("lessonid" => $lesson->id); | |
e07c51c4 EL |
158 | // Need to use inner view to avoid distinct + text |
159 | if (!$users = $DB->get_records_sql(" | |
160 | SELECT u.* | |
161 | FROM {user} u | |
162 | JOIN ( | |
9695ff81 TH |
163 | SELECT DISTINCT userid |
164 | FROM {lesson_attempts} | |
165 | WHERE lessonid = :lessonid | |
2f045083 | 166 | ) ui ON u.id = ui.userid", $params)) { |
0a4abb73 | 167 | print_error('cannotfinduser', 'lesson'); |
f15eb92c | 168 | } |
0a4abb73 | 169 | } |
f15eb92c | 170 | |
0a4abb73 SH |
171 | $pages = $lesson->load_all_pages(); |
172 | foreach ($pages as $key=>$page) { | |
173 | if ($page->qtype !== LESSON_PAGE_ESSAY) { | |
174 | unset($pages[$key]); | |
f15eb92c | 175 | } |
0a4abb73 SH |
176 | } |
177 | ||
178 | // Get only the attempts that are in response to essay questions | |
179 | list($usql, $params) = $DB->get_in_or_equal(array_keys($pages)); | |
180 | if (!empty($queryadd)) { | |
181 | $params[] = $userid; | |
182 | } | |
183 | if (!$attempts = $DB->get_records_select('lesson_attempts', "pageid $usql".$queryadd, $params)) { | |
184 | print_error('nooneansweredthisquestion', 'lesson'); | |
185 | } | |
186 | // Get the answers | |
187 | list($answerUsql, $parameters) = $DB->get_in_or_equal(array_keys($pages)); | |
188 | array_unshift($parameters, $lesson->id); | |
189 | if (!$answers = $DB->get_records_select('lesson_answers', "lessonid = ? AND pageid $answerUsql", $parameters, '', 'pageid, score')) { | |
190 | print_error('cannotfindanswer', 'lesson'); | |
191 | } | |
192 | $options = new stdClass; | |
193 | $options->noclean = true; | |
194 | ||
195 | foreach ($attempts as $attempt) { | |
196 | $essayinfo = unserialize($attempt->useranswer); | |
197 | if ($essayinfo->graded && !$essayinfo->sent) { | |
198 | // Holds values for the essayemailsubject string for the email message | |
199 | $a = new stdClass; | |
200 | ||
201 | // Set the grade | |
202 | $grades = $DB->get_records('lesson_grades', array("lessonid"=>$lesson->id, "userid"=>$attempt->userid), 'completed', '*', $attempt->retry, 1); | |
203 | $grade = current($grades); | |
204 | $a->newgrade = $grade->grade; | |
205 | ||
206 | // Set the points | |
207 | if ($lesson->custom) { | |
208 | $a->earned = $essayinfo->score; | |
209 | $a->outof = $answers[$attempt->pageid]->score; | |
210 | } else { | |
211 | $a->earned = $essayinfo->score; | |
212 | $a->outof = 1; | |
213 | } | |
f15eb92c | 214 | |
0a4abb73 SH |
215 | // Set rest of the message values |
216 | $currentpage = $lesson->load_page($attempt->pageid); | |
01c37ef1 | 217 | $a->question = format_text($currentpage->contents, $currentpage->contentsformat, $options); |
0a4abb73 SH |
218 | $a->response = s($essayinfo->answer); |
219 | $a->comment = s($essayinfo->response); | |
220 | ||
221 | // Fetch message HTML and plain text formats | |
222 | $message = get_string('essayemailmessage2', 'lesson', $a); | |
223 | $plaintext = format_text_email($message, FORMAT_HTML); | |
224 | ||
225 | // Subject | |
226 | $subject = get_string('essayemailsubject', 'lesson', format_string($pages[$attempt->pageid]->title,true)); | |
227 | ||
39790bd8 | 228 | $eventdata = new stdClass(); |
0a4abb73 SH |
229 | $eventdata->modulename = 'lesson'; |
230 | $eventdata->userfrom = $USER; | |
231 | $eventdata->userto = $users[$attempt->userid]; | |
232 | $eventdata->subject = $subject; | |
233 | $eventdata->fullmessage = $plaintext; | |
234 | $eventdata->fullmessageformat = FORMAT_PLAIN; | |
235 | $eventdata->fullmessagehtml = $message; | |
236 | $eventdata->smallmessage = ''; | |
237 | ||
238 | // Required for messaging framework | |
239 | $eventdata->component = 'mod_lesson'; | |
240 | $eventdata->name = 'graded_essay'; | |
2f67a9b3 | 241 | |
0a4abb73 SH |
242 | message_send($eventdata); |
243 | $essayinfo->sent = 1; | |
244 | $attempt->useranswer = serialize($essayinfo); | |
245 | $DB->update_record('lesson_attempts', $attempt); | |
646fc290 | 246 | } |
0a4abb73 SH |
247 | } |
248 | $lesson->add_message(get_string('emailsuccess', 'lesson'), 'notifysuccess'); | |
a6855934 | 249 | redirect(new moodle_url('/mod/lesson/essay.php', array('id'=>$cm->id))); |
0a4abb73 SH |
250 | break; |
251 | case 'display': // Default view - get the necessary data | |
252 | default: | |
253 | // Get lesson pages that are essay | |
254 | $pages = $lesson->load_all_pages(); | |
255 | foreach ($pages as $key=>$page) { | |
256 | if ($page->qtype !== LESSON_PAGE_ESSAY) { | |
257 | unset($pages[$key]); | |
f15eb92c | 258 | } |
0a4abb73 SH |
259 | } |
260 | if (count($pages) > 0) { | |
261 | $params = array ("lessonid" => $lesson->id, "qtype" => LESSON_PAGE_ESSAY); | |
262 | // Get only the attempts that are in response to essay questions | |
263 | list($usql, $parameters) = $DB->get_in_or_equal(array_keys($pages)); | |
264 | if ($essayattempts = $DB->get_records_select('lesson_attempts', 'pageid '.$usql, $parameters)) { | |
265 | // Get all the users who have taken this lesson, order by their last name | |
eae1948c | 266 | $ufields = user_picture::fields('u'); |
9695ff81 TH |
267 | list($sort, $sortparams) = users_order_by_sql('u'); |
268 | $params = array_merge($params, $sortparams); | |
157771a3 MA |
269 | $sql = "SELECT DISTINCT $ufields |
270 | FROM {user} u, | |
271 | {lesson_attempts} a | |
272 | WHERE a.lessonid = :lessonid and | |
273 | u.id = a.userid | |
274 | ORDER BY $sort"; | |
0a4abb73 SH |
275 | if (!$users = $DB->get_records_sql($sql, $params)) { |
276 | $mode = 'none'; // not displaying anything | |
277 | $lesson->add_message(get_string('noonehasanswered', 'lesson')); | |
278 | } | |
279 | } else { | |
280 | $mode = 'none'; // not displaying anything | |
281 | $lesson->add_message(get_string('noonehasanswered', 'lesson')); | |
f15eb92c | 282 | } |
0a4abb73 SH |
283 | } else { |
284 | $mode = 'none'; // not displaying anything | |
285 | $lesson->add_message(get_string('noessayquestionsfound', 'lesson')); | |
286 | } | |
287 | break; | |
288 | } | |
0a4abb73 | 289 | |
649cf95d | 290 | $lessonoutput = $PAGE->get_renderer('mod_lesson'); |
d42bc7dc | 291 | echo $lessonoutput->header($lesson, $cm, 'essay', false, null, get_string('manualgrading', 'lesson')); |
0a4abb73 SH |
292 | |
293 | switch ($mode) { | |
294 | case 'display': | |
295 | // Expects $user, $essayattempts and $pages to be set already | |
296 | ||
297 | // Group all the essays by userid | |
298 | $studentessays = array(); | |
299 | foreach ($essayattempts as $essay) { | |
300 | // Not very nice :) but basically | |
301 | // this organizes the essays so we know how many | |
302 | // times a student answered an essay per try and per page | |
303 | $studentessays[$essay->userid][$essay->pageid][$essay->retry][] = $essay; | |
304 | } | |
305 | ||
306 | // Setup table | |
307 | $table = new html_table(); | |
308 | $table->head = array(get_string('name'), get_string('essays', 'lesson'), get_string('email', 'lesson')); | |
16be8974 | 309 | $table->attributes['class'] = 'standardtable generaltable'; |
0a4abb73 SH |
310 | $table->align = array('left', 'left', 'left'); |
311 | $table->wrap = array('nowrap', 'nowrap', ''); | |
312 | ||
313 | // Cycle through all the students | |
314 | foreach (array_keys($studentessays) as $userid) { | |
315 | $studentname = fullname($users[$userid], true); | |
316 | $essaylinks = array(); | |
317 | ||
318 | // Number of attempts on the lesson | |
319 | $attempts = $DB->count_records('lesson_grades', array('userid'=>$userid, 'lessonid'=>$lesson->id)); | |
320 | ||
321 | // Go through each essay page | |
322 | foreach ($studentessays[$userid] as $page => $tries) { | |
323 | $count = 0; | |
324 | ||
325 | // Go through each attempt per page | |
326 | foreach($tries as $try) { | |
327 | if ($count == $attempts) { | |
328 | break; // Stop displaying essays (attempt not completed) | |
329 | } | |
330 | $count++; | |
331 | ||
332 | // Make sure they didn't answer it more than the max number of attmepts | |
333 | if (count($try) > $lesson->maxattempts) { | |
334 | $essay = $try[$lesson->maxattempts-1]; | |
f15eb92c | 335 | } else { |
0a4abb73 | 336 | $essay = end($try); |
f15eb92c | 337 | } |
9101efd3 | 338 | |
0a4abb73 SH |
339 | // Start processing the attempt |
340 | $essayinfo = unserialize($essay->useranswer); | |
341 | ||
342 | // link for each essay | |
a6855934 | 343 | $url = new moodle_url('/mod/lesson/essay.php', array('id'=>$cm->id,'mode'=>'grade','attemptid'=>$essay->id,'sesskey'=>sesskey())); |
9bf16314 | 344 | $attributes = array(); |
0a4abb73 SH |
345 | // Different colors for all the states of an essay (graded, if sent, not graded) |
346 | if (!$essayinfo->graded) { | |
9bf16314 | 347 | $attributes['class'] = "graded"; |
0a4abb73 | 348 | } elseif (!$essayinfo->sent) { |
9bf16314 | 349 | $attributes['class'] = "sent"; |
0a4abb73 | 350 | } else { |
9bf16314 | 351 | $attributes['class'] = "ungraded"; |
0a4abb73 | 352 | } |
9bf16314 | 353 | $essaylinks[] = html_writer::link($url, userdate($essay->timeseen, get_string('strftimedatetime')).' '.format_string($pages[$essay->pageid]->title,true), $attributes); |
f15eb92c | 354 | } |
355 | } | |
0a4abb73 | 356 | // email link for this user |
a6855934 | 357 | $url = new moodle_url('/mod/lesson/essay.php', array('id'=>$cm->id,'mode'=>'email','userid'=>$userid,'sesskey'=>sesskey())); |
57cd3739 | 358 | $emaillink = html_writer::link($url, get_string('emailgradedessays', 'lesson')); |
86342d63 | 359 | |
812dbaf7 | 360 | $table->data[] = array($OUTPUT->user_picture($users[$userid], array('courseid'=>$course->id)).$studentname, implode("<br />", $essaylinks), $emaillink); |
0a4abb73 | 361 | } |
f15eb92c | 362 | |
0a4abb73 | 363 | // email link for all users |
a6855934 | 364 | $url = new moodle_url('/mod/lesson/essay.php', array('id'=>$cm->id,'mode'=>'email','sesskey'=>sesskey())); |
57cd3739 | 365 | $emailalllink = html_writer::link($url, get_string('emailallgradedessays', 'lesson')); |
86342d63 | 366 | |
0a4abb73 SH |
367 | $table->data[] = array(' ', ' ', $emailalllink); |
368 | ||
16be8974 | 369 | echo html_writer::table($table); |
0a4abb73 SH |
370 | break; |
371 | case 'grade': | |
b6374c24 MN |
372 | // Trigger the essay grade viewed event. |
373 | $event = \mod_lesson\event\essay_attempt_viewed::create(array( | |
374 | 'objectid' => $attempt->id, | |
375 | 'relateduserid' => $attempt->userid, | |
376 | 'context' => $context, | |
377 | 'courseid' => $course->id, | |
378 | )); | |
379 | $event->add_record_snapshot('lesson_attempts', $attempt); | |
380 | $event->trigger(); | |
381 | ||
0a4abb73 SH |
382 | // Grading form |
383 | // Expects the following to be set: $attemptid, $answer, $user, $page, $attempt | |
0a4abb73 | 384 | $essayinfo = unserialize($attempt->useranswer); |
3195bc84 | 385 | $currentpage = $lesson->load_page($attempt->pageid); |
b38f0baa AB |
386 | |
387 | $mform = new essay_grading_form(null, array('scoreoptions'=>$scoreoptions, 'user'=>$user)); | |
0a4abb73 SH |
388 | $data = new stdClass; |
389 | $data->id = $cm->id; | |
390 | $data->attemptid = $attemptid; | |
391 | $data->score = $essayinfo->score; | |
3195bc84 | 392 | $data->question = format_string($currentpage->contents, $currentpage->contentsformat); |
d3254ceb | 393 | $data->studentanswer = format_string($essayinfo->answer, $essayinfo->answerformat); |
0a4abb73 SH |
394 | $data->response = $essayinfo->response; |
395 | $mform->set_data($data); | |
396 | ||
397 | $mform->display(); | |
398 | break; | |
399 | } | |
400 | ||
401 | echo $OUTPUT->footer(); |