See Release Notes
Long Term Support Release
Differences Between: [Versions 39 and 310] [Versions 39 and 311] [Versions 39 and 400] [Versions 39 and 401] [Versions 39 and 402] [Versions 39 and 403]
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 26 defined('MOODLE_INTERNAL') || die(); 27 28 use \assignfeedback_editpdf\document_services; 29 use \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 */ 38 class assign_feedback_editpdf extends assign_feedback_plugin { 39 40 /** @var boolean|null $enabledcache Cached lookup of the is_enabled function */ 41 private $enabledcache = null; 42 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; 61 if ($grade && isset($grade->attemptnumber)) { 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 137 $widget = new assignfeedback_editpdf_widget($this->assignment->get_instance()->id, 138 $userid, 139 $attempt, 140 $url, 141 $filename, 142 $stampfiles, 143 $readonly 144 ); 145 return $widget; 146 } 147 148 /** 149 * Get form elements for grading form 150 * 151 * @param stdClass $grade 152 * @param MoodleQuickForm $mform 153 * @param stdClass $data 154 * @param int $userid 155 * @return bool true if elements were added to the form 156 */ 157 public function get_form_elements_for_user($grade, MoodleQuickForm $mform, stdClass $data, $userid) { 158 global $PAGE; 159 160 $attempt = -1; 161 if ($grade) { 162 $attempt = $grade->attemptnumber; 163 } 164 165 $renderer = $PAGE->get_renderer('assignfeedback_editpdf'); 166 167 // Links to download the generated pdf... 168 if ($attempt > -1 && page_editor::has_annotations_or_comments($grade->id, false)) { 169 $html = $this->assignment->render_area_files('assignfeedback_editpdf', 170 document_services::FINAL_PDF_FILEAREA, 171 $grade->id); 172 $mform->addElement('static', 'editpdf_files', get_string('downloadfeedback', 'assignfeedback_editpdf'), $html); 173 } 174 175 $widget = $this->get_widget($userid, $grade, false); 176 177 $html = $renderer->render($widget); 178 $mform->addElement('static', 'editpdf', get_string('editpdf', 'assignfeedback_editpdf'), $html); 179 $mform->addHelpButton('editpdf', 'editpdf', 'assignfeedback_editpdf'); 180 $mform->addElement('hidden', 'editpdf_source_userid', $userid); 181 $mform->setType('editpdf_source_userid', PARAM_INT); 182 $mform->setConstant('editpdf_source_userid', $userid); 183 } 184 185 /** 186 * Check to see if the grade feedback for the pdf has been modified. 187 * 188 * @param stdClass $grade Grade object. 189 * @param stdClass $data Data from the form submission (not used). 190 * @return boolean True if the pdf has been modified, else false. 191 */ 192 public function is_feedback_modified(stdClass $grade, stdClass $data) { 193 // We only need to know if the source user's PDF has changed. If so then all 194 // following users will have the same status. If it's only an individual annotation 195 // then only one user will come through this method. 196 // Source user id is only added to the form if there was a pdf. 197 if (!empty($data->editpdf_source_userid)) { 198 $sourceuserid = $data->editpdf_source_userid; 199 // Retrieve the grade information for the source user. 200 $sourcegrade = $this->assignment->get_user_grade($sourceuserid, true, $grade->attemptnumber); 201 $pagenumbercount = document_services::page_number_for_attempt($this->assignment, $sourceuserid, $sourcegrade->attemptnumber); 202 for ($i = 0; $i < $pagenumbercount; $i++) { 203 // Select all annotations. 204 $draftannotations = page_editor::get_annotations($sourcegrade->id, $i, true); 205 $nondraftannotations = page_editor::get_annotations($grade->id, $i, false); 206 // Check to see if the count is the same. 207 if (count($draftannotations) != count($nondraftannotations)) { 208 // The count is different so we have a modification. 209 return true; 210 } else { 211 $matches = 0; 212 // Have a closer look and see if the draft files match all the non draft files. 213 foreach ($nondraftannotations as $ndannotation) { 214 foreach ($draftannotations as $dannotation) { 215 foreach ($ndannotation as $key => $value) { 216 if ($key != 'id' && $value != $dannotation->{$key}) { 217 continue 2; 218 } 219 } 220 $matches++; 221 } 222 } 223 if ($matches !== count($nondraftannotations)) { 224 return true; 225 } 226 } 227 // Select all comments. 228 $draftcomments = page_editor::get_comments($sourcegrade->id, $i, true); 229 $nondraftcomments = page_editor::get_comments($grade->id, $i, false); 230 if (count($draftcomments) != count($nondraftcomments)) { 231 return true; 232 } else { 233 // Go for a closer inspection. 234 $matches = 0; 235 foreach ($nondraftcomments as $ndcomment) { 236 foreach ($draftcomments as $dcomment) { 237 foreach ($ndcomment as $key => $value) { 238 if ($key != 'id' && $value != $dcomment->{$key}) { 239 continue 2; 240 } 241 } 242 $matches++; 243 } 244 } 245 if ($matches !== count($nondraftcomments)) { 246 return true; 247 } 248 } 249 } 250 } 251 return false; 252 } 253 254 /** 255 * Generate the pdf. 256 * 257 * @param stdClass $grade 258 * @param stdClass $data 259 * @return bool 260 */ 261 public function save(stdClass $grade, stdClass $data) { 262 // Source user id is only added to the form if there was a pdf. 263 if (!empty($data->editpdf_source_userid)) { 264 $sourceuserid = $data->editpdf_source_userid; 265 // Copy drafts annotations and comments if current user is different to sourceuserid. 266 if ($sourceuserid != $grade->userid) { 267 page_editor::copy_drafts_from_to($this->assignment, $grade, $sourceuserid); 268 } 269 } 270 if (page_editor::has_annotations_or_comments($grade->id, true)) { 271 document_services::generate_feedback_document($this->assignment, $grade->userid, $grade->attemptnumber); 272 } 273 274 return true; 275 } 276 277 /** 278 * Display the list of files in the feedback status table. 279 * 280 * @param stdClass $grade 281 * @param bool $showviewlink (Always set to false). 282 * @return string 283 */ 284 public function view_summary(stdClass $grade, & $showviewlink) { 285 $showviewlink = false; 286 return $this->view($grade); 287 } 288 289 /** 290 * Display the list of files in the feedback status table. 291 * 292 * @param stdClass $grade 293 * @return string 294 */ 295 public function view(stdClass $grade) { 296 global $PAGE; 297 $html = ''; 298 // Show a link to download the pdf. 299 if (page_editor::has_annotations_or_comments($grade->id, false)) { 300 $html = $this->assignment->render_area_files('assignfeedback_editpdf', 301 document_services::FINAL_PDF_FILEAREA, 302 $grade->id); 303 304 // Also show the link to the read-only interface. 305 $renderer = $PAGE->get_renderer('assignfeedback_editpdf'); 306 $widget = $this->get_widget($grade->userid, $grade, true); 307 308 $html .= $renderer->render($widget); 309 } 310 return $html; 311 } 312 313 /** 314 * Return true if there are no released comments/annotations. 315 * 316 * @param stdClass $grade 317 */ 318 public function is_empty(stdClass $grade) { 319 global $DB; 320 321 $comments = $DB->count_records('assignfeedback_editpdf_cmnt', array('gradeid'=>$grade->id, 'draft'=>0)); 322 $annotations = $DB->count_records('assignfeedback_editpdf_annot', array('gradeid'=>$grade->id, 'draft'=>0)); 323 return $comments == 0 && $annotations == 0; 324 } 325 326 /** 327 * The assignment has been deleted - remove the plugin specific data 328 * 329 * @return bool 330 */ 331 public function delete_instance() { 332 global $DB; 333 $grades = $DB->get_records('assign_grades', array('assignment'=>$this->assignment->get_instance()->id), '', 'id'); 334 if ($grades) { 335 list($gradeids, $params) = $DB->get_in_or_equal(array_keys($grades), SQL_PARAMS_NAMED); 336 $DB->delete_records_select('assignfeedback_editpdf_annot', 'gradeid ' . $gradeids, $params); 337 $DB->delete_records_select('assignfeedback_editpdf_cmnt', 'gradeid ' . $gradeids, $params); 338 } 339 return true; 340 } 341 342 /** 343 * Determine if ghostscript is available and working. 344 * 345 * @return bool 346 */ 347 public function is_available() { 348 if ($this->enabledcache === null) { 349 $testpath = assignfeedback_editpdf\pdf::test_gs_path(false); 350 $this->enabledcache = ($testpath->status == assignfeedback_editpdf\pdf::GSPATH_OK); 351 } 352 return $this->enabledcache; 353 } 354 /** 355 * Prevent enabling this plugin if ghostscript is not available. 356 * 357 * @return bool false 358 */ 359 public function is_configurable() { 360 return $this->is_available(); 361 } 362 363 /** 364 * Get file areas returns a list of areas this plugin stores files. 365 * 366 * @return array - An array of fileareas (keys) and descriptions (values) 367 */ 368 public function get_file_areas() { 369 return array(document_services::FINAL_PDF_FILEAREA => $this->get_name()); 370 } 371 372 /** 373 * This plugin will inject content into the review panel with javascript. 374 * @return bool true 375 */ 376 public function supports_review_panel() { 377 return true; 378 } 379 380 /** 381 * Return the plugin configs for external functions. 382 * 383 * @return array the list of settings 384 * @since Moodle 3.2 385 */ 386 public function get_config_for_external() { 387 return (array) $this->get_config(); 388 } 389 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body