die; } else { if ($action == 'revertchanges') { require_capability('mod/assign:grade', $context); $grade = $assignment->get_user_grade($userid, true, $attemptnumber); $result = page_editor::revert_drafts($gradeid); echo json_encode($result); die; } else { if ($action == 'removefromquicklist') { require_capability('mod/assign:grade', $context); $commentid = required_param('commentid', PARAM_INT); $result = comments_quick_list::remove_comment($commentid); echo json_encode($result); die; } else { if ($action == 'deletefeedbackdocument') { require_capability('mod/assign:grade', $context); $grade = $assignment->get_user_grade($userid, true, $attemptnumber); $result = document_services::delete_feedback_document($assignment, $userid, $attemptnumber); $result = $result && page_editor::unrelease_drafts($grade->id); echo json_encode($result); die; } } } } } } } }
/** * Display the list of files in the feedback status table. * * @param stdClass $grade * @return string */ public function view(stdClass $grade) { global $PAGE; $html = ''; // Show a link to download the pdf. if (page_editor::has_annotations_or_comments($grade->id, false)) { $html = $this->assignment->render_area_files('assignfeedback_editpdf', document_services::FINAL_PDF_FILEAREA, $grade->id); // Also show the link to the read-only interface. $renderer = $PAGE->get_renderer('assignfeedback_editpdf'); $widget = $this->get_widget($grade->userid, $grade, true); $html .= $renderer->render($widget); } return $html; }
/** * Test that modifying the annotated pdf form return true when modified * and false when not modified. */ public function test_is_feedback_modified() { global $DB; $assign = $this->create_assign_and_submit_pdf(); $this->setUser($this->teachers[0]); $grade = $assign->get_user_grade($this->students[0]->id, true); $notempty = page_editor::has_annotations_or_comments($grade->id, false); $this->assertFalse($notempty); $comment = new comment(); $comment->rawtext = 'Comment text'; $comment->width = 100; $comment->x = 100; $comment->y = 100; $comment->colour = 'red'; page_editor::set_comments($grade->id, 0, array($comment)); $annotations = array(); $annotation = new annotation(); $annotation->path = ''; $annotation->x = 100; $annotation->y = 100; $annotation->endx = 200; $annotation->endy = 200; $annotation->type = 'line'; $annotation->colour = 'red'; array_push($annotations, $annotation); page_editor::set_annotations($grade->id, 0, $annotations); $plugin = $assign->get_feedback_plugin_by_type('editpdf'); $data = new stdClass(); $data->editpdf_source_userid = $this->students[0]->id; $this->assertTrue($plugin->is_feedback_modified($grade, $data)); $plugin->save($grade, $data); $annotation = new annotation(); $annotation->gradeid = $grade->id; $annotation->pageno = 0; $annotation->path = ''; $annotation->x = 100; $annotation->y = 100; $annotation->endx = 200; $annotation->endy = 200; $annotation->type = 'rectangle'; $annotation->colour = 'yellow'; $yellowannotationid = page_editor::add_annotation($annotation); // Add a comment as well. $comment = new comment(); $comment->gradeid = $grade->id; $comment->pageno = 0; $comment->rawtext = 'Second Comment text'; $comment->width = 100; $comment->x = 100; $comment->y = 100; $comment->colour = 'red'; page_editor::add_comment($comment); $this->assertTrue($plugin->is_feedback_modified($grade, $data)); $plugin->save($grade, $data); // We should have two annotations. $this->assertCount(2, page_editor::get_annotations($grade->id, 0, false)); // And two comments. $this->assertCount(2, page_editor::get_comments($grade->id, 0, false)); // Add one annotation and delete another. $annotation = new annotation(); $annotation->gradeid = $grade->id; $annotation->pageno = 0; $annotation->path = '100,100:105,105:110,100'; $annotation->x = 100; $annotation->y = 100; $annotation->endx = 110; $annotation->endy = 105; $annotation->type = 'pen'; $annotation->colour = 'black'; page_editor::add_annotation($annotation); $annotations = page_editor::get_annotations($grade->id, 0, true); page_editor::remove_annotation($yellowannotationid); $this->assertTrue($plugin->is_feedback_modified($grade, $data)); $plugin->save($grade, $data); // We should have two annotations. $this->assertCount(2, page_editor::get_annotations($grade->id, 0, false)); // And two comments. $this->assertCount(2, page_editor::get_comments($grade->id, 0, false)); // Add a comment and then remove it. Should not be considered as modified. $comment = new comment(); $comment->gradeid = $grade->id; $comment->pageno = 0; $comment->rawtext = 'Third Comment text'; $comment->width = 400; $comment->x = 57; $comment->y = 205; $comment->colour = 'black'; $comment->id = page_editor::add_comment($comment); // We should now have three comments. $this->assertCount(3, page_editor::get_comments($grade->id, 0, true)); // Now delete the newest record. page_editor::remove_comment($comment->id); // Back to two comments. $this->assertCount(2, page_editor::get_comments($grade->id, 0, true)); // No modification. $this->assertFalse($plugin->is_feedback_modified($grade, $data)); }
public function test_document_services() { $assign = $this->create_assign_and_submit_pdf(); $this->setUser($this->teachers[0]); $grade = $assign->get_user_grade($this->students[0]->id, true); $notempty = page_editor::has_annotations_or_comments($grade->id, false); $this->assertFalse($notempty); $comment = new comment(); $comment->rawtext = 'Comment text'; $comment->width = 100; $comment->x = 100; $comment->y = 100; $comment->colour = 'red'; page_editor::set_comments($grade->id, 0, array($comment)); $annotations = array(); $annotation = new annotation(); $annotation->path = ''; $annotation->x = 100; $annotation->y = 100; $annotation->endx = 200; $annotation->endy = 200; $annotation->type = 'line'; $annotation->colour = 'red'; array_push($annotations, $annotation); $annotation = new annotation(); $annotation->path = ''; $annotation->x = 100; $annotation->y = 100; $annotation->endx = 200; $annotation->endy = 200; $annotation->type = 'rectangle'; $annotation->colour = 'yellow'; array_push($annotations, $annotation); $annotation = new annotation(); $annotation->path = ''; $annotation->x = 100; $annotation->y = 100; $annotation->endx = 200; $annotation->endy = 200; $annotation->type = 'oval'; $annotation->colour = 'green'; array_push($annotations, $annotation); $annotation = new annotation(); $annotation->path = ''; $annotation->x = 100; $annotation->y = 100; $annotation->endx = 200; $annotation->endy = 116; $annotation->type = 'highlight'; $annotation->colour = 'blue'; array_push($annotations, $annotation); $annotation = new annotation(); $annotation->path = '100,100:105,105:110,100'; $annotation->x = 100; $annotation->y = 100; $annotation->endx = 110; $annotation->endy = 105; $annotation->type = 'pen'; $annotation->colour = 'black'; array_push($annotations, $annotation); page_editor::set_annotations($grade->id, 0, $annotations); page_editor::release_drafts($grade->id); $notempty = page_editor::has_annotations_or_comments($grade->id, false); $this->assertTrue($notempty); $file = document_services::generate_feedback_document($assign->get_instance()->id, $grade->userid, $grade->attemptnumber); $this->assertNotEmpty($file); $file2 = document_services::get_feedback_document($assign->get_instance()->id, $grade->userid, $grade->attemptnumber); $this->assertEquals($file, $file2); document_services::delete_feedback_document($assign->get_instance()->id, $grade->userid, $grade->attemptnumber); $file3 = document_services::get_feedback_document($assign->get_instance()->id, $grade->userid, $grade->attemptnumber); $this->assertEmpty($file3); }
/** * This function takes the combined pdf and embeds all the comments and annotations. * * This also moves the annotations and comments from drafts to not drafts. And it will * copy all the images stored to the readonly area, so that they can be viewed online, and * not be overwritten when a new submission is sent. * * @param int|\assign $assignment * @param int $userid * @param int $attemptnumber (-1 means latest attempt) * @return stored_file */ public static function generate_feedback_document($assignment, $userid, $attemptnumber) { $assignment = self::get_assignment_from_param($assignment); if (!$assignment->can_view_submission($userid)) { \print_error('nopermission'); } if (!$assignment->can_grade()) { \print_error('nopermission'); } // Need to generate the page images - first get a combined pdf. $file = self::get_combined_pdf_for_attempt($assignment, $userid, $attemptnumber); if (!$file) { throw new \moodle_exception('Could not generate combined pdf.'); } $tmpdir = \make_temp_directory('assignfeedback_editpdf/final/' . self::hash($assignment, $userid, $attemptnumber)); $combined = $tmpdir . '/' . self::COMBINED_PDF_FILENAME; $file->copy_content_to($combined); // Copy the file. $pdf = new pdf(); $fs = \get_file_storage(); $stamptmpdir = \make_temp_directory('assignfeedback_editpdf/stamps/' . self::hash($assignment, $userid, $attemptnumber)); $grade = $assignment->get_user_grade($userid, true, $attemptnumber); // Copy any new stamps to this instance. if ($files = $fs->get_area_files($assignment->get_context()->id, 'assignfeedback_editpdf', 'stamps', $grade->id, "filename", false)) { foreach ($files as $file) { $filename = $stamptmpdir . '/' . $file->get_filename(); $file->copy_content_to($filename); // Copy the file. } } $pagecount = $pdf->set_pdf($combined); $grade = $assignment->get_user_grade($userid, true, $attemptnumber); page_editor::release_drafts($grade->id); for ($i = 0; $i < $pagecount; $i++) { $pdf->copy_page(); $comments = page_editor::get_comments($grade->id, $i, false); $annotations = page_editor::get_annotations($grade->id, $i, false); foreach ($comments as $comment) { $pdf->add_comment($comment->rawtext, $comment->x, $comment->y, $comment->width, $comment->colour); } foreach ($annotations as $annotation) { $pdf->add_annotation($annotation->x, $annotation->y, $annotation->endx, $annotation->endy, $annotation->colour, $annotation->type, $annotation->path, $stamptmpdir); } } fulldelete($stamptmpdir); $filename = self::get_downloadable_feedback_filename($assignment, $userid, $attemptnumber); $filename = clean_param($filename, PARAM_FILE); $generatedpdf = $tmpdir . '/' . $filename; $pdf->save_pdf($generatedpdf); $record = new \stdClass(); $record->contextid = $assignment->get_context()->id; $record->component = 'assignfeedback_editpdf'; $record->filearea = self::FINAL_PDF_FILEAREA; $record->itemid = $grade->id; $record->filepath = '/'; $record->filename = $filename; // Only keep one current version of the generated pdf. $fs->delete_area_files($record->contextid, $record->component, $record->filearea, $record->itemid); $file = $fs->create_file_from_pathname($record, $generatedpdf); // Cleanup. @unlink($generatedpdf); @unlink($combined); @rmdir($tmpdir); self::copy_pages_to_readonly_area($assignment, $grade); return $file; }