MDL-52397 editpdf: Fix draft vs nondraft comparison
[moodle.git] / mod / assign / feedback / editpdf / locallib.php
CommitLineData
5c386472
DW
1<?php
2// This file is part of Moodle - http://moodle.org/
3//
4// Moodle is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// Moodle is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
16
17/**
18 * This file contains the definition for the library class for PDF feedback plugin
19 *
20 *
21 * @package assignfeedback_editpdf
22 * @copyright 2012 Davo Smith
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 */
25
26defined('MOODLE_INTERNAL') || die();
27
28use \assignfeedback_editpdf\document_services;
29use \assignfeedback_editpdf\page_editor;
30
31/**
32 * library class for editpdf feedback plugin extending feedback plugin base class
33 *
34 * @package assignfeedback_editpdf
35 * @copyright 2012 Davo Smith
36 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
37 */
38class assign_feedback_editpdf extends assign_feedback_plugin {
39
c70de965
DW
40 /** @var boolean|null $enabledcache Cached lookup of the is_enabled function */
41 private $enabledcache = null;
42
5c386472
DW
43 /**
44 * Get the name of the file feedback plugin
45 * @return string
46 */
47 public function get_name() {
48 return get_string('pluginname', 'assignfeedback_editpdf');
49 }
50
51 /**
52 * Create a widget for rendering the editor.
53 *
54 * @param int $userid
55 * @param stdClass $grade
56 * @param bool $readonly
57 * @return assignfeedback_editpdf_widget
58 */
59 public function get_widget($userid, $grade, $readonly) {
60 $attempt = -1;
720d2240 61 if ($grade && $grade->attemptnumber) {
5c386472
DW
62 $attempt = $grade->attemptnumber;
63 } else {
64 $grade = $this->assignment->get_user_grade($userid, true);
65 }
66
67 $feedbackfile = document_services::get_feedback_document($this->assignment->get_instance()->id,
68 $userid,
69 $attempt);
70
71 $stampfiles = array();
72 $fs = get_file_storage();
73 $syscontext = context_system::instance();
74
75 // Copy any new stamps to this instance.
76 if ($files = $fs->get_area_files($syscontext->id,
77 'assignfeedback_editpdf',
78 'stamps',
79 0,
80 "filename",
81 false)) {
82 foreach ($files as $file) {
83 $filename = $file->get_filename();
84 if ($filename !== '.') {
85
86 $existingfile = $fs->get_file($this->assignment->get_context()->id,
87 'assignfeedback_editpdf',
88 'stamps',
89 $grade->id,
90 '/',
91 $file->get_filename());
92 if (!$existingfile) {
93 $newrecord = new stdClass();
94 $newrecord->contextid = $this->assignment->get_context()->id;
95 $newrecord->itemid = $grade->id;
96 $fs->create_file_from_storedfile($newrecord, $file);
97 }
98 }
99 }
100 }
101
102 // Now get the full list of stamp files for this instance.
103 if ($files = $fs->get_area_files($this->assignment->get_context()->id,
104 'assignfeedback_editpdf',
105 'stamps',
106 $grade->id,
107 "filename",
108 false)) {
109 foreach ($files as $file) {
110 $filename = $file->get_filename();
111 if ($filename !== '.') {
112 $url = moodle_url::make_pluginfile_url($this->assignment->get_context()->id,
113 'assignfeedback_editpdf',
114 'stamps',
115 $grade->id,
116 '/',
117 $file->get_filename(),
118 false);
119 array_push($stampfiles, $url->out());
120 }
121 }
122 }
123
124 $url = false;
125 $filename = '';
126 if ($feedbackfile) {
127 $url = moodle_url::make_pluginfile_url($this->assignment->get_context()->id,
128 'assignfeedback_editpdf',
129 document_services::FINAL_PDF_FILEAREA,
130 $grade->id,
131 '/',
132 $feedbackfile->get_filename(),
133 false);
134 $filename = $feedbackfile->get_filename();
135 }
136
aa3e4bde
JM
137 // Retrieve total number of pages.
138 $pagetotal = document_services::page_number_for_attempt($this->assignment->get_instance()->id,
139 $userid,
098f7dd4
FM
140 $attempt,
141 $readonly);
5c386472
DW
142
143 $widget = new assignfeedback_editpdf_widget($this->assignment->get_instance()->id,
144 $userid,
145 $attempt,
146 $url,
147 $filename,
148 $stampfiles,
aa3e4bde
JM
149 $readonly,
150 $pagetotal);
5c386472
DW
151 return $widget;
152 }
153
154 /**
155 * Get form elements for grading form
156 *
157 * @param stdClass $grade
158 * @param MoodleQuickForm $mform
159 * @param stdClass $data
160 * @param int $userid
161 * @return bool true if elements were added to the form
162 */
163 public function get_form_elements_for_user($grade, MoodleQuickForm $mform, stdClass $data, $userid) {
164 global $PAGE;
165
166 $attempt = -1;
167 if ($grade) {
168 $attempt = $grade->attemptnumber;
169 }
170
171 $files = document_services::list_compatible_submission_files_for_attempt($this->assignment, $userid, $attempt);
172 // Only show the editor if there was a compatible file submitted.
173 if (count($files)) {
174
175 $renderer = $PAGE->get_renderer('assignfeedback_editpdf');
176
177 $widget = $this->get_widget($userid, $grade, false);
178
179 $html = $renderer->render($widget);
180 $mform->addElement('static', 'editpdf', get_string('editpdf', 'assignfeedback_editpdf'), $html);
181 $mform->addHelpButton('editpdf', 'editpdf', 'assignfeedback_editpdf');
028c9d20
GF
182 $mform->addElement('hidden', 'editpdf_source_userid', $userid);
183 $mform->setType('editpdf_source_userid', PARAM_INT);
184 $mform->setConstant('editpdf_source_userid', $userid);
5c386472
DW
185 }
186 }
187
238c05c2
AG
188 /**
189 * Check to see if the grade feedback for the pdf has been modified.
190 *
191 * @param stdClass $grade Grade object.
192 * @param stdClass $data Data from the form submission (not used).
193 * @return boolean True if the pdf has been modified, else false.
194 */
195 public function is_feedback_modified(stdClass $grade, stdClass $data) {
196 global $USER;
197 $pagenumbercount = document_services::page_number_for_attempt($this->assignment, $grade->userid, $grade->attemptnumber);
198 for ($i = 0; $i < $pagenumbercount; $i++) {
199 // Select all annotations.
200 $draftannotations = page_editor::get_annotations($grade->id, $i, true);
201 $nondraftannotations = page_editor::get_annotations($grade->id, $i, false);
202 // Check to see if the count is the same.
203 if (count($draftannotations) != count($nondraftannotations)) {
204 // The count is different so we have a modification.
205 return true;
206 } else {
4edd8e77
DM
207 $matches = 0;
208 // Have a closer look and see if the draft files match all the non draft files.
209 foreach ($nondraftannotations as $ndannotation) {
210 foreach ($draftannotations as $dannotation) {
211 foreach ($ndannotation as $key => $value) {
212 if ($key != 'id' && $value != $dannotation->{$key}) {
213 continue 2;
214 }
238c05c2 215 }
4edd8e77 216 $matches++;
238c05c2
AG
217 }
218 }
4edd8e77
DM
219 if ($matches !== count($nondraftannotations)) {
220 return true;
221 }
238c05c2
AG
222 }
223 // Select all comments.
224 $draftcomments = page_editor::get_comments($grade->id, $i, true);
225 $nondraftcomments = page_editor::get_comments($grade->id, $i, false);
226 if (count($draftcomments) != count($nondraftcomments)) {
227 return true;
228 } else {
229 // Go for a closer inspection.
4edd8e77
DM
230 $matches = 0;
231 foreach ($nondraftcomments as $ndcomment) {
232 foreach ($draftcomments as $dcomment) {
233 foreach ($ndcomment as $key => $value) {
234 if ($key != 'id' && $value != $dcomment->{$key}) {
235 continue 2;
236 }
238c05c2 237 }
4edd8e77 238 $matches++;
238c05c2
AG
239 }
240 }
4edd8e77
DM
241 if ($matches !== count($nondraftcomments)) {
242 return true;
243 }
238c05c2
AG
244 }
245 }
246 return false;
247 }
248
5c386472
DW
249 /**
250 * Generate the pdf.
251 *
252 * @param stdClass $grade
253 * @param stdClass $data
254 * @return bool
255 */
256 public function save(stdClass $grade, stdClass $data) {
177cc379
DW
257 // Source user id is only added to the form if there was a pdf.
258 if (!empty($data->editpdf_source_userid)) {
259 $sourceuserid = $data->editpdf_source_userid;
260 // Copy drafts annotations and comments if current user is different to sourceuserid.
261 if ($sourceuserid != $grade->userid) {
262 page_editor::copy_drafts_from_to($this->assignment, $grade, $sourceuserid);
263 }
028c9d20 264 }
5c386472
DW
265 if (page_editor::has_annotations_or_comments($grade->id, true)) {
266 document_services::generate_feedback_document($this->assignment, $grade->userid, $grade->attemptnumber);
267 }
268
269 return true;
270 }
271
272 /**
273 * Display the list of files in the feedback status table.
274 *
275 * @param stdClass $grade
276 * @param bool $showviewlink (Always set to false).
277 * @return string
278 */
279 public function view_summary(stdClass $grade, & $showviewlink) {
280 $showviewlink = false;
281 return $this->view($grade);
282 }
283
284 /**
285 * Display the list of files in the feedback status table.
286 *
287 * @param stdClass $grade
288 * @return string
289 */
290 public function view(stdClass $grade) {
291 global $PAGE;
292 $html = '';
293 // Show a link to download the pdf.
294 if (page_editor::has_annotations_or_comments($grade->id, false)) {
295 $html = $this->assignment->render_area_files('assignfeedback_editpdf',
296 document_services::FINAL_PDF_FILEAREA,
297 $grade->id);
298
299 // Also show the link to the read-only interface.
300 $renderer = $PAGE->get_renderer('assignfeedback_editpdf');
301 $widget = $this->get_widget($grade->userid, $grade, true);
302
303 $html .= $renderer->render($widget);
304 }
305 return $html;
306 }
307
308 /**
309 * Return true if there are no released comments/annotations.
310 *
311 * @param stdClass $grade
312 */
313 public function is_empty(stdClass $grade) {
314 global $DB;
315
316 $comments = $DB->count_records('assignfeedback_editpdf_cmnt', array('gradeid'=>$grade->id, 'draft'=>0));
317 $annotations = $DB->count_records('assignfeedback_editpdf_annot', array('gradeid'=>$grade->id, 'draft'=>0));
318 return $comments == 0 && $annotations == 0;
319 }
320
321 /**
322 * The assignment has been deleted - remove the plugin specific data
323 *
324 * @return bool
325 */
326 public function delete_instance() {
327 global $DB;
9f5193a4
DW
328 $grades = $DB->get_records('assign_grades', array('assignment'=>$this->assignment->get_instance()->id), '', 'id');
329 if ($grades) {
330 list($gradeids, $params) = $DB->get_in_or_equal(array_keys($grades), SQL_PARAMS_NAMED);
331 $DB->delete_records_select('assignfeedback_editpdf_annot', 'gradeid ' . $gradeids, $params);
332 $DB->delete_records_select('assignfeedback_editpdf_cmnt', 'gradeid ' . $gradeids, $params);
333 }
334 return true;
5c386472
DW
335 }
336
f159ad73 337 /**
338 * Automatically enable or disable editpdf feedback plugin based on
339 * whether the ghostscript path is set correctly.
340 *
341 * @return bool
342 */
343 public function is_enabled() {
c70de965
DW
344 if ($this->enabledcache === null) {
345 $testpath = assignfeedback_editpdf\pdf::test_gs_path(false);
346 $this->enabledcache = ($testpath->status == assignfeedback_editpdf\pdf::GSPATH_OK);
f159ad73 347 }
c70de965 348 return $this->enabledcache;
f159ad73 349 }
350 /**
351 * Automatically hide the setting for the editpdf feedback plugin.
352 *
353 * @return bool false
354 */
355 public function is_configurable() {
356 return false;
357 }
5c386472 358}