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
6955a2fb
Commit
6955a2fb
authored
May 16, 2017
by
M. Chardon
Browse files
adaptation moodle3.3 avec mise à jour d'editpdf v201705
parent
d9ee9007
Changes
44
Expand all
Hide whitespace changes
Inline
Side-by-side
ajax.php
View file @
6955a2fb
...
...
@@ -23,8 +23,8 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
use
\
assignfeedback_editpdfplus\document_services
;
use
\
assignfeedback_editpdfplus\combined_document
;
use
\
assignfeedback_editpdfplus\page_editor
;
use
\
assignfeedback_editpdfplus\comments_quick_list
;
define
(
'AJAX_SCRIPT'
,
true
);
...
...
@@ -50,7 +50,7 @@ if (!$assignment->can_view_submission($userid)) {
print_error
(
'nopermission'
);
}
if
(
$action
==
'
loadallpage
s'
)
{
if
(
$action
==
=
'
pollconversion
s'
)
{
$draft
=
true
;
if
(
!
has_capability
(
'mod/assign:grade'
,
$context
))
{
$draft
=
false
;
...
...
@@ -58,50 +58,79 @@ if ($action == 'loadallpages') {
require_capability
(
'mod/assign:submit'
,
$context
);
}
// Whoever is viewing the readonly version should not use the drafts, but the actual annotations.
if
(
$readonly
)
{
// Whoever is viewing the readonly version should not use the drafts, but the actual annotations.
$draft
=
false
;
}
$pages
=
document_services
::
get_page_images_for_attempt
(
$assignment
,
$userid
,
$attemptnumber
,
$readonly
);
$response
=
new
stdClass
();
$response
->
pagecount
=
count
(
$pages
);
$response
->
pages
=
array
();
$grade
=
$assignment
->
get_user_grade
(
$userid
,
true
);
// The readonly files are stored in a different file area.
$filearea
=
document_services
::
PAGE_IMAGE_FILEAREA
;
if
(
$readonly
)
{
$filearea
=
document_services
::
PAGE_IMAGE_READONLY_FILEAREA
;
}
$response
=
(
object
)
[
'status'
=>
-
1
,
'filecount'
=>
0
,
'pagecount'
=>
0
,
'pageready'
=>
0
,
'pages'
=>
[],
];
//$pages = document_services::get_page_images_for_attempt($assignment, $userid, $attemptnumber, $readonly);
//$response = new stdClass();
//$response->pagecount = count($pages);
//$response->pages = array();
$combineddocument
=
document_services
::
get_combined_document_for_attempt
(
$assignment
,
$userid
,
$attemptnumber
);
$response
->
status
=
$combineddocument
->
get_status
();
$response
->
filecount
=
$combineddocument
->
get_document_count
();
if
(
$response
->
status
===
combined_document
::
STATUS_READY
)
{
$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
)
{
$pages
=
document_services
::
get_page_images_for_attempt
(
$assignment
,
$userid
,
$attemptnumber
,
$readonly
);
$response
->
pagecount
=
$combineddocument
->
get_page_count
();
//$grade = $assignment->get_user_grade($userid, true);
$grade
=
$assignment
->
get_user_grade
(
$userid
,
true
,
$attemptnumber
);
// The readonly files are stored in a different file area.
$filearea
=
document_services
::
PAGE_IMAGE_FILEAREA
;
if
(
$readonly
)
{
$filearea
=
document_services
::
PAGE_IMAGE_READONLY_FILEAREA
;
}
foreach
(
$pages
as
$id
=>
$pagefile
)
{
$index
=
count
(
$response
->
pages
);
$page
=
new
stdClass
();
$comments
=
page_editor
::
get_comments
(
$grade
->
id
,
$index
,
$draft
);
$page
->
url
=
moodle_url
::
make_pluginfile_url
(
$context
->
id
,
'assignfeedback_editpdfplus'
,
$filearea
,
$grade
->
id
,
'/'
,
$pagefile
->
get_filename
())
->
out
();
$page
->
comments
=
$comments
;
if
(
$imageinfo
=
$pagefile
->
get_imageinfo
())
{
$page
->
width
=
$imageinfo
[
'width'
];
$page
->
height
=
$imageinfo
[
'height'
];
}
else
{
$page
->
width
=
0
;
$page
->
height
=
0
;
foreach
(
$pages
as
$id
=>
$pagefile
)
{
$index
=
count
(
$response
->
pages
);
$page
=
new
stdClass
();
//$comments = page_editor::get_comments($grade->id, $index, $draft);
$page
->
url
=
moodle_url
::
make_pluginfile_url
(
$context
->
id
,
'assignfeedback_editpdfplus'
,
$filearea
,
$grade
->
id
,
'/'
,
$pagefile
->
get_filename
())
->
out
();
//$page->comments = $comments;
if
(
$imageinfo
=
$pagefile
->
get_imageinfo
())
{
$page
->
width
=
$imageinfo
[
'width'
];
$page
->
height
=
$imageinfo
[
'height'
];
}
else
{
$page
->
width
=
0
;
$page
->
height
=
0
;
}
$annotations
=
page_editor
::
get_annotations
(
$grade
->
id
,
$index
,
$draft
);
$page
->
annotations
=
$annotations
;
//array_push($response->pages, $page);
$response
->
pages
[]
=
$page
;
$component
=
'assignfeedback_editpdfplus'
;
$filearea
=
document_services
::
PAGE_IMAGE_FILEAREA
;
$filepath
=
'/'
;
$fs
=
get_file_storage
();
$files
=
$fs
->
get_directory_files
(
$context
->
id
,
$component
,
$filearea
,
$grade
->
id
,
$filepath
);
$response
->
pageready
=
count
(
$files
);
$tools
=
page_editor
::
get_tools
(
null
);
$typetools
=
page_editor
::
get_typetools
(
null
);
$axis
=
page_editor
::
get_axis
(
null
);
$response
->
tools
=
$tools
;
$response
->
typetools
=
$typetools
;
$response
->
axis
=
$axis
;
}
$annotations
=
page_editor
::
get_annotations
(
$grade
->
id
,
$index
,
$draft
);
$page
->
annotations
=
$annotations
;
array_push
(
$response
->
pages
,
$page
);
}
$tools
=
page_editor
::
get_tools
(
null
);
$typetools
=
page_editor
::
get_typetools
(
null
);
$axis
=
page_editor
::
get_axis
(
null
);
$response
->
tools
=
$tools
;
$response
->
typetools
=
$typetools
;
$response
->
axis
=
$axis
;
echo
json_encode
(
$response
);
die
();
}
else
if
(
$action
==
'savepage'
)
{
...
...
@@ -116,10 +145,10 @@ if ($action == 'loadallpages') {
$page
=
json_decode
(
$pagejson
);
$index
=
required_param
(
'index'
,
PARAM_INT
);
$added
=
page_editor
::
set_comments
(
$grade
->
id
,
$index
,
$page
->
comments
);
if
(
$added
!=
count
(
$page
->
comments
))
{
array_push
(
$response
->
errors
,
get_string
(
'couldnotsavepage'
,
'assignfeedback_editpdfplus'
,
$index
+
1
));
}
/*
$added = page_editor::set_comments($grade->id, $index, $page->comments);
if ($added != count($page->comments)) {
array_push($response->errors, get_string('couldnotsavepage', 'assignfeedback_editpdfplus', $index + 1));
} */
$added
=
page_editor
::
set_annotations
(
$grade
->
id
,
$index
,
$page
->
annotations
);
if
(
$added
!=
count
(
$page
->
annotations
))
{
array_push
(
$response
->
errors
,
get_string
(
'couldnotsavepage'
,
'assignfeedback_editpdfplus'
,
$index
+
1
));
...
...
@@ -127,6 +156,7 @@ if ($action == 'loadallpages') {
echo
json_encode
(
$response
);
die
();
}
else
if
(
$action
==
'generatepdf'
)
{
$refresh
=
optional_param
(
'refresh'
,
false
,
PARAM_BOOL
);
if
(
!
$refresh
)
{
...
...
@@ -135,7 +165,7 @@ if ($action == 'loadallpages') {
require_capability
(
'mod/assign:submit'
,
$context
);
}
$response
=
new
stdClass
();
$grade
=
$assignment
->
get_user_grade
(
$userid
,
true
);
$grade
=
$assignment
->
get_user_grade
(
$userid
,
true
,
$attemptnumber
);
$file
=
document_services
::
generate_feedback_document
(
$assignment
,
$userid
,
$attemptnumber
,
$refresh
);
$response
->
url
=
''
;
...
...
@@ -155,7 +185,7 @@ if ($action == 'loadallpages') {
$formatparams
=
array
(
'context'
=>
$contextb
->
get_course_context
());
$body
=
format_string
(
$course
->
shortname
,
true
,
$formatparams
)
.
' -> '
.
$modulename
.
$modulename
.
' -> '
.
format_string
(
$assignmentname
,
true
,
$formatparams
)
.
"
\n
"
.
"
\n
---------------------------------------------------------------------
\n
"
...
...
@@ -163,17 +193,17 @@ if ($action == 'loadallpages') {
.
$response
->
url
.
"
\n\n
Ceci est un mail automatique."
;
$bodyhtml
=
'<p><font face="sans-serif">'
.
'<a href="'
.
$CFG
->
wwwroot
.
'/course/view.php?id='
.
$course
->
id
.
'">'
.
format_string
(
$course
->
shortname
,
true
,
$formatparams
)
.
'</a> ->'
.
'<a href="'
.
$CFG
->
wwwroot
.
'/mod/assign/index.php?id='
.
$course
->
id
.
'">'
.
$modulename
.
'</a> ->'
.
'<a href="'
.
$CFG
->
wwwroot
.
'/mod/assign/view.php?id='
.
$coursemodule
->
id
.
'">'
.
format_string
(
$assignmentname
,
true
,
$formatparams
)
.
'</a></font></p>'
.
'<hr /><font face="sans-serif">'
.
"<b>Information Moodle</b><br/>"
.
'<a href="'
.
$CFG
->
wwwroot
.
'/course/view.php?id='
.
$course
->
id
.
'">'
.
format_string
(
$course
->
shortname
,
true
,
$formatparams
)
.
'</a> ->'
.
'<a href="'
.
$CFG
->
wwwroot
.
'/mod/assign/index.php?id='
.
$course
->
id
.
'">'
.
$modulename
.
'</a> ->'
.
'<a href="'
.
$CFG
->
wwwroot
.
'/mod/assign/view.php?id='
.
$coursemodule
->
id
.
'">'
.
format_string
(
$assignmentname
,
true
,
$formatparams
)
.
'</a></font></p>'
.
'<hr /><font face="sans-serif">'
.
"<b>Information Moodle</b><br/>"
.
"<p>La correction du devoir a été mise à jour. Vous pouvez accéder au document en suivant ce <a href='"
.
$response
->
url
.
"'>lien</a></p>"
...
...
@@ -185,43 +215,43 @@ if ($action == 'loadallpages') {
echo
json_encode
(
$response
);
die
();
}
else
if
(
$action
==
'loadquicklist'
)
{
require_capability
(
'mod/assign:grade'
,
$context
);
}
/*
else if ($action == 'loadquicklist') {
require_capability('mod/assign:grade', $context);
$result
=
comments_quick_list
::
get_comments
();
$result = comments_quick_list::get_comments();
echo
json_encode
(
$result
);
die
();
}
else
if
(
$action
==
'addtoquicklist'
)
{
require_capability
(
'mod/assign:grade'
,
$context
);
echo json_encode($result);
die();
} *//*
else if ($action == 'addtoquicklist') {
require_capability('mod/assign:grade', $context);
$comment
=
required_param
(
'commenttext'
,
PARAM_RAW
);
$width
=
required_param
(
'width'
,
PARAM_INT
);
$colour
=
required_param
(
'colour'
,
PARAM_ALPHA
);
$comment = required_param('commenttext', PARAM_RAW);
$width = required_param('width', PARAM_INT);
$colour = required_param('colour', PARAM_ALPHA);
$result
=
comments_quick_list
::
add_comment
(
$comment
,
$width
,
$colour
);
$result = comments_quick_list::add_comment($comment, $width, $colour);
echo
json_encode
(
$result
);
die
();
}
else
if
(
$action
==
'revertchanges'
)
{
echo json_encode($result);
die();
} */
else
if
(
$action
==
'revertchanges'
)
{
require_capability
(
'mod/assign:grade'
,
$context
);
$grade
=
$assignment
->
get_user_grade
(
$userid
,
true
);
$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
);
}
/*
else if ($action == 'removefromquicklist') {
require_capability('mod/assign:grade', $context);
$commentid
=
required_param
(
'commentid'
,
PARAM_INT
);
$commentid = required_param('commentid', PARAM_INT);
$result
=
comments_quick_list
::
remove_comment
(
$commentid
);
$result = comments_quick_list::remove_comment($commentid);
echo
json_encode
(
$result
);
die
();
}
else
if
(
$action
==
'deletefeedbackdocument'
)
{
echo json_encode($result);
die();
} */
else
if
(
$action
==
'deletefeedbackdocument'
)
{
require_capability
(
'mod/assign:grade'
,
$context
);
$grade
=
$assignment
->
get_user_grade
(
$userid
,
true
);
...
...
classes/combined_document.php
0 → 100644
View file @
6955a2fb
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This file contains the combined document class for the assignfeedback_editpdfplus plugin.
*
* @package assignfeedback_editpdfplus
* @copyright 2017 Andrew Nicols <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace
assignfeedback_editpdfplus
;
defined
(
'MOODLE_INTERNAL'
)
||
die
();
/**
* The combined_document class for the assignfeedback_editpdfplus plugin.
*
* @copyright 2017 Andrew Nicols <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class
combined_document
{
/**
* Status value representing a conversion waiting to start.
*/
const
STATUS_PENDING_INPUT
=
0
;
/**
* Status value representing all documents ready to be combined.
*/
const
STATUS_READY
=
1
;
/**
* Status value representing a successful conversion.
*/
const
STATUS_COMPLETE
=
2
;
/**
* Status value representing a permanent error.
*/
const
STATUS_FAILED
=
-
1
;
/**
* The list of files which make this document.
*/
protected
$sourcefiles
=
[];
/**
* The resultant combined file.
*/
protected
$combinedfile
;
/**
* The combination status.
*/
protected
$combinationstatus
=
null
;
/**
* The number of pages in the combined PDF.
*/
protected
$pagecount
=
0
;
/**
* Check the current status of the document combination.
*
* @return int
*/
public
function
get_status
()
{
if
(
$this
->
combinedfile
)
{
// The combined file exists. Report success.
return
self
::
STATUS_COMPLETE
;
}
if
(
empty
(
$this
->
sourcefiles
))
{
// There are no source files to combine.
return
self
::
STATUS_FAILED
;
}
if
(
!
empty
(
$this
->
combinationstatus
))
{
// The combination is in progress and has set a status.
// Return it instead.
return
$this
->
combinationstatus
;
}
$pending
=
false
;
foreach
(
$this
->
sourcefiles
as
$file
)
{
// The combined file has not yet been generated.
// Check the status of each source file.
if
(
is_a
(
$file
,
\
core_files\conversion
::
class
))
{
$status
=
$file
->
get
(
'status'
);
switch
(
$status
)
{
case
\
core_files\conversion
::
STATUS_IN_PROGRESS
:
case
\
core_files\conversion
::
STATUS_PENDING
:
$pending
=
true
;
case
\
core_files\conversion
::
STATUS_FAILED
:
return
self
::
STATUS_FAILED
;
}
}
}
if
(
$pending
)
{
return
self
::
STATUS_PENDING_INPUT
;
}
else
{
return
self
::
STATUS_READY
;
}
}
/**
* Set the completed combined file.
*
* @param stored_file $file The completed document for all files to be combined.
* @return $this
*/
public
function
set_combined_file
(
$file
)
{
$this
->
combinedfile
=
$file
;
return
$this
;
}
/**
* Retrieve the completed combined file.
*
* @return stored_file
*/
public
function
get_combined_file
()
{
return
$this
->
combinedfile
;
}
/**
* Set all source files which are to be combined.
*
* @param stored_file|conversion[] $files The complete list of all source files to be combined.
* @return $this
*/
public
function
set_source_files
(
$files
)
{
$this
->
sourcefiles
=
$files
;
return
$this
;
}
/**
* Add an additional source file to the end of the existing list.
*
* @param stored_file|conversion $file The file to add to the end of the list.
* @return $this
*/
public
function
add_source_file
(
$file
)
{
$this
->
sourcefiles
[]
=
$file
;
return
$this
;
}
/**
* Retrieve the complete list of source files.
*
* @return stored_file|conversion[]
*/
public
function
get_source_files
()
{
return
$this
->
sourcefiles
;
}
/**
* Refresh the files.
*
* This includes polling any pending conversions to see if they are complete.
*
* @return $this
*/
public
function
refresh_files
()
{
$converter
=
new
\
core_files\converter
();
foreach
(
$this
->
sourcefiles
as
$file
)
{
if
(
is_a
(
$file
,
\
core_files\conversion
::
class
))
{
$status
=
$file
->
get
(
'status'
);
switch
(
$status
)
{
case
\
core_files\conversion
::
STATUS_COMPLETE
:
continue
;
break
;
default
:
$converter
->
poll_conversion
(
$conversion
);
}
}
}
return
$this
;
}
/**
* Combine all source files into a single PDF and store it in the
* file_storage API using the supplied contextid and itemid.
*
* @param int $contextid The contextid for the file to be stored under
* @param int $itemid The itemid for the file to be stored under
* @return $this
*/
public
function
combine_files
(
$contextid
,
$itemid
)
{
global
$CFG
;
$currentstatus
=
$this
->
get_status
();
if
(
$currentstatus
===
self
::
STATUS_FAILED
)
{
$this
->
store_empty_document
(
$contextid
,
$itemid
);
return
$this
;
}
else
if
(
$currentstatus
!==
self
::
STATUS_READY
)
{
// The document is either:
// * already combined; or
// * pending input being fully converted; or
// * unable to continue due to an issue with the input documents.
//
// Exit early as we cannot continue.
return
$this
;
}
require_once
(
$CFG
->
libdir
.
'/pdflib.php'
);
$pdf
=
new
pdf
();
$files
=
$this
->
get_source_files
();
$compatiblepdfs
=
[];
foreach
(
$files
as
$file
)
{
// Check that each file is compatible and add it to the list.
// Note: We drop non-compatible files.
$compatiblepdf
=
false
;
if
(
is_a
(
$file
,
\
core_files\conversion
::
class
))
{
$compatiblepdf
=
pdf
::
ensure_pdf_compatible
(
$file
->
get_destfile
());
}
else
{
$compatiblepdf
=
pdf
::
ensure_pdf_compatible
(
$file
);
}
if
(
$compatiblepdf
)
{
$compatiblepdfs
[]
=
$compatiblepdf
;
}
}
$tmpdir
=
make_request_directory
();
$tmpfile
=
$tmpdir
.
'/'
.
document_services
::
COMBINED_PDF_FILENAME
;
try
{
$pagecount
=
$pdf
->
combine_pdfs
(
$compatiblepdfs
,
$tmpfile
);
$pdf
->
Close
();
}
catch
(
\
Exception
$e
)
{
// Unable to combine the PDF.
debugging
(
'TCPDF could not process the pdf files:'
.
$e
->
getMessage
(),
DEBUG_DEVELOPER
);
$pdf
->
Close
();
return
$this
->
mark_combination_failed
();
}
// Verify the PDF.
$verifypdf
=
new
pdf
();
$verifypagecount
=
$verifypdf
->
load_pdf
(
$tmpfile
);
$verifypdf
->
Close
();
if
(
$verifypagecount
<=
0
)
{
// No pages were found in the combined PDF.
return
$this
->
mark_combination_failed
();
}
// Store the newly created file as a stored_file.
$this
->
store_combined_file
(
$tmpfile
,
$contextid
,
$itemid
);
// Note the verified page count.
$this
->
pagecount
=
$verifypagecount
;
return
$this
;
}
/**
* Mark the combination attempt as having encountered a permanent failure.
*
* @return $this
*/
protected
function
mark_combination_failed
()
{
$this
->
combinationstatus
=
self
::
STATUS_FAILED
;
return
$this
;
}
/**
* Store the combined file in the file_storage API.
*
* @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
* @return $this
*/
protected
function
store_combined_file
(
$tmpfile
,
$contextid
,
$itemid
)
{
// Store the file.
$record
=
$this
->
get_stored_file_record
(
$contextid
,
$itemid
);
$fs
=
get_file_storage
();
// Delete existing files first.
$fs
->
delete_area_files
(
$record
->
contextid
,
$record
->
component
,
$record
->
filearea
,
$record
->
itemid
);
// This was a combined pdf.
$file
=
$fs
->
create_file_from_pathname
(
$record
,
$tmpfile
);
$this
->
set_combined_file
(
$file
);
return
$this
;
}
/**
* Store the empty document file in the file_storage API.
*
* @param int $contextid The contextid for the file to be stored under
* @param int $itemid The itemid for the file to be stored under
* @return $this
*/
protected
function
store_empty_document
(
$contextid
,
$itemid
)
{
// Store the file.
$record
=
$this
->
get_stored_file_record
(
$contextid
,
$itemid
);
$fs
=
get_file_storage
();
// Delete existing files first.
$fs
->
delete_area_files
(
$record
->
contextid
,
$record
->
component
,
$record
->
filearea
,
$record
->
itemid
);
$file
=
$fs
->
create_file_from_string
(
$record
,
base64_decode
(
document_services
::
BLANK_PDF_BASE64
));
$this
->
pagecount
=
1
;
$this
->
set_combined_file
(
$file
);
return
$this
;
}
/**
* Get the total number of pages in the combined document.
*
* If there are no pages, or it is not yet possible to count them a
* value of 0 is returned.
*
* @return int
*/
public
function
get_page_count
()
{
if
(
$this
->
pagecount
)
{
return
$this
->
pagecount
;
}
if
(
$this
->
get_status
()
===
self
::
STATUS_FAILED
)
{
// The empty document will be returned.