Gitlab CSE Unil

Commit 84642d6f authored by M. Chardon's avatar M. Chardon
Browse files

editpdfplus : adaptations moodle 3.7

parent 11e3d7f4
...@@ -74,6 +74,7 @@ if ($action === 'pollconversions') { ...@@ -74,6 +74,7 @@ if ($action === 'pollconversions') {
'filecount' => 0, 'filecount' => 0,
'pagecount' => 0, 'pagecount' => 0,
'pageready' => 0, 'pageready' => 0,
'partial' => false,
'pages' => [], 'pages' => [],
]; ];
...@@ -81,10 +82,13 @@ if ($action === 'pollconversions') { ...@@ -81,10 +82,13 @@ if ($action === 'pollconversions') {
$response->status = $combineddocument->get_status(); $response->status = $combineddocument->get_status();
$response->filecount = $combineddocument->get_document_count(); $response->filecount = $combineddocument->get_document_count();
if ($response->status === combined_document::STATUS_READY) { $readystatuslist = [combined_document::STATUS_READY, combined_document::STATUS_READY_PARTIAL];
$completestatuslist = [combined_document::STATUS_COMPLETE, combined_document::STATUS_FAILED];
if (in_array($response->status, $readystatuslist)) {
$combineddocument = document_services::get_combined_pdf_for_attempt($assignment, $userid, $attemptnumber); $combineddocument = document_services::get_combined_pdf_for_attempt($assignment, $userid, $attemptnumber);
$response->pagecount = $combineddocument->get_page_count(); $response->pagecount = $combineddocument->get_page_count();
} else if ($response->status === combined_document::STATUS_COMPLETE || $response->status === combined_document::STATUS_FAILED) { } else if (in_array($response->status, $completestatuslist)) {
$pages = document_services::get_page_images_for_attempt($assignment, $userid, $attemptnumber, $readonly); $pages = document_services::get_page_images_for_attempt($assignment, $userid, $attemptnumber, $readonly);
$response->pagecount = $combineddocument->get_page_count(); $response->pagecount = $combineddocument->get_page_count();
...@@ -96,6 +100,7 @@ if ($action === 'pollconversions') { ...@@ -96,6 +100,7 @@ if ($action === 'pollconversions') {
if ($readonly) { if ($readonly) {
$filearea = document_services::PAGE_IMAGE_READONLY_FILEAREA; $filearea = document_services::PAGE_IMAGE_READONLY_FILEAREA;
} }
$response->partial = $combineddocument->is_partial_conversion();
foreach ($pages as $id => $pagefile) { foreach ($pages as $id => $pagefile) {
$index = count($response->pages); $index = count($response->pages);
...@@ -174,11 +179,11 @@ if ($action === 'pollconversions') { ...@@ -174,11 +179,11 @@ if ($action === 'pollconversions') {
$teachers = get_users_by_capability($context, 'assignfeedback/editpdfplus:notify'); $teachers = get_users_by_capability($context, 'assignfeedback/editpdfplus:notify');
$course = $assignment->get_course(); $course = $assignment->get_course();
$coursemodule = $assignment->get_course_module(); $coursemodule = $assignment->get_course_module();
$a = (object)[ $a = (object) [
'coursename' => format_string($course->shortname, true), 'coursename' => format_string($course->shortname, true),
'modulename' => get_string('modulename', 'assign'), 'modulename' => get_string('modulename', 'assign'),
'assignmentname' => format_string($assignment->get_instance()->name, true), 'assignmentname' => format_string($assignment->get_instance()->name, true),
'url' => $response->url 'url' => $response->url
]; ];
foreach ($teachers as $teacher) { foreach ($teachers as $teacher) {
$res = email_to_user($teacher, $USER, get_string('assignmentgradedsubject', 'assignfeedback_editpdfplus'), get_string('assignmentgradedbody', 'assignfeedback_editpdfplus', $a)); $res = email_to_user($teacher, $USER, get_string('assignmentgradedsubject', 'assignfeedback_editpdfplus'), get_string('assignmentgradedbody', 'assignfeedback_editpdfplus', $a));
...@@ -205,6 +210,27 @@ if ($action === 'pollconversions') { ...@@ -205,6 +210,27 @@ if ($action === 'pollconversions') {
$result = $result && page_editor::unrelease_drafts($grade->id); $result = $result && page_editor::unrelease_drafts($grade->id);
echo json_encode($result); echo json_encode($result);
die(); die();
} else if ($action == 'rotatepage') {
require_capability(PERMISSION_ASSIGN_GRADE, $context);
$response = new stdClass();
$index = required_param('index', PARAM_INT);
$grade = $assignment->get_user_grade($userid, true, $attemptnumber);
$rotateleft = required_param('rotateleft', PARAM_BOOL);
$filearea = document_services::PAGE_IMAGE_FILEAREA;
$pagefile = document_services::rotate_page($assignment, $userid, $attemptnumber, $index, $rotateleft);
$page = new stdClass();
$page->url = moodle_url::make_pluginfile_url($context->id, document_services::COMPONENT, $filearea,
$grade->id, '/', $pagefile->get_filename())->out();
if ($imageinfo = $pagefile->get_imageinfo()) {
$page->width = $imageinfo['width'];
$page->height = $imageinfo['height'];
} else {
$page->width = 0;
$page->height = 0;
}
$response = (object) ['page' => $page];
echo json_encode($response);
die();
} else if ($action == 'updatestudentview') { } else if ($action == 'updatestudentview') {
require_capability(PERMISSION_ASSIGN_SUBMIT, $context); require_capability(PERMISSION_ASSIGN_SUBMIT, $context);
......
...@@ -47,16 +47,22 @@ class backup_assignfeedback_editpdfplus_subplugin extends backup_subplugin { ...@@ -47,16 +47,22 @@ class backup_assignfeedback_editpdfplus_subplugin extends backup_subplugin {
$subpluginelementannotation = new backup_nested_element( $subpluginelementannotation = new backup_nested_element(
'feedback_editpdfplus_annotation', null, array(self::GRADEID, 'pageno', 'x', 'y', 'endx', 'endy', 'cartridgex', 'cartridgey', 'path', 'toolid', 'textannot', 'colour', 'draft', 'answerrequested', 'studentanswer', 'studentstatus', 'displaylock', 'displayrotation', 'borderstyle', 'parent_annot') 'feedback_editpdfplus_annotation', null, array(self::GRADEID, 'pageno', 'x', 'y', 'endx', 'endy', 'cartridgex', 'cartridgey', 'path', 'toolid', 'textannot', 'colour', 'draft', 'answerrequested', 'studentanswer', 'studentstatus', 'displaylock', 'displayrotation', 'borderstyle', 'parent_annot')
); );
$subpluginelementrotation = new backup_nested_element('feedback_editpdfplus_rotation');
$subpluginelementpagerotation = new backup_nested_element('pagerotation', null,
array('gradeid', 'pageno', 'pathnamehash', 'isrotated', 'degree'));
// Connect XML elements into the tree. // Connect XML elements into the tree.
$subplugin->add_child($subpluginwrapper); $subplugin->add_child($subpluginwrapper);
$subpluginelementannotations->add_child($subpluginelementannotation); $subpluginelementannotations->add_child($subpluginelementannotation);
$subpluginelementrotation->add_child($subpluginelementpagerotation);
$subpluginwrapper->add_child($subpluginelementfiles); $subpluginwrapper->add_child($subpluginelementfiles);
$subpluginwrapper->add_child($subpluginelementannotations); $subpluginwrapper->add_child($subpluginelementannotations);
$subpluginwrapper->add_child($subpluginelementrotation);
// Set source to populate the data. // Set source to populate the data.
$subpluginelementfiles->set_source_sql('SELECT id AS gradeid from {assign_grades} where id = :' . self::GRADEID, array(self::GRADEID => backup::VAR_PARENTID)); $subpluginelementfiles->set_source_sql('SELECT id AS gradeid from {assign_grades} where id = :' . self::GRADEID, array(self::GRADEID => backup::VAR_PARENTID));
$subpluginelementannotation->set_source_table('assignfeedback_editpp_annot', array(self::GRADEID => backup::VAR_PARENTID)); $subpluginelementannotation->set_source_table('assignfeedback_editpp_annot', array(self::GRADEID => backup::VAR_PARENTID));
$subpluginelementpagerotation->set_source_table('assignfeedback_editpp_rot', array('gradeid' => backup::VAR_PARENTID));
// We only need to backup the files in the final pdf area, and the readonly page images - the others can be regenerated. // We only need to backup the files in the final pdf area, and the readonly page images - the others can be regenerated.
$subpluginelementfiles->annotate_files('assignfeedback_editpdfplus', \assignfeedback_editpdfplus\document_services::FINAL_PDF_FILEAREA, self::GRADEID); $subpluginelementfiles->annotate_files('assignfeedback_editpdfplus', \assignfeedback_editpdfplus\document_services::FINAL_PDF_FILEAREA, self::GRADEID);
$subpluginelementfiles->annotate_files('assignfeedback_editpdfplus', \assignfeedback_editpdfplus\document_services::PAGE_IMAGE_READONLY_FILEAREA, self::GRADEID); $subpluginelementfiles->annotate_files('assignfeedback_editpdfplus', \assignfeedback_editpdfplus\document_services::PAGE_IMAGE_READONLY_FILEAREA, self::GRADEID);
......
...@@ -52,6 +52,12 @@ class restore_assignfeedback_editpdfplus_subplugin extends restore_subplugin { ...@@ -52,6 +52,12 @@ class restore_assignfeedback_editpdfplus_subplugin extends restore_subplugin {
$elename = $this->get_namefor('feedback_editpdfplus_annotation'); $elename = $this->get_namefor('feedback_editpdfplus_annotation');
$elepath = $this->get_pathfor('/feedback_editpdfplus_annotations/feedback_editpdfplus_annotation'); $elepath = $this->get_pathfor('/feedback_editpdfplus_annotations/feedback_editpdfplus_annotation');
$paths[] = new restore_path_element($elename, $elepath); $paths[] = new restore_path_element($elename, $elepath);
// Rotation details.
$elename = $this->get_namefor('pagerotation');
$elepath = $this->get_pathfor('/feedback_editpdfplus_rotation/pagerotation');
$paths[] = new restore_path_element($elename, $elepath);
return $paths; return $paths;
} }
...@@ -84,4 +90,15 @@ class restore_assignfeedback_editpdfplus_subplugin extends restore_subplugin { ...@@ -84,4 +90,15 @@ class restore_assignfeedback_editpdfplus_subplugin extends restore_subplugin {
$DB->insert_record('assignfeedback_editpp_annot', $data); $DB->insert_record('assignfeedback_editpp_annot', $data);
} }
/**
* Processes one /feedback_editpdfplus_rotation/pagerotation element
* @param mixed $data
*/
public function process_assignfeedback_editpdfplus_pagerotation($data) {
global $DB;
$data = (object)$data;
$oldgradeid = $data->gradeid;
$data->gradeid = $this->get_mappingid('grade', $oldgradeid);
$DB->insert_record('assignfeedback_editpp_rot', $data);
}
} }
...@@ -40,7 +40,9 @@ class tool_generic extends tool { ...@@ -40,7 +40,9 @@ class tool_generic extends tool {
"rectangle" => "fa fa-square-o", "rectangle" => "fa fa-square-o",
"drag" => "fa fa-hand-paper-o", "drag" => "fa fa-hand-paper-o",
"select" => "fa fa-mouse-pointer", "select" => "fa fa-mouse-pointer",
"annotationcolour" => "fa fa-tint" "annotationcolour" => "fa fa-tint",
"rotateleft" => "fa fa-undo",
"rotateright" => "fa fa-undo fa-flip-horizontal"
); );
/** /**
......
...@@ -47,6 +47,11 @@ class combined_document { ...@@ -47,6 +47,11 @@ class combined_document {
*/ */
const STATUS_COMPLETE = 2; const STATUS_COMPLETE = 2;
/**
* Status value representing all documents are ready to be combined as are supported.
*/
const STATUS_READY_PARTIAL = 3;
/** /**
* Status value representing a permanent error. * Status value representing a permanent error.
*/ */
...@@ -74,6 +79,9 @@ class combined_document { ...@@ -74,6 +79,9 @@ class combined_document {
/** /**
* Check the current status of the document combination. * Check the current status of the document combination.
* Note that the combined document may not contain all the source files if some of the
* source files were not able to be converted. An example is an audio file with a pdf cover sheet. Only
* the cover sheet will be included in the combined document.
* *
* @return int * @return int
*/ */
...@@ -95,6 +103,7 @@ class combined_document { ...@@ -95,6 +103,7 @@ class combined_document {
} }
$pending = false; $pending = false;
$partial = false;
foreach ($this->sourcefiles as $file) { foreach ($this->sourcefiles as $file) {
// The combined file has not yet been generated. // The combined file has not yet been generated.
// Check the status of each source file. // Check the status of each source file.
...@@ -107,7 +116,9 @@ class combined_document { ...@@ -107,7 +116,9 @@ class combined_document {
break; break;
case \core_files\conversion::STATUS_FAILED: case \core_files\conversion::STATUS_FAILED:
return self::STATUS_FAILED; $partial = true;
break;
default : default :
break; break;
} }
...@@ -116,10 +127,27 @@ class combined_document { ...@@ -116,10 +127,27 @@ class combined_document {
if ($pending) { if ($pending) {
return self::STATUS_PENDING_INPUT; return self::STATUS_PENDING_INPUT;
} else { } else {
if ($partial) {
return self::STATUS_READY_PARTIAL;
}
return self::STATUS_READY; return self::STATUS_READY;
} }
} }
/**
* Return true of the combined file contained only some of the submission files.
*
* @return boolean
*/
public function is_partial_conversion() {
$combinedfile = $this->get_combined_file();
if (empty($combinedfile)) {
return false;
}
$filearea = $combinedfile->get_filearea();
return $filearea == document_services::PARTIAL_PDF_FILEAREA;
}
/** /**
* Set the completed combined file. * Set the completed combined file.
* *
...@@ -188,7 +216,7 @@ class combined_document { ...@@ -188,7 +216,7 @@ class combined_document {
$status = $file->get('status'); $status = $file->get('status');
switch ($status) { switch ($status) {
case \core_files\conversion::STATUS_COMPLETE: case \core_files\conversion::STATUS_COMPLETE:
continue; continue 2;
default: default:
$converter->poll_conversion($conversion); $converter->poll_conversion($conversion);
} }
...@@ -210,11 +238,12 @@ class combined_document { ...@@ -210,11 +238,12 @@ class combined_document {
global $CFG; global $CFG;
$currentstatus = $this->get_status(); $currentstatus = $this->get_status();
$readystatuslist = [self::STATUS_READY, self::STATUS_READY_PARTIAL];
if ($currentstatus === self::STATUS_FAILED) { if ($currentstatus === self::STATUS_FAILED) {
$this->store_empty_document($contextid, $itemid); $this->store_empty_document($contextid, $itemid);
return $this; return $this;
} else if ($currentstatus !== self::STATUS_READY) { } else if (!in_array($currentstatus, $readystatuslist)) {
// The document is either: // The document is either:
// * already combined; or // * already combined; or
// * pending input being fully converted; or // * pending input being fully converted; or
...@@ -235,7 +264,10 @@ class combined_document { ...@@ -235,7 +264,10 @@ class combined_document {
// Note: We drop non-compatible files. // Note: We drop non-compatible files.
$compatiblepdf = false; $compatiblepdf = false;
if (is_a($file, \core_files\conversion::class)) { if (is_a($file, \core_files\conversion::class)) {
$compatiblepdf = pdf::ensure_pdf_compatible($file->get_destfile()); $status = $file->get('status');
if ($status == \core_files\conversion::STATUS_COMPLETE) {
$compatiblepdf = pdf::ensure_pdf_compatible($file->get_destfile());
}
} else { } else {
$compatiblepdf = pdf::ensure_pdf_compatible($file); $compatiblepdf = pdf::ensure_pdf_compatible($file);
} }
...@@ -270,7 +302,7 @@ class combined_document { ...@@ -270,7 +302,7 @@ class combined_document {
} }
// Store the newly created file as a stored_file. // Store the newly created file as a stored_file.
$this->store_combined_file($tmpfile, $contextid, $itemid); $this->store_combined_file($tmpfile, $contextid, $itemid, ($currentstatus == self::STATUS_READY_PARTIAL));
// Note the verified page count. // Note the verified page count.
$this->pagecount = $verifypagecount; $this->pagecount = $verifypagecount;
...@@ -295,11 +327,12 @@ class combined_document { ...@@ -295,11 +327,12 @@ class combined_document {
* @param string $tmpfile The path to the file on disk to be stored. * @param string $tmpfile The path to the file on disk to be stored.
* @param int $contextid The contextid for the file to be stored under * @param int $contextid The contextid for the file to be stored under
* @param int $itemid The itemid for the file to be stored under * @param int $itemid The itemid for the file to be stored under
* @param boolean $partial The combined pdf contains only some of the source files.
* @return $this * @return $this
*/ */
protected function store_combined_file($tmpfile, $contextid, $itemid) { protected function store_combined_file($tmpfile, $contextid, $itemid, $partial = false) {
// Store the file. // Store the file.
$record = $this->get_stored_file_record($contextid, $itemid); $record = $this->get_stored_file_record($contextid, $itemid, $partial);
$fs = get_file_storage(); $fs = get_file_storage();
// Delete existing files first. // Delete existing files first.
...@@ -349,12 +382,14 @@ class combined_document { ...@@ -349,12 +382,14 @@ class combined_document {
return $this->pagecount; return $this->pagecount;
} }
if ($this->get_status() === self::STATUS_FAILED) { $status = $this->get_status();
if ($status === self::STATUS_FAILED) {
// The empty document will be returned. // The empty document will be returned.
return 1; return 1;
} }
if ($this->get_status() !== self::STATUS_COMPLETE) { if ($status !== self::STATUS_COMPLETE) {
// No pages yet. // No pages yet.
return 0; return 0;
} }
...@@ -391,13 +426,18 @@ class combined_document { ...@@ -391,13 +426,18 @@ class combined_document {
* *
* @param int $contextid The contextid for the file to be stored under * @param int $contextid The contextid for the file to be stored under
* @param int $itemid The itemid for the file to be stored under * @param int $itemid The itemid for the file to be stored under
* @param boolean $partial The combined file contains only some of the source files.
* @return stdClass * @return stdClass
*/ */
protected function get_stored_file_record($contextid, $itemid) { protected function get_stored_file_record($contextid, $itemid, $partial = false) {
$filearea = document_services::COMBINED_PDF_FILEAREA;
if ($partial) {
$filearea = document_services::PARTIAL_PDF_FILEAREA;
}
return (object) [ return (object) [
'contextid' => $contextid, 'contextid' => $contextid,
'component' => 'assignfeedback_editpdfplus', 'component' => 'assignfeedback_editpdfplus',
'filearea' => document_services::COMBINED_PDF_FILEAREA, 'filearea' => $filearea,
'itemid' => $itemid, 'itemid' => $itemid,
'filepath' => '/', 'filepath' => '/',
'filename' => document_services::COMBINED_PDF_FILENAME, 'filename' => document_services::COMBINED_PDF_FILENAME,
......
...@@ -37,12 +37,18 @@ use DOMDocument; ...@@ -37,12 +37,18 @@ use DOMDocument;
class document_services { class document_services {
/** Compoment name */
const COMPONENT = "assignfeedback_editpdfplus";
/** File area for generated pdf */ /** File area for generated pdf */
const FINAL_PDF_FILEAREA = 'download'; const FINAL_PDF_FILEAREA = 'download';
/** File area for combined pdf */ /** File area for combined pdf */
const COMBINED_PDF_FILEAREA = 'combined'; const COMBINED_PDF_FILEAREA = 'combined';
/** File area for partial combined pdf */
const PARTIAL_PDF_FILEAREA = 'partial';
/** File area for importing html */ /** File area for importing html */
const IMPORT_HTML_FILEAREA = 'importhtml'; const IMPORT_HTML_FILEAREA = 'importhtml';
...@@ -85,7 +91,6 @@ RTg3MkIyMjU4NTI2RTg+IF0KL0RvY0NoZWNrc3VtIC9BNTYwMEZCMDAzRURCRTg0MTNBNTk3RTZF ...@@ -85,7 +91,6 @@ RTg3MkIyMjU4NTI2RTg+IF0KL0RvY0NoZWNrc3VtIC9BNTYwMEZCMDAzRURCRTg0MTNBNTk3RTZF
MURDQzJBRgo+PgpzdGFydHhyZWYKNzM2CiUlRU9GCg== MURDQzJBRgo+PgpzdGFydHhyZWYKNzM2CiUlRU9GCg==
EOD; EOD;
const NOPERMISSIONMESSAGE = "nopermission"; const NOPERMISSIONMESSAGE = "nopermission";
const PLUGIN_NAME = "assignfeedback_editpdfplus";
/** /**
* This function will take an int or an assignment instance and * This function will take an int or an assignment instance and
...@@ -128,23 +133,24 @@ EOD; ...@@ -128,23 +133,24 @@ EOD;
* @return string New html with no image tags. * @return string New html with no image tags.
*/ */
protected static function strip_images($html) { protected static function strip_images($html) {
// Load HTML and suppress any parsing errors (DOMDocument->loadHTML() does not current support HTML5 tags).
$dom = new DOMDocument(); $dom = new DOMDocument();
$dom->loadHTML("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>" . $html); libxml_use_internal_errors(true);
$images = $dom->getElementsByTagName('img'); $dom->loadHTML('<?xml version="1.0" encoding="UTF-8" ?>' . $html);
$i = 0; libxml_clear_errors();
for ($i = ($images->length - 1); $i >= 0; $i--) { // Find all img tags.
$node = $images->item($i); if ($imgnodes = $dom->getElementsByTagName('img')) {
// Replace img nodes with the img alt text without overriding DOM elements.
if ($node->hasAttribute('alt')) { for ($i = ($imgnodes->length - 1); $i >= 0; $i--) {
$replacement = ' [ ' . $node->getAttribute('alt') . ' ] '; $imgnode = $imgnodes->item($i);
} else { $alt = ($imgnode->hasAttribute('alt')) ? ' [ ' . $imgnode->getAttribute('alt') . ' ] ' : ' ';
$replacement = ' '; $textnode = $dom->createTextNode($alt);
$imgnode->parentNode->replaceChild($textnode, $imgnode);
} }
$text = $dom->createTextNode($replacement);
$node->parentNode->replaceChild($text, $node);
} }
$count = 1; $count = 1;
return str_replace("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>", "", $dom->saveHTML(), $count); return str_replace("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>", "", $dom->saveHTML(), $count);
} }
...@@ -200,7 +206,7 @@ EOD; ...@@ -200,7 +206,7 @@ EOD;
} else if ($converter->can_convert_format_to('html', 'pdf')) { } else if ($converter->can_convert_format_to('html', 'pdf')) {
$record = new \stdClass(); $record = new \stdClass();
$record->contextid = $assignment->get_context()->id; $record->contextid = $assignment->get_context()->id;
$record->component = self::PLUGIN_NAME; $record->component = self::COMPONENT;
$record->filearea = self::IMPORT_HTML_FILEAREA; $record->filearea = self::IMPORT_HTML_FILEAREA;
$record->itemid = $submission->id; $record->itemid = $submission->id;
$record->filepath = '/'; $record->filepath = '/';
...@@ -277,7 +283,7 @@ EOD; ...@@ -277,7 +283,7 @@ EOD;
} }
$contextid = $assignment->get_context()->id; $contextid = $assignment->get_context()->id;
$component = self::PLUGIN_NAME; $component = self::COMPONENT;
$filearea = self::COMBINED_PDF_FILEAREA; $filearea = self::COMBINED_PDF_FILEAREA;
$itemid = $grade->id; $itemid = $grade->id;
$filepath = '/'; $filepath = '/';
...@@ -352,7 +358,7 @@ EOD; ...@@ -352,7 +358,7 @@ EOD;
if ($readonly) { if ($readonly) {
$grade = $assignment->get_user_grade($userid, true, $attemptnumber); $grade = $assignment->get_user_grade($userid, true, $attemptnumber);
$fs = get_file_storage(); $fs = get_file_storage();
$files = $fs->get_directory_files($assignment->get_context()->id, self::PLUGIN_NAME, self::PAGE_IMAGE_READONLY_FILEAREA, $grade->id, '/'); $files = $fs->get_directory_files($assignment->get_context()->id, self::COMPONENT, self::PAGE_IMAGE_READONLY_FILEAREA, $grade->id, '/');
$pagecount = count($files); $pagecount = count($files);
if ($pagecount > 0) { if ($pagecount > 0) {
return $pagecount; return $pagecount;
...@@ -369,9 +375,10 @@ EOD; ...@@ -369,9 +375,10 @@ EOD;
* @param int|\assign $assignment * @param int|\assign $assignment
* @param int $userid * @param int $userid
* @param int $attemptnumber (-1 means latest attempt) * @param int $attemptnumber (-1 means latest attempt)
* @param bool $resetrotation check if need to reset page rotation information
* @return array(stored_file) * @return array(stored_file)
*/ */
protected static function generate_page_images_for_attempt($assignment, $userid, $attemptnumber) { protected static function generate_page_images_for_attempt($assignment, $userid, $attemptnumber, $resetrotation = true) {
global $CFG; global $CFG;
require_once($CFG->libdir . '/pdflib.php'); require_once($CFG->libdir . '/pdflib.php');
...@@ -406,7 +413,7 @@ EOD; ...@@ -406,7 +413,7 @@ EOD;
$record = new \stdClass(); $record = new \stdClass();
$record->contextid = $assignment->get_context()->id; $record->contextid = $assignment->get_context()->id;
$record->component = self::PLUGIN_NAME; $record->component = self::COMPONENT;
$record->filearea = self::PAGE_IMAGE_FILEAREA; $record->filearea = self::PAGE_IMAGE_FILEAREA;
$record->itemid = $grade->id; $record->itemid = $grade->id;
$record->filepath = '/'; $record->filepath = '/';
...@@ -419,6 +426,16 @@ EOD; ...@@ -419,6 +426,16 @@ EOD;
for ($i = 0; $i < $pagecount; $i++) { for ($i = 0; $i < $pagecount; $i++) {
try { try {
$image = $pdf->get_image($i); $image = $pdf->get_image($i);
if (!$resetrotation) {
$pagerotation = page_editor::get_page_rotation($grade->id, $i);
$degree = !empty($pagerotation) ? $pagerotation->degree : 0;
if ($degree != 0) {
$filepath = $tmpdir . '/' . $image;
$imageresource = imagecreatefrompng($filepath);
$content = imagerotate($imageresource, $degree, 0);
imagepng($content, $filepath);
}
}
} catch (\moodle_exception $e) { } catch (\moodle_exception $e) {
// We catch only moodle_exception here as other exceptions indicate issue with setup not the pdf. // We catch only moodle_exception here as other exceptions indicate issue with setup not the pdf.