a034f1f69e81daaa05ea44fab9a593860371d467
[moodle.git] / mod / lesson / essay.php
1 <?php
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/>.
18 /**
19  * Provides the interface for grading essay questions
20  *
21  * @package lesson
22  * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
23  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24  **/
26 require_once('../../config.php');
27 require_once($CFG->dirroot.'/mod/lesson/locallib.php');
28 require_once($CFG->dirroot.'/mod/lesson/essay_form.php');
29 require_once($CFG->libdir.'/eventslib.php');
31 $id   = required_param('id', PARAM_INT);             // Course Module ID
32 $mode = optional_param('mode', 'display', PARAM_ALPHA);
33 try {
34     $cm = get_coursemodule_from_id('lesson', $id, 0, false, MUST_EXIST);;
35     $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST);
36     $lesson = new lesson($DB->get_record('lesson', array('id' => $cm->instance), '*', MUST_EXIST));
37 } catch (Exception $e) {
38     print_error('invalidcoursemodule');
39 }
40 require_login($course, false, $cm);
41 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
42 require_capability('mod/lesson:edit', $context);
44 $url = new moodle_url('/mod/lesson/essay.php', array('id'=>$id));
45 if ($mode !== 'display') {
46     $url->param('mode', $mode);
47 }
48 $PAGE->set_url($url);
50 /// Handle any preprocessing before header is printed - based on $mode
51 switch ($mode) {
52     case 'grade':
53         // Grading form - get the necessary data
54         require_sesskey();
56         $attemptid = required_param('attemptid', PARAM_INT);
58         if (!$attempt = $DB->get_record('lesson_attempts', array('id' => $attemptid))) {
59             print_error('cannotfindattempt', 'lesson');
60         }
61         $page = $lesson->load_page($attempt->pageid);
62         if (!$user = $DB->get_record('user', array('id' => $attempt->userid))) {
63             print_error('cannotfinduser', 'lesson');
64         }
65         if (!$answer = $DB->get_record('lesson_answers', array('lessonid' => $lesson->id, 'pageid' => $page->id))) {
66             print_error('cannotfindanswer', 'lesson');
67         }
68         break;
70     case 'update':
71         require_sesskey();
72         $mform = new essay_grading_form();
73         if ($form = $mform->get_data()) {
75             if (optional_param('cancel', false, PARAM_RAW)) {
76                 redirect("$CFG->wwwroot/mod/lesson/essay.php?id=$cm->id");
77             }
79             $attemptid = required_param('attemptid', PARAM_INT);
80             if (!$attempt = $DB->get_record('lesson_attempts', array('id' => $attemptid))) {
81                 print_error('cannotfindattempt', 'lesson');
82             }
83             if (!$grades = $DB->get_records('lesson_grades', array("lessonid"=>$lesson->id, "userid"=>$attempt->userid), 'completed', '*', $attempt->retry, 1)) {
84                 print_error('cannotfindgrade', 'lesson');
85             }
87             $essayinfo = new stdClass;
88             $essayinfo = unserialize($attempt->useranswer);
90             $essayinfo->graded = 1;
91             $essayinfo->score = clean_param($form->score, PARAM_INT);
92             $essayinfo->response = clean_param($form->response, PARAM_RAW);
93             $essayinfo->sent = 0;
94             if (!$lesson->custom && $essayinfo->score == 1) {
95                 $attempt->correct = 1;
96             } else {
97                 $attempt->correct = 0;
98             }
100             $attempt->useranswer = serialize($essayinfo);
102             $DB->update_record('lesson_attempts', $attempt);
104             // Get grade information
105             $grade = current($grades);
106             $gradeinfo = lesson_grade($lesson, $attempt->retry, $attempt->userid);
108             // Set and update
109             $updategrade->id = $grade->id;
110             $updategrade->grade = $gradeinfo->grade;
111             $DB->update_record('lesson_grades', $updategrade);
112             // Log it
113             add_to_log($course->id, 'lesson', 'update grade', "essay.php?id=$cm->id", $lesson->name, $cm->id);
115             $lesson->add_message(get_string('changessaved'), 'notifysuccess');
117             // update central gradebook
118             lesson_update_grades($lesson, $grade->userid);
120             redirect(new moodle_url('/mod/lesson/essay.php', array('id'=>$cm->id)));
121         } else {
122             print_error('invalidformdata');
123         }
124         break;
125     case 'email':
126         // Sending an email(s) to a single user or all
127         require_sesskey();
129         // Get our users (could be singular)
130         if ($userid = optional_param('userid', 0, PARAM_INT)) {
131             $queryadd = " AND userid = ?";
132             if (! $users = $DB->get_records('user', array('id' => $userid))) {
133                 print_error('cannotfinduser', 'lesson');
134             }
135         } else {
136             $queryadd = '';
137             $params = array ("lessonid" => $lesson->id);
138             if (!$users = $DB->get_records_sql("SELECT DISTINCT u.id, u.*
139                                      FROM {user} u,
140                                           {lesson_attempts} a
141                                      WHERE a.lessonid = :lessonid and
142                                            u.id = a.userid
143                                      ORDER BY u.lastname", $params)) {
144                 print_error('cannotfinduser', 'lesson');
145             }
146         }
148         $pages = $lesson->load_all_pages();
149         foreach ($pages as $key=>$page) {
150             if ($page->qtype !== LESSON_PAGE_ESSAY) {
151                 unset($pages[$key]);
152             }
153         }
155         // Get only the attempts that are in response to essay questions
156         list($usql, $params) = $DB->get_in_or_equal(array_keys($pages));
157         if (!empty($queryadd)) {
158             $params[] = $userid;
159         }
160         if (!$attempts = $DB->get_records_select('lesson_attempts', "pageid $usql".$queryadd, $params)) {
161             print_error('nooneansweredthisquestion', 'lesson');
162         }
163         // Get the answers
164         list($answerUsql, $parameters) = $DB->get_in_or_equal(array_keys($pages));
165         array_unshift($parameters, $lesson->id);
166         if (!$answers = $DB->get_records_select('lesson_answers', "lessonid = ? AND pageid $answerUsql", $parameters, '', 'pageid, score')) {
167             print_error('cannotfindanswer', 'lesson');
168         }
169         $options = new stdClass;
170         $options->noclean = true;
172         foreach ($attempts as $attempt) {
173             $essayinfo = unserialize($attempt->useranswer);
174             if ($essayinfo->graded && !$essayinfo->sent) {
175                 // Holds values for the essayemailsubject string for the email message
176                 $a = new stdClass;
178                 // Set the grade
179                 $grades = $DB->get_records('lesson_grades', array("lessonid"=>$lesson->id, "userid"=>$attempt->userid), 'completed', '*', $attempt->retry, 1);
180                 $grade  = current($grades);
181                 $a->newgrade = $grade->grade;
183                 // Set the points
184                 if ($lesson->custom) {
185                     $a->earned = $essayinfo->score;
186                     $a->outof  = $answers[$attempt->pageid]->score;
187                 } else {
188                     $a->earned = $essayinfo->score;
189                     $a->outof  = 1;
190                 }
192                 // Set rest of the message values
193                 $currentpage = $lesson->load_page($attempt->pageid);
194                 $a->question = format_text($currentpage->contents, FORMAT_MOODLE, $options);
195                 $a->response = s($essayinfo->answer);
196                 $a->comment  = s($essayinfo->response);
198                 // Fetch message HTML and plain text formats
199                 $message  = get_string('essayemailmessage2', 'lesson', $a);
200                 $plaintext = format_text_email($message, FORMAT_HTML);
202                 // Subject
203                 $subject = get_string('essayemailsubject', 'lesson', format_string($pages[$attempt->pageid]->title,true));
205                 $eventdata = new object();
206                 $eventdata->modulename       = 'lesson';
207                 $eventdata->userfrom         = $USER;
208                 $eventdata->userto           = $users[$attempt->userid];
209                 $eventdata->subject          = $subject;
210                 $eventdata->fullmessage      = $plaintext;
211                 $eventdata->fullmessageformat = FORMAT_PLAIN;
212                 $eventdata->fullmessagehtml  = $message;
213                 $eventdata->smallmessage     = '';
215                 // Required for messaging framework
216                 $eventdata->component = 'mod_lesson';
217                 $eventdata->name = 'graded_essay';
219                 message_send($eventdata);
220                 $essayinfo->sent = 1;
221                 $attempt->useranswer = serialize($essayinfo);
222                 $DB->update_record('lesson_attempts', $attempt);
223                 // Log it
224                 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);
225             }
226         }
227         $lesson->add_message(get_string('emailsuccess', 'lesson'), 'notifysuccess');
228         redirect(new moodle_url('/mod/lesson/essay.php', array('id'=>$cm->id)));
229         break;
230     case 'display':  // Default view - get the necessary data
231     default:
232         // Get lesson pages that are essay
233         $pages = $lesson->load_all_pages();
234         foreach ($pages as $key=>$page) {
235             if ($page->qtype !== LESSON_PAGE_ESSAY) {
236                 unset($pages[$key]);
237             }
238         }
239         if (count($pages) > 0) {
240             $params = array ("lessonid" => $lesson->id, "qtype" => LESSON_PAGE_ESSAY);
241             // Get only the attempts that are in response to essay questions
242             list($usql, $parameters) = $DB->get_in_or_equal(array_keys($pages));
243             if ($essayattempts = $DB->get_records_select('lesson_attempts', 'pageid '.$usql, $parameters)) {
244                 // Get all the users who have taken this lesson, order by their last name
245                 if (!empty($cm->groupingid)) {
246                     $params["groupinid"] = $cm->groupingid;
247                     $sql = "SELECT DISTINCT u.*
248                             FROM {lesson_attempts} a
249                                 INNER JOIN {user} u ON u.id = a.userid
250                                 INNER JOIN {groups_members} gm ON gm.userid = u.id
251                                 INNER JOIN {groupings_groups} gg ON gm.groupid = :groupinid
252                             WHERE a.lessonid = :lessonid
253                             ORDER BY u.lastname";
254                 } else {
255                     $sql = "SELECT DISTINCT u.*
256                             FROM {user} u,
257                                  {lesson_attempts} a
258                             WHERE a.lessonid = :lessonid and
259                                   u.id = a.userid
260                             ORDER BY u.lastname";
261                 }
262                 if (!$users = $DB->get_records_sql($sql, $params)) {
263                     $mode = 'none'; // not displaying anything
264                     $lesson->add_message(get_string('noonehasanswered', 'lesson'));
265                 }
266             } else {
267                 $mode = 'none'; // not displaying anything
268                 $lesson->add_message(get_string('noonehasanswered', 'lesson'));
269             }
270         } else {
271             $mode = 'none'; // not displaying anything
272             $lesson->add_message(get_string('noessayquestionsfound', 'lesson'));
273         }
274         break;
276 // Log it
277 add_to_log($course->id, 'lesson', 'view grade', "essay.php?id=$cm->id", get_string('manualgrading', 'lesson'), $cm->id);
279 $lessonoutput = $PAGE->get_renderer('mod_lesson');
280 echo $lessonoutput->header($lesson, $cm, 'essay');
282 switch ($mode) {
283     case 'display':
284         // Expects $user, $essayattempts and $pages to be set already
286         // Group all the essays by userid
287         $studentessays = array();
288         foreach ($essayattempts as $essay) {
289             // Not very nice :) but basically
290             //   this organizes the essays so we know how many
291             //   times a student answered an essay per try and per page
292             $studentessays[$essay->userid][$essay->pageid][$essay->retry][] = $essay;
293         }
295         // Setup table
296         $table = new html_table();
297         $table->head = array(get_string('name'), get_string('essays', 'lesson'), get_string('email', 'lesson'));
298         $table->attributes['class'] = 'standardtable generaltable';
299         $table->align = array('left', 'left', 'left');
300         $table->wrap = array('nowrap', 'nowrap', '');
302         // Cycle through all the students
303         foreach (array_keys($studentessays) as $userid) {
304             $studentname = fullname($users[$userid], true);
305             $essaylinks = array();
307             // Number of attempts on the lesson
308             $attempts = $DB->count_records('lesson_grades', array('userid'=>$userid, 'lessonid'=>$lesson->id));
310             // Go through each essay page
311             foreach ($studentessays[$userid] as $page => $tries) {
312                 $count = 0;
314                 // Go through each attempt per page
315                 foreach($tries as $try) {
316                     if ($count == $attempts) {
317                         break;  // Stop displaying essays (attempt not completed)
318                     }
319                     $count++;
321                     // Make sure they didn't answer it more than the max number of attmepts
322                     if (count($try) > $lesson->maxattempts) {
323                         $essay = $try[$lesson->maxattempts-1];
324                     } else {
325                         $essay = end($try);
326                     }
328                     // Start processing the attempt
329                     $essayinfo = unserialize($essay->useranswer);
331                     // link for each essay
332                     $url = new moodle_url('/mod/lesson/essay.php', array('id'=>$cm->id,'mode'=>'grade','attemptid'=>$essay->id,'sesskey'=>sesskey()));
333                     $attributes = array();
334                     // Different colors for all the states of an essay (graded, if sent, not graded)
335                     if (!$essayinfo->graded) {
336                         $attributes['class'] = "graded";
337                     } elseif (!$essayinfo->sent) {
338                         $attributes['class'] = "sent";
339                     } else {
340                         $attributes['class'] = "ungraded";
341                     }
342                     $essaylinks[] = html_writer::link($url, userdate($essay->timeseen, get_string('strftimedatetime')).' '.format_string($pages[$essay->pageid]->title,true), $attributes);
343                 }
344             }
345             // email link for this user
346             $url = new moodle_url('/mod/lesson/essay.php', array('id'=>$cm->id,'mode'=>'email','userid'=>$userid,'sesskey'=>sesskey()));
347             $emaillink = html_writer::link($url, get_string('emailgradedessays', 'lesson'));
349             $table->data[] = array($OUTPUT->user_picture($users[$userid], array('courseid'=>$course->id)).$studentname, implode("<br />", $essaylinks), $emaillink);
350         }
352         // email link for all users
353         $url = new moodle_url('/mod/lesson/essay.php', array('id'=>$cm->id,'mode'=>'email','sesskey'=>sesskey()));
354         $emailalllink = html_writer::link($url, get_string('emailallgradedessays', 'lesson'));
356         $table->data[] = array(' ', ' ', $emailalllink);
358         echo html_writer::table($table);
359         break;
360     case 'grade':
361         // Grading form
362         // Expects the following to be set: $attemptid, $answer, $user, $page, $attempt
365         $essayinfo = unserialize($attempt->useranswer);
366         $options = array();
367         if ($lesson->custom) {
368             $i = $answer->score;
369             while ($i >= 0) {
370                 $options[$i] = (string)$i;
371                 $i--;
372             }
373         } else {
374             $options[0] = get_string('nocredit', 'lesson');
375             $options[1] = get_string('credit', 'lesson');
376         }
377         $mform = new essay_grading_form(null, array('scoreoptions'=>$options, 'user'=>$user));
379         $data = new stdClass;
380         $data->id = $cm->id;
381         $data->attemptid = $attemptid;
382         $data->score = $essayinfo->score;
383         $data->studentanswer = format_string($essayinfo->answer, FORMAT_MOODLE);
384         $data->response = $essayinfo->response;
385         $mform->set_data($data);
387         $mform->display();
388         break;
391 echo $OUTPUT->footer();