Gitlab CSE Unil
Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
M. Chardon
moodle-assignfeedback_editpdfplus
Commits
84642d6f
Commit
84642d6f
authored
May 29, 2019
by
M. Chardon
Browse files
editpdfplus : adaptations moodle 3.7
parent
11e3d7f4
Changes
29
Expand all
Hide whitespace changes
Inline
Side-by-side
ajax.php
View file @
84642d6f
...
...
@@ -74,6 +74,7 @@ if ($action === 'pollconversions') {
'filecount'
=>
0
,
'pagecount'
=>
0
,
'pageready'
=>
0
,
'partial'
=>
false
,
'pages'
=>
[],
];
...
...
@@ -81,10 +82,13 @@ if ($action === 'pollconversions') {
$response
->
status
=
$combineddocument
->
get_status
();
$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
);
$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
);
$response
->
pagecount
=
$combineddocument
->
get_page_count
();
...
...
@@ -96,6 +100,7 @@ if ($action === 'pollconversions') {
if
(
$readonly
)
{
$filearea
=
document_services
::
PAGE_IMAGE_READONLY_FILEAREA
;
}
$response
->
partial
=
$combineddocument
->
is_partial_conversion
();
foreach
(
$pages
as
$id
=>
$pagefile
)
{
$index
=
count
(
$response
->
pages
);
...
...
@@ -174,11 +179,11 @@ if ($action === 'pollconversions') {
$teachers
=
get_users_by_capability
(
$context
,
'assignfeedback/editpdfplus:notify'
);
$course
=
$assignment
->
get_course
();
$coursemodule
=
$assignment
->
get_course_module
();
$a
=
(
object
)[
'coursename'
=>
format_string
(
$course
->
shortname
,
true
),
'modulename'
=>
get_string
(
'modulename'
,
'assign'
),
'assignmentname'
=>
format_string
(
$assignment
->
get_instance
()
->
name
,
true
),
'url'
=>
$response
->
url
$a
=
(
object
)
[
'coursename'
=>
format_string
(
$course
->
shortname
,
true
),
'modulename'
=>
get_string
(
'modulename'
,
'assign'
),
'assignmentname'
=>
format_string
(
$assignment
->
get_instance
()
->
name
,
true
),
'url'
=>
$response
->
url
];
foreach
(
$teachers
as
$teacher
)
{
$res
=
email_to_user
(
$teacher
,
$USER
,
get_string
(
'assignmentgradedsubject'
,
'assignfeedback_editpdfplus'
),
get_string
(
'assignmentgradedbody'
,
'assignfeedback_editpdfplus'
,
$a
));
...
...
@@ -205,6 +210,27 @@ if ($action === 'pollconversions') {
$result
=
$result
&&
page_editor
::
unrelease_drafts
(
$grade
->
id
);
echo
json_encode
(
$result
);
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'
)
{
require_capability
(
PERMISSION_ASSIGN_SUBMIT
,
$context
);
...
...
backup/moodle2/backup_assignfeedback_editpdfplus_subplugin.class.php
View file @
84642d6f
...
...
@@ -47,16 +47,22 @@ class backup_assignfeedback_editpdfplus_subplugin extends backup_subplugin {
$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'
)
);
$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.
$subplugin
->
add_child
(
$subpluginwrapper
);
$subpluginelementannotations
->
add_child
(
$subpluginelementannotation
);
$subpluginelementrotation
->
add_child
(
$subpluginelementpagerotation
);
$subpluginwrapper
->
add_child
(
$subpluginelementfiles
);
$subpluginwrapper
->
add_child
(
$subpluginelementannotations
);
$subpluginwrapper
->
add_child
(
$subpluginelementrotation
);
// 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
));
$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.
$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
);
...
...
backup/moodle2/restore_assignfeedback_editpdfplus_subplugin.class.php
View file @
84642d6f
...
...
@@ -52,6 +52,12 @@ class restore_assignfeedback_editpdfplus_subplugin extends restore_subplugin {
$elename
=
$this
->
get_namefor
(
'feedback_editpdfplus_annotation'
);
$elepath
=
$this
->
get_pathfor
(
'/feedback_editpdfplus_annotations/feedback_editpdfplus_annotation'
);
$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
;
}
...
...
@@ -84,4 +90,15 @@ class restore_assignfeedback_editpdfplus_subplugin extends restore_subplugin {
$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
);
}
}
classes/bdd/tool_generic.php
View file @
84642d6f
...
...
@@ -40,7 +40,9 @@ class tool_generic extends tool {
"rectangle"
=>
"fa fa-square-o"
,
"drag"
=>
"fa fa-hand-paper-o"
,
"select"
=>
"fa fa-mouse-pointer"
,
"annotationcolour"
=>
"fa fa-tint"
"annotationcolour"
=>
"fa fa-tint"
,
"rotateleft"
=>
"fa fa-undo"
,
"rotateright"
=>
"fa fa-undo fa-flip-horizontal"
);
/**
...
...
classes/combined_document.php
View file @
84642d6f
...
...
@@ -47,6 +47,11 @@ class combined_document {
*/
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.
*/
...
...
@@ -74,6 +79,9 @@ class combined_document {
/**
* 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
*/
...
...
@@ -95,6 +103,7 @@ class combined_document {
}
$pending
=
false
;
$partial
=
false
;
foreach
(
$this
->
sourcefiles
as
$file
)
{
// The combined file has not yet been generated.
// Check the status of each source file.
...
...
@@ -107,7 +116,9 @@ class combined_document {
break
;
case
\
core_files\conversion
::
STATUS_FAILED
:
return
self
::
STATUS_FAILED
;
$partial
=
true
;
break
;
default
:
break
;
}
...
...
@@ -116,10 +127,27 @@ class combined_document {
if
(
$pending
)
{
return
self
::
STATUS_PENDING_INPUT
;
}
else
{
if
(
$partial
)
{
return
self
::
STATUS_READY_PARTIAL
;
}
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.
*
...
...
@@ -188,7 +216,7 @@ class combined_document {
$status
=
$file
->
get
(
'status'
);
switch
(
$status
)
{
case
\
core_files\conversion
::
STATUS_COMPLETE
:
continue
;
continue
2
;
default
:
$converter
->
poll_conversion
(
$conversion
);
}
...
...
@@ -210,11 +238,12 @@ class combined_document {
global
$CFG
;
$currentstatus
=
$this
->
get_status
();
$readystatuslist
=
[
self
::
STATUS_READY
,
self
::
STATUS_READY_PARTIAL
];
if
(
$currentstatus
===
self
::
STATUS_FAILED
)
{
$this
->
store_empty_document
(
$contextid
,
$itemid
);
return
$this
;
}
else
if
(
$currentstatus
!==
self
::
STATUS_READY
)
{
}
else
if
(
!
in_array
(
$currentstatus
,
$readystatuslist
)
)
{
// The document is either:
// * already combined; or
// * pending input being fully converted; or
...
...
@@ -235,7 +264,10 @@ class combined_document {
// Note: We drop non-compatible files.
$compatiblepdf
=
false
;
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
{
$compatiblepdf
=
pdf
::
ensure_pdf_compatible
(
$file
);
}
...
...
@@ -270,7 +302,7 @@ class combined_document {
}
// 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.
$this
->
pagecount
=
$verifypagecount
;
...
...
@@ -295,11 +327,12 @@ class combined_document {
* @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 $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
*/
protected
function
store_combined_file
(
$tmpfile
,
$contextid
,
$itemid
)
{
protected
function
store_combined_file
(
$tmpfile
,
$contextid
,
$itemid
,
$partial
=
false
)
{
// Store the file.
$record
=
$this
->
get_stored_file_record
(
$contextid
,
$itemid
);
$record
=
$this
->
get_stored_file_record
(
$contextid
,
$itemid
,
$partial
);
$fs
=
get_file_storage
();
// Delete existing files first.
...
...
@@ -349,12 +382,14 @@ class combined_document {
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.
return
1
;
}
if
(
$
this
->
get_
status
()
!==
self
::
STATUS_COMPLETE
)
{
if
(
$status
!==
self
::
STATUS_COMPLETE
)
{
// No pages yet.
return
0
;
}
...
...
@@ -391,13 +426,18 @@ class combined_document {
*
* @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 boolean $partial The combined file contains only some of the source files.
* @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
)
[
'contextid'
=>
$contextid
,
'component'
=>
'assignfeedback_editpdfplus'
,
'filearea'
=>
document_services
::
COMBINED_PDF_FILEAREA
,
'filearea'
=>
$filearea
,
'itemid'
=>
$itemid
,
'filepath'
=>
'/'
,
'filename'
=>
document_services
::
COMBINED_PDF_FILENAME
,
...
...
classes/document_services.php
View file @
84642d6f
...
...
@@ -37,12 +37,18 @@ use DOMDocument;
class
document_services
{
/** Compoment name */
const
COMPONENT
=
"assignfeedback_editpdfplus"
;
/** File area for generated pdf */
const
FINAL_PDF_FILEAREA
=
'download'
;
/** File area for combined pdf */
const
COMBINED_PDF_FILEAREA
=
'combined'
;
/** File area for partial combined pdf */
const
PARTIAL_PDF_FILEAREA
=
'partial'
;
/** File area for importing html */
const
IMPORT_HTML_FILEAREA
=
'importhtml'
;
...
...
@@ -85,7 +91,6 @@ RTg3MkIyMjU4NTI2RTg+IF0KL0RvY0NoZWNrc3VtIC9BNTYwMEZCMDAzRURCRTg0MTNBNTk3RTZF
MURDQzJBRgo+PgpzdGFydHhyZWYKNzM2CiUlRU9GCg==
EOD;
const
NOPERMISSIONMESSAGE
=
"nopermission"
;
const
PLUGIN_NAME
=
"assignfeedback_editpdfplus"
;
/**
* This function will take an int or an assignment instance and
...
...
@@ -128,23 +133,24 @@ EOD;
* @return string New html with no image tags.
*/
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
->
loadHTML
(
"<?xml version=
\"
1.0
\"
encoding=
\"
UTF-8
\"
?>"
.
$html
);
$images
=
$dom
->
getElementsByTagName
(
'img'
);
$i
=
0
;
for
(
$i
=
(
$images
->
length
-
1
);
$i
>=
0
;
$i
--
)
{
$node
=
$images
->
item
(
$i
);
if
(
$node
->
hasAttribute
(
'alt'
))
{
$replacement
=
' [ '
.
$node
->
getAttribute
(
'alt'
)
.
' ] '
;
}
else
{
$replacement
=
' '
;
libxml_use_internal_errors
(
true
);
$dom
->
loadHTML
(
'<?xml version="1.0" encoding="UTF-8" ?>'
.
$html
);
libxml_clear_errors
();
// Find all img tags.
if
(
$imgnodes
=
$dom
->
getElementsByTagName
(
'img'
))
{
// Replace img nodes with the img alt text without overriding DOM elements.
for
(
$i
=
(
$imgnodes
->
length
-
1
);
$i
>=
0
;
$i
--
)
{
$imgnode
=
$imgnodes
->
item
(
$i
);
$alt
=
(
$imgnode
->
hasAttribute
(
'alt'
))
?
' [ '
.
$imgnode
->
getAttribute
(
'alt'
)
.
' ] '
:
' '
;
$textnode
=
$dom
->
createTextNode
(
$alt
);
$imgnode
->
parentNode
->
replaceChild
(
$textnode
,
$imgnode
);
}
$text
=
$dom
->
createTextNode
(
$replacement
);
$node
->
parentNode
->
replaceChild
(
$text
,
$node
);
}
$count
=
1
;
return
str_replace
(
"<?xml version=
\"
1.0
\"
encoding=
\"
UTF-8
\"
?>"
,
""
,
$dom
->
saveHTML
(),
$count
);
}
...
...
@@ -200,7 +206,7 @@ EOD;
}
else
if
(
$converter
->
can_convert_format_to
(
'html'
,
'pdf'
))
{
$record
=
new
\
stdClass
();
$record
->
contextid
=
$assignment
->
get_context
()
->
id
;
$record
->
component
=
self
::
PLUGIN_NAME
;
$record
->
component
=
self
::
COMPONENT
;
$record
->
filearea
=
self
::
IMPORT_HTML_FILEAREA
;
$record
->
itemid
=
$submission
->
id
;
$record
->
filepath
=
'/'
;
...
...
@@ -277,7 +283,7 @@ EOD;
}
$contextid
=
$assignment
->
get_context
()
->
id
;
$component
=
self
::
PLUGIN_NAME
;
$component
=
self
::
COMPONENT
;
$filearea
=
self
::
COMBINED_PDF_FILEAREA
;
$itemid
=
$grade
->
id
;
$filepath
=
'/'
;
...
...
@@ -352,7 +358,7 @@ EOD;
if
(
$readonly
)
{
$grade
=
$assignment
->
get_user_grade
(
$userid
,
true
,
$attemptnumber
);
$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
);
if
(
$pagecount
>
0
)
{
return
$pagecount
;
...
...
@@ -369,9 +375,10 @@ EOD;
* @param int|\assign $assignment
* @param int $userid
* @param int $attemptnumber (-1 means latest attempt)
* @param bool $resetrotation check if need to reset page rotation information
* @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
;
require_once
(
$CFG
->
libdir
.
'/pdflib.php'
);
...
...
@@ -406,7 +413,7 @@ EOD;
$record
=
new
\
stdClass
();
$record
->
contextid
=
$assignment
->
get_context
()
->
id
;
$record
->
component
=
self
::
PLUGIN_NAME
;
$record
->
component
=
self
::
COMPONENT
;
$record
->
filearea
=
self
::
PAGE_IMAGE_FILEAREA
;
$record
->
itemid
=
$grade
->
id
;
$record
->
filepath
=
'/'
;
...
...
@@ -419,6 +426,16 @@ EOD;
for
(
$i
=
0
;
$i
<
$pagecount
;
$i
++
)
{
try
{
$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
)
{
// We catch only moodle_exception here as other exceptions indicate issue with setup not the pdf.
$image
=
pdf
::
get_error_image
(
$tmpdir
,
$i
);
...
...
@@ -426,6 +443,12 @@ EOD;
$record
->
filename
=
basename
(
$image
);
$files
[
$i
]
=
$fs
->
create_file_from_pathname
(
$record
,
$tmpdir
.
'/'
.
$image
);
@
unlink
(
$tmpdir
.
'/'
.
$image
);
// Set page rotation default value.
if
(
!
empty
(
$files
[
$i
]))
{
if
(
$resetrotation
)
{
page_editor
::
set_page_rotation
(
$grade
->
id
,
$i
,
false
,
$files
[
$i
]
->
get_pathnamehash
());
}
}
}
$pdf
->
Close
();
// PDF loaded and never saved/outputted needs to be closed.
...
...
@@ -471,7 +494,7 @@ EOD;
$grade
=
$assignment
->
get_user_grade
(
$userid
,
true
,
$attemptnumber
);
$contextid
=
$assignment
->
get_context
()
->
id
;
$component
=
self
::
PLUGIN_NAME
;
$component
=
self
::
COMPONENT
;
$itemid
=
$grade
->
id
;
$filepath
=
'/'
;
$filearea
=
self
::
PAGE_IMAGE_FILEAREA
;
...
...
@@ -492,6 +515,7 @@ EOD;
$files
=
$fs
->
get_directory_files
(
$contextid
,
$component
,
$filearea
,
$itemid
,
$filepath
);
$pages
=
array
();
$resetrotation
=
false
;
if
(
!
empty
(
$files
))
{
$first
=
reset
(
$files
);
$pagemodified
=
$first
->
get_timemodified
();
...
...
@@ -512,6 +536,7 @@ EOD;
$fs
->
delete_area_files
(
$contextid
,
$component
,
$filearea
,
$itemid
);
page_editor
::
delete_draft_content
(
$itemid
);
$files
=
array
();
$resetrotation
=
true
;
}
else
{
// Need to reorder the files following their name.
...
...
@@ -521,7 +546,7 @@ EOD;
preg_match
(
'/page([\d]+)\./'
,
$file
->
get_filename
(),
$matches
);
if
(
empty
(
$matches
)
or
!
is_numeric
(
$matches
[
1
]))
{
throw
new
\
coding_exception
(
"'"
.
$file
->
get_filename
()
.
"' file hasn't the expected format filename: image_pageXXXX.png."
);
.
"' file hasn't the expected format filename: image_pageXXXX.png."
);
}
$pagenumber
=
(
int
)
$matches
[
1
];
...
...
@@ -538,7 +563,7 @@ EOD;
// whenever we are requesting the readonly version.
throw
new
\
moodle_exception
(
'Could not find readonly pages for grade '
.
$grade
->
id
);
}
$pages
=
self
::
generate_page_images_for_attempt
(
$assignment
,
$userid
,
$attemptnumber
);
$pages
=
self
::
generate_page_images_for_attempt
(
$assignment
,
$userid
,
$attemptnumber
,
$resetrotation
);
}
return
$pages
;
...
...
@@ -621,7 +646,7 @@ EOD;
$combined
=
$tmpdir
.
'/'
.
self
::
COMBINED_PDF_FILENAME
;
$file
->
copy_content_to
(
$combined
);
// Copy the file.
$pdf
=
new
pdf
();
$pdf
=
new
dom
pdf
();
$pagecount
=
$pdf
->
set_pdf
(
$combined
);
$grade
=
$assignment
->
get_user_grade
(
$userid
,
true
,
$attemptnumber
);
...
...
@@ -640,7 +665,7 @@ EOD;
$record
=
new
\
stdClass
();
$record
->
contextid
=
$assignment
->
get_context
()
->
id
;
$record
->
component
=
self
::
PLUGIN_NAME
;
$record
->
component
=
self
::
COMPONENT
;
$record
->
filearea
=
self
::
FINAL_PDF_FILEAREA
;
$record
->
itemid
=
$grade
->
id
;
$record
->
filepath
=
'/'
;
...
...
@@ -672,9 +697,23 @@ EOD;
protected
static
function
addAnnotationstoPDF
(
$pdf
,
$pagecount
,
$gradeid
)
{
$annotation_index
=
[];
$compteur
=
1
;
$fs
=
get_file_storage
();
for
(
$i
=
0
;
$i
<
$pagecount
;
$i
++
)
{
$pdf
->
copy_page
();
$pagerotation
=
page_editor
::
get_page_rotation
(
$gradeid
,
$i
);
$pagemargin
=
$pdf
->
getBreakMargin
();
$autopagebreak
=
$pdf
->
getAutoPageBreak
();
if
(
empty
(
$pagerotation
)
||
!
$pagerotation
->
isrotated
)
{
$pdf
->
copy_page
();
}
else
{
$rotatedimagefile
=
$fs
->
get_file_by_hash
(
$pagerotation
->
pathnamehash
);
if
(
empty
(
$rotatedimagefile
))
{
$pdf
->
copy_page
();
}
else
{
$pdf
->
add_image_page
(
$rotatedimagefile
);
}
}
$annotations
=
page_editor
::
get_annotations
(
$gradeid
,
$i
,
false
);
foreach
(
$annotations
as
$annotation
)
{
...
...
@@ -685,6 +724,8 @@ EOD;
$annotation_index
[
$annotation
->
id
]
=
$compteur
;
$compteur
++
;
}
$pdf
->
SetAutoPageBreak
(
$autopagebreak
,
$pagemargin
);
$pdf
->
setPageMark
();
}
//add feedback by annotation
...
...
@@ -757,7 +798,7 @@ EOD;
$fs
=
get_file_storage
();
$assignment
=
self
::
get_assignment_from_param
(
$assignment
);
$contextid
=
$assignment
->
get_context
()
->
id
;
$component
=
self
::
PLUGIN_NAME
;
$component
=
self
::
COMPONENT
;
$itemid
=
$grade
->
id
;
// Get all the pages.
...
...
@@ -794,7 +835,7 @@ EOD;
$grade
=
$assignment
->
get_user_grade
(
$userid
,
true
,
$attemptnumber
);
$contextid
=
$assignment
->
get_context
()
->
id
;
$component
=
self
::
PLUGIN_NAME
;
$component
=
self
::
COMPONENT
;
$filearea
=
self
::
FINAL_PDF_FILEAREA
;
$itemid
=
$grade
->
id
;
$filepath
=
'/'
;
...
...
@@ -828,7 +869,7 @@ EOD;
$grade
=
$assignment
->
get_user_grade
(
$userid
,
true
,
$attemptnumber
);
$contextid
=
$assignment
->
get_context
()
->
id
;
$component
=
self
::
PLUGIN_NAME
;
$component
=
self
::
COMPONENT
;
$filearea
=
self
::
FINAL_PDF_FILEAREA
;
$itemid
=
$grade
->
id
;
...
...
@@ -836,4 +877,130 @@ EOD;
return
$fs
->
delete_area_files
(
$contextid
,
$component
,
$filearea
,
$itemid
);
}
/**
* Get All files in a File area
* @param int|\assign $assignment Assignment
* @param int $userid User ID
* @param int $attemptnumber Attempt Number
* @param string $filearea File Area
* @param string $filepath File Path
* @return array
*/
private
static
function
get_files
(
$assignment
,
$userid
,
$attemptnumber
,
$filearea
,
$filepath
=
'/'
)
{
$grade
=
$assignment
->
get_user_grade
(
$userid
,
true
,
$attemptnumber
);
$itemid
=
$grade
->
id
;
$contextid
=
$assignment
->
get_context
()
->
id
;
$component
=
self
::
COMPONENT
;
$fs
=
get_file_storage
();
$files
=
$fs
->
get_directory_files
(
$contextid
,
$component
,
$filearea
,
$itemid
,
$filepath
);
return
$files
;
}
/**
* Save file.
* @param int|\assign $assignment Assignment
* @param int $userid User ID
* @param int $attemptnumber Attempt Number
* @param string $filearea File Area
* @param string $newfilepath File Path
* @param string $storedfilepath stored file path
* @return \stored_file
* @throws \file_exception
* @throws \stored_file_creation_exception
*/
private
static
function
save_file
(
$assignment
,
$userid
,
$attemptnumber
,
$filearea
,
$newfilepath
,
$storedfilepath
=
'/'
)
{
$grade
=
$assignment
->
get_user_grade
(
$userid
,
true
,
$attemptnumber
);
$itemid
=
$grade
->
id
;
$contextid
=
$assignment
->
get_context
()
->
id
;
$record
=
new
\
stdClass
();
$record
->
contextid
=
$contextid
;
$record
->
component
=
self
::
COMPONENT
;
$record
->
filearea
=
$filearea
;
$record
->
itemid
=
$itemid
;
$record
->
filepath
=
$storedfilepath
;
$record
->
filename
=
basename
(
$newfilepath
);
$fs
=
get_file_storage
();