MDL-11082 Improved groups upgrade performance 1.8x -> 1.9; thanks Eloy for telling...
[moodle-pu.git] / mod / lesson / essay.php
blobbdccd0653fc219a1ec699ceb638d18c62d807692
1 <?php // $Id$
2 /**
3 * Provides the interface for grading essay questions
5 * @version $Id$
6 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
7 * @package lesson
8 **/
10 require_once('../../config.php');
11 require_once('locallib.php');
12 require_once('lib.php');
14 $id = required_param('id', PARAM_INT); // Course Module ID
15 $mode = optional_param('mode', 'display', PARAM_ALPHA);
17 list($cm, $course, $lesson) = lesson_get_basics($id);
19 require_login($course->id, false, $cm);
21 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
23 require_capability('mod/lesson:edit', $context);
25 /// Handle any preprocessing before header is printed - based on $mode
26 switch ($mode) {
27 case 'display': // Default view - get the necessary data
28 // Get lesson pages that are essay
29 if ($pages = get_records_select('lesson_pages', "lessonid = $lesson->id AND qtype = ".LESSON_ESSAY)) {
30 // Get only the attempts that are in response to essay questions
31 if ($essayattempts = get_records_select('lesson_attempts', 'pageid IN('.implode(',', array_keys($pages)).')')) {
32 // Get all the users who have taken this lesson, order by their last name
33 if (!empty($CFG->enablegroupings) && !empty($cm->groupingid)) {
34 $sql = "SELECT DISTINCT u.*
35 FROM {$CFG->prefix}lesson_attempts a
36 INNER JOIN {$CFG->prefix}user u ON u.id = a.userid
37 INNER JOIN {$CFG->prefix}groups_members gm ON gm.userid = u.id
38 INNER JOIN {$CFG->prefix}groupings_groups gg ON gm.groupid = {$cm->groupingid}
39 WHERE a.lessonid = '$lesson->id'
40 ORDER BY u.lastname";
41 } else {
42 $sql = "SELECT u.*
43 FROM {$CFG->prefix}user u,
44 {$CFG->prefix}lesson_attempts a
45 WHERE a.lessonid = '$lesson->id' and
46 u.id = a.userid
47 ORDER BY u.lastname";
49 if (!$users = get_records_sql($sql)) {
50 $mode = 'none'; // not displaying anything
51 lesson_set_message(get_string('noonehasanswered', 'lesson'));
53 } else {
54 $mode = 'none'; // not displaying anything
55 lesson_set_message(get_string('noonehasanswered', 'lesson'));
57 } else {
58 $mode = 'none'; // not displaying anything
59 lesson_set_message(get_string('noessayquestionsfound', 'lesson'));
61 break;
62 case 'grade': // Grading form - get the necessary data
63 confirm_sesskey();
65 $attemptid = required_param('attemptid', PARAM_INT);
67 if (!$attempt = get_record('lesson_attempts', 'id', $attemptid)) {
68 error('Error: could not find attempt');
70 if (!$page = get_record('lesson_pages', 'id', $attempt->pageid)) {
71 error('Error: could not find lesson page');
73 if (!$user = get_record('user', 'id', $attempt->userid)) {
74 error('Error: could not find users');
76 if (!$answer = get_record('lesson_answers', 'lessonid', $lesson->id, 'pageid', $page->id)) {
77 error('Error: could not find answer');
79 break;
80 case 'update':
81 if (confirm_sesskey() and $form = data_submitted($CFG->wwwroot.'/mod/lesson/essay.php')) {
82 if (optional_param('cancel', 0)) {
83 redirect("$CFG->wwwroot/mod/lesson/essay.php?id=$cm->id");
86 $attemptid = required_param('attemptid', PARAM_INT);
88 if (!$attempt = get_record('lesson_attempts', 'id', $attemptid)) {
89 error('Error: could not find essay');
91 if (!$grades = get_records_select('lesson_grades', "lessonid = $lesson->id and userid = $attempt->userid", 'completed', '*', $attempt->retry, 1)) {
92 error('Error: could not find grades');
95 $essayinfo = new stdClass;
96 $essayinfo = unserialize($attempt->useranswer);
98 $essayinfo->graded = 1;
99 $essayinfo->score = clean_param($form->score, PARAM_INT);
100 $essayinfo->response = stripslashes_safe(clean_param($form->response, PARAM_RAW));
101 $essayinfo->sent = 0;
102 if (!$lesson->custom && $essayinfo->score == 1) {
103 $attempt->correct = 1;
104 } else {
105 $attempt->correct = 0;
108 $attempt->useranswer = addslashes(serialize($essayinfo));
110 if (!update_record('lesson_attempts', $attempt)) {
111 error('Could not update essay score');
114 // Get grade information
115 $grade = current($grades);
116 $gradeinfo = lesson_grade($lesson, $attempt->retry, $attempt->userid);
118 // Set and update
119 $updategrade->id = $grade->id;
120 $updategrade->grade = $gradeinfo->grade;
121 if(update_record('lesson_grades', $updategrade)) {
122 // Log it
123 add_to_log($course->id, 'lesson', 'update grade', "essay.php?id=$cm->id", $lesson->name, $cm->id);
125 lesson_set_message(get_string('changessaved'), 'notifysuccess');
126 } else {
127 lesson_set_message(get_string('updatefailed', 'lesson'));
130 // update central gradebook
131 lesson_update_grades($lesson, $grade->userid);
133 redirect("$CFG->wwwroot/mod/lesson/essay.php?id=$cm->id");
134 } else {
135 error('Something is wrong with the form data');
137 break;
138 case 'email': // Sending an email(s) to a single user or all
139 confirm_sesskey();
141 // Get our users (could be singular)
142 if ($userid = optional_param('userid', 0, PARAM_INT)) {
143 $queryadd = " AND userid = $userid";
144 if (! $users = get_records('user', 'id', $userid)) {
145 error('Error: could not find users');
147 } else {
148 $queryadd = '';
149 if (!$users = get_records_sql("SELECT u.*
150 FROM {$CFG->prefix}user u,
151 {$CFG->prefix}lesson_attempts a
152 WHERE a.lessonid = '$lesson->id' and
153 u.id = a.userid
154 ORDER BY u.lastname")) {
155 error('Error: could not find users');
159 // Get lesson pages that are essay
160 if (!$pages = get_records_select('lesson_pages', "lessonid = $lesson->id AND qtype = ".LESSON_ESSAY)) {
161 error('Error: could not find lesson pages');
164 // Get only the attempts that are in response to essay questions
165 $pageids = implode(',', array_keys($pages)); // all the pageids in comma seperated list
166 if (!$attempts = get_records_select('lesson_attempts', "pageid IN($pageids)".$queryadd)) {
167 error ('No one has answered essay questions yet...');
169 // Get the answers
170 if (!$answers = get_records_select('lesson_answers', "lessonid = $lesson->id AND pageid IN($pageids)", '', 'pageid, score')) {
171 error ('Could not find answer records.');
173 $options = new stdClass;
174 $options->noclean = true;
176 foreach ($attempts as $attempt) {
177 $essayinfo = unserialize($attempt->useranswer);
178 if ($essayinfo->graded and !$essayinfo->sent) {
179 // Holds values for the essayemailsubject string for the email message
180 $a = new stdClass;
182 // Set the grade
183 $grades = get_records_select('lesson_grades', "lessonid = $lesson->id and userid = $attempt->userid", 'completed', '*', $attempt->retry, 1);
184 $grade = current($grades);
185 $a->newgrade = $grade->grade;
187 // Set the points
188 if ($lesson->custom) {
189 $a->earned = $essayinfo->score;
190 $a->outof = $answers[$attempt->pageid]->score;
191 } else {
192 $a->earned = $essayinfo->score;
193 $a->outof = 1;
196 // Set rest of the message values
197 $a->question = format_text($pages[$attempt->pageid]->contents, FORMAT_MOODLE, $options);
198 $a->response = s(stripslashes_safe($essayinfo->answer));
199 $a->teacher = $course->teacher;
200 $a->comment = s($essayinfo->response);
203 // Fetch message HTML and plain text formats
204 $message = get_string('essayemailmessage', 'lesson', $a);
205 $plaintxt = format_text_email($message, FORMAT_HTML);
207 // Subject
208 $subject = get_string('essayemailsubject', 'lesson', format_string($pages[$attempt->pageid]->title,true));
210 if(email_to_user($users[$attempt->userid], $USER, $subject, $plaintxt, $message)) {
211 $essayinfo->sent = 1;
212 $attempt->useranswer = addslashes(serialize($essayinfo));
213 update_record('lesson_attempts', $attempt);
214 // Log it
215 add_to_log($course->id, 'lesson', 'update email essay grade', "essay.php?id=$cm->id", format_string($pages[$attempt->pageid]->title,true).': '.fullname($users[$attempt->userid]), $cm->id);
216 } else {
217 error('Emailing Failed');
221 lesson_set_message(get_string('emailsuccess', 'lesson'), 'notifysuccess');
222 redirect("$CFG->wwwroot/mod/lesson/essay.php?id=$cm->id");
223 break;
226 // Log it
227 add_to_log($course->id, 'lesson', 'view grade', "essay.php?id=$cm->id", get_string('manualgrading', 'lesson'), $cm->id);
229 lesson_print_header($cm, $course, $lesson, 'essay');
231 switch ($mode) {
232 case 'display':
233 // Expects $user, $essayattempts and $pages to be set already
235 // Group all the essays by userid
236 $studentessays = array();
237 foreach ($essayattempts as $essay) {
238 // Not very nice :) but basically
239 // this organizes the essays so we know how many
240 // times a student answered an essay per try and per page
241 $studentessays[$essay->userid][$essay->pageid][$essay->retry][] = $essay;
244 // Setup table
245 $table = new stdClass;
246 $table->head = array($course->students, get_string('essays', 'lesson'), get_string('email', 'lesson'));
247 $table->align = array('left', 'left', 'left');
248 $table->wrap = array('nowrap', 'nowrap', 'nowrap');
250 // Get the student ids of the users who have answered the essay question
251 $userids = array_keys($studentessays);
253 // Cycle through all the students
254 foreach ($userids as $userid) {
255 $studentname = fullname($users[$userid], true);
256 $essaylinks = array();
258 // Number of attempts on the lesson
259 $attempts = count_records('lesson_grades', 'userid', $userid, 'lessonid', $lesson->id);
261 // Go through each essay page
262 foreach ($studentessays[$userid] as $page => $tries) {
263 $count = 0;
265 // Go through each attempt per page
266 foreach($tries as $try) {
267 if ($count == $attempts) {
268 break; // Stop displaying essays (attempt not completed)
270 $count++;
272 // Make sure they didn't answer it more than the max number of attmepts
273 if (count($try) > $lesson->maxattempts) {
274 $essay = $try[$lesson->maxattempts-1];
275 } else {
276 $essay = end($try);
279 // Start processing the attempt
280 $essayinfo = unserialize($essay->useranswer);
282 // Different colors for all the states of an essay (graded, if sent, not graded)
283 if (!$essayinfo->graded) {
284 $class = ' class="graded"';
285 } elseif (!$essayinfo->sent) {
286 $class = ' class="sent"';
287 } else {
288 $class = ' class="ungraded"';
290 // link for each essay
291 $essaylinks[] = "<a$class href=\"$CFG->wwwroot/mod/lesson/essay.php?id=$cm->id&amp;mode=grade&amp;attemptid=$essay->id&amp;sesskey=".sesskey().'">'.userdate($essay->timeseen, get_string('strftimedatetime')).' '.format_string($pages[$essay->pageid]->title,true).'</a>';
294 // email link for this user
295 $emaillink = "<a href=\"$CFG->wwwroot/mod/lesson/essay.php?id=$cm->id&amp;mode=email&amp;userid=$userid&amp;sesskey=".sesskey().'">'.get_string('emailgradedessays', 'lesson').'</a>';
297 $table->data[] = array(print_user_picture($userid, $course->id, $users[$userid]->picture, 0, true).$studentname, implode("<br />\n", $essaylinks), $emaillink);
299 // email link for all users
300 $emailalllink = "<a href=\"$CFG->wwwroot/mod/lesson/essay.php?id=$cm->id&amp;mode=email&amp;sesskey=".sesskey().'">'.get_string('emailallgradedessays', 'lesson').'</a>';
302 $table->data[] = array(' ', ' ', $emailalllink);
304 print_table($table);
305 break;
306 case 'grade':
307 // Grading form
308 // Expects the following to be set: $attemptid, $answer, $user, $page, $attempt
310 echo '<div class="grade">
311 <form id="essaygrade" method="post" action="'.$CFG->wwwroot.'/mod/lesson/essay.php">
312 <input type="hidden" name="id" value="'.$cm->id.'" />
313 <input type="hidden" name="mode" value="update" />
314 <input type="hidden" name="attemptid" value="'.$attemptid.'" />
315 <input type="hidden" name="sesskey" value="'.sesskey().'" />';
317 // All tables will have these settings
318 $table = new stdClass;
319 $table->align = array('left');
320 $table->wrap = array();
321 $table->width = '50%';
322 $table->size = array('100%');
323 $table->class = 'generaltable gradetable';
325 // Print the question
326 $table->head = array(get_string('question', 'lesson'));
327 $options = new stdClass;
328 $options->noclean = true;
329 $table->data[] = array(format_text($page->contents, FORMAT_MOODLE, $options));
331 print_table($table);
333 unset($table->data);
335 // Now the user's answer
336 $essayinfo = unserialize($attempt->useranswer);
338 $table->head = array(get_string('studentresponse', 'lesson', fullname($user, true)));
339 $table->data[] = array(s(stripslashes_safe($essayinfo->answer)));
341 print_table($table);
343 unset($table->data);
345 // Now a response box and grade drop-down for grader
346 $table->head = array(get_string('comments', 'lesson'));
347 $table->data[] = array(print_textarea(false, 15, 60, 0, 0, 'response', $essayinfo->response, $course->id, true));
348 $options = array();
349 if ($lesson->custom) {
350 for ($i=$answer->score; $i>=0; $i--) {
351 $options[$i] = $i;
353 } else {
354 $options[0] = get_string('nocredit', 'lesson');
355 $options[1] = get_string('credit', 'lesson');
357 $table->data[] = array(get_string('essayscore', 'lesson').': '.choose_from_menu($options, 'score', $essayinfo->score, '', '', '', true));
359 print_table($table);
360 echo '<div class="buttons">
361 <input type="submit" name="cancel" value="'.get_string('cancel').'" />
362 <input type="submit" value="'.get_string('savechanges').'" />
363 </div>
364 </form>
365 </div>';
366 break;
369 print_footer($course);