Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
M
Moodle Qtype Moopt
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
elc
Moodle Qtype Moopt
Commits
fb6fa2c5
Commit
fb6fa2c5
authored
9 months ago
by
Alexander Loewe
Browse files
Options
Downloads
Patches
Plain Diff
Added support to import and export textarea specific options and taskfiles
parent
a18436ba
No related branches found
No related tags found
No related merge requests found
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
externallib.php
+3
-3
3 additions, 3 deletions
externallib.php
locallib.php
+143
-67
143 additions, 67 deletions
locallib.php
questiontype.php
+147
-10
147 additions, 10 deletions
questiontype.php
with
293 additions
and
80 deletions
externallib.php
+
3
−
3
View file @
fb6fa2c5
...
@@ -82,7 +82,7 @@ class qtype_moopt_external extends external_api {
...
@@ -82,7 +82,7 @@ class qtype_moopt_external extends external_api {
$usercontext
=
context_user
::
instance
(
$USER
->
id
);
$usercontext
=
context_user
::
instance
(
$USER
->
id
);
self
::
validate_context
(
$usercontext
);
self
::
validate_context
(
$usercontext
);
$unzipinfo
=
unzip_task_file_in_
draft
_area
(
$draftid
,
$usercontext
);
$unzipinfo
=
unzip_task_file_in_
file
_area
(
$usercontext
,
'user'
,
'draft'
,
$draftid
);
if
(
$unzipinfo
==
null
)
{
if
(
$unzipinfo
==
null
)
{
return
[
'error'
=>
'Error extracting zip file'
];
return
[
'error'
=>
'Error extracting zip file'
];
}
else
if
(
isset
(
$unzipinfo
[
'error'
]))
{
}
else
if
(
isset
(
$unzipinfo
[
'error'
]))
{
...
@@ -92,7 +92,7 @@ class qtype_moopt_external extends external_api {
...
@@ -92,7 +92,7 @@ class qtype_moopt_external extends external_api {
$taskzipfilename
=
$unzipinfo
[
'zip'
]
??
null
;
$taskzipfilename
=
$unzipinfo
[
'zip'
]
??
null
;
$keepfilename
=
$taskzipfilename
!=
null
?
$taskzipfilename
:
$taskxmlfilename
;
$keepfilename
=
$taskzipfilename
!=
null
?
$taskzipfilename
:
$taskxmlfilename
;
$doc
=
create_domdocument_from_task_xml
(
$usercontext
,
$draftid
,
$taskxmlfilename
,
$taskzipfilename
);
$doc
=
create_domdocument_from_task_xml
(
$usercontext
,
'user'
,
'draft'
,
$draftid
,
$taskxmlfilename
,
$taskzipfilename
);
$namespace
=
detect_proforma_namespace
(
$doc
);
$namespace
=
detect_proforma_namespace
(
$doc
);
$returnval
=
array
();
$returnval
=
array
();
...
@@ -290,7 +290,7 @@ class qtype_moopt_external extends external_api {
...
@@ -290,7 +290,7 @@ class qtype_moopt_external extends external_api {
}
}
// Do a little bit of cleanup and remove everything from the file area we extracted.
// Do a little bit of cleanup and remove everything from the file area we extracted.
remove_all_files_from_
draft
_area
(
$draftid
,
$usercontext
,
$keepfilename
);
remove_all_files_from_
file
_area
(
$usercontext
,
'user'
,
'draft'
,
$draftid
,
$keepfilename
);
return
$returnval
;
return
$returnval
;
}
}
...
...
This diff is collapsed.
Click to expand it.
locallib.php
+
143
−
67
View file @
fb6fa2c5
...
@@ -118,41 +118,43 @@ use qtype_moopt\exceptions\resource_not_found_exception;
...
@@ -118,41 +118,43 @@ use qtype_moopt\exceptions\resource_not_found_exception;
use
qtype_moopt\utility\communicator\communicator_factory
;
use
qtype_moopt\utility\communicator\communicator_factory
;
use
qtype_moopt\utility\proforma_xml\separate_feedback_handler
;
use
qtype_moopt\utility\proforma_xml\separate_feedback_handler
;
/*
/*
*
* Unzips the task zip file in the given
draft
area into the area
* Unzips the task zip file in the given
file
area into the area
* moodle doesn't display thrown exceptions, so we handle them as array with key 'error' in calling function
* moodle doesn't display thrown exceptions, so we handle them as array with key 'error' in calling function
*
*
* @param type $draftareaid
* @param type $context
* @param type $usercontext
* @param type $component
* @param type $filearea
* @param type $fileareaid
* @return array the name of the task zip file and the task xml file.
* @return array the name of the task zip file and the task xml file.
* [
* [
* 'zip' => (string) the name of the zip file, if any (the key 'zip' is optional)
* 'zip' => (string) the name of the zip file, if any (the key 'zip' is optional)
* 'xml' => (string) the name of the xml file (mandatory)
* 'xml' => (string) the name of the xml file (mandatory)
* ]
* ]
* Returns false, if there is no file in the given
draft
area.
* Returns false, if there is no file in the given
file
area.
*/
*/
function
unzip_task_file_in_
draft
_area
(
$
draft
area
id
,
$
usercontext
)
{
function
unzip_task_file_in_
file
_area
(
$
context
,
$component
,
$file
area
,
$
fileareaid
)
{
global
$USER
;
global
$USER
;
$fs
=
get_file_storage
();
$fs
=
get_file_storage
();
// Check if there is only the file we want.
// Check if there is only the file we want.
$area
=
file_get_
draft
_area_info
(
$
draft
areaid
,
"/"
);
$area
=
file_get_
file
_area_info
(
$
context
->
id
,
$component
,
$filearea
,
$file
areaid
,
"/"
);
if
(
$area
[
'filecount'
]
==
0
)
{
if
(
$area
[
'filecount'
]
==
0
)
{
return
false
;
return
false
;
}
else
if
(
$area
[
'filecount'
]
>
1
||
$area
[
'foldercount'
]
!=
0
)
{
}
else
if
(
$area
[
'filecount'
]
>
1
||
$area
[
'foldercount'
]
!=
0
)
{
$error
=
'Only one file is allowed to be in this
draft
area: A ProFormA-Task as either ZIP or XML file. Check for additional folders as well.'
;
$error
=
'Only one file is allowed to be in this
file
area: A ProFormA-Task as either ZIP or XML file. Check for additional folders as well.'
;
return
array
(
'error'
=>
$error
);
return
array
(
'error'
=>
$error
);
}
}
// Get name of the file.
// Get name of the file.
$files
=
$fs
->
get_area_files
(
$
user
context
->
id
,
'user'
,
'draft'
,
$draft
areaid
);
$files
=
$fs
->
get_area_files
(
$context
->
id
,
$component
,
$filearea
,
$file
areaid
);
// Get_area_files returns an associative array where the keys are some kind of hash value.
// Get_area_files returns an associative array where the keys are some kind of hash value.
$keys
=
array_keys
(
$files
);
$keys
=
array_keys
(
$files
);
// Index 1 because index 0 is the current directory it seems.
// Index 1 because index 0 is the current directory it seems.
$filename
=
$files
[
$keys
[
1
]]
->
get_filename
();
$filename
=
$files
[
$keys
[
1
]]
->
get_filename
();
$file
=
$fs
->
get_file
(
$
user
context
->
id
,
'user'
,
'draft'
,
$draft
areaid
,
"/"
,
$filename
);
$file
=
$fs
->
get_file
(
$context
->
id
,
$component
,
$filearea
,
$file
areaid
,
"/"
,
$filename
);
// Check file type (it's really only checking the file extension but that is good enough here).
// Check file type (it's really only checking the file extension but that is good enough here).
$fileinfo
=
pathinfo
(
$filename
);
$fileinfo
=
pathinfo
(
$filename
);
...
@@ -174,13 +176,13 @@ function unzip_task_file_in_draft_area($draftareaid, $usercontext) {
...
@@ -174,13 +176,13 @@ function unzip_task_file_in_draft_area($draftareaid, $usercontext) {
$zipper
=
get_file_packer
(
'application/zip'
);
$zipper
=
get_file_packer
(
'application/zip'
);
// Find unused name for directory to extract the archive.
// Find unused name for directory to extract the archive.
$temppath
=
$fs
->
get_unused_dirname
(
$
user
context
->
id
,
'user'
,
'draft'
,
$draft
areaid
,
"/"
.
pathinfo
(
$zipfilename
,
$temppath
=
$fs
->
get_unused_dirname
(
$context
->
id
,
$component
,
$filearea
,
$file
areaid
,
"/"
.
pathinfo
(
$zipfilename
,
PATHINFO_FILENAME
)
.
'/'
);
PATHINFO_FILENAME
)
.
'/'
);
$donotremovedirs
=
array
();
$donotremovedirs
=
array
();
$doremovedirs
=
array
(
$temppath
);
$doremovedirs
=
array
(
$temppath
);
// Extract archive and move all files from $temppath to $filepath.
// Extract archive and move all files from $temppath to $filepath.
if
(
$file
->
extract_to_storage
(
$zipper
,
$
user
context
->
id
,
'user'
,
'draft'
,
$draft
areaid
,
$temppath
,
$USER
->
id
))
{
if
(
$file
->
extract_to_storage
(
$zipper
,
$context
->
id
,
$component
,
$filearea
,
$file
areaid
,
$temppath
,
$USER
->
id
))
{
$extractedfiles
=
$fs
->
get_directory_files
(
$
user
context
->
id
,
'user'
,
'draft'
,
$draft
areaid
,
$temppath
,
true
);
$extractedfiles
=
$fs
->
get_directory_files
(
$context
->
id
,
$component
,
$filearea
,
$file
areaid
,
$temppath
,
true
);
$xtemppath
=
preg_quote
(
$temppath
,
'|'
);
$xtemppath
=
preg_quote
(
$temppath
,
'|'
);
foreach
(
$extractedfiles
as
$exfile
)
{
foreach
(
$extractedfiles
as
$exfile
)
{
$realpath
=
preg_replace
(
'|^'
.
$xtemppath
.
'|'
,
'/'
,
$exfile
->
get_filepath
());
$realpath
=
preg_replace
(
'|^'
.
$xtemppath
.
'|'
,
'/'
,
$exfile
->
get_filepath
());
...
@@ -188,13 +190,18 @@ function unzip_task_file_in_draft_area($draftareaid, $usercontext) {
...
@@ -188,13 +190,18 @@ function unzip_task_file_in_draft_area($draftareaid, $usercontext) {
// Set the source to the extracted file to indicate that it came from archive.
// Set the source to the extracted file to indicate that it came from archive.
$exfile
->
set_source
(
serialize
((
object
)
array
(
'source'
=>
'/'
)));
$exfile
->
set_source
(
serialize
((
object
)
array
(
'source'
=>
'/'
)));
}
}
if
(
!
$fs
->
file_exists
(
$
user
context
->
id
,
'user'
,
'draft'
,
$draft
areaid
,
$realpath
,
$exfile
->
get_filename
()))
{
if
(
!
$fs
->
file_exists
(
$context
->
id
,
$component
,
$filearea
,
$file
areaid
,
$realpath
,
$exfile
->
get_filename
()))
{
// File or directory did not exist, just move it.
// File or directory did not exist, just move it.
$exfile
->
rename
(
$realpath
,
$exfile
->
get_filename
());
$exfile
->
rename
(
$realpath
,
$exfile
->
get_filename
());
}
else
if
(
!
$exfile
->
is_directory
())
{
}
else
if
(
!
$exfile
->
is_directory
())
{
// File already existed, overwrite it.
// File already existed, overwrite it.
repository
::
overwrite_existing_draftfile
(
$draftareaid
,
$realpath
,
$exfile
->
get_filename
(),
$exfile
->
get_filepath
(),
if
(
$file
=
$fs
->
get_file
(
$context
->
id
,
$component
,
$filearea
,
$fileareaid
,
$realpath
,
$exfile
->
get_filename
()))
{
$exfile
->
get_filename
());
if
(
$tempfile
=
$fs
->
get_file
(
$context
->
id
,
$component
,
$filearea
,
$fileareaid
,
$exfile
->
get_filepath
(),
$exfile
->
get_filename
()))
{
$file
->
delete
();
$fs
->
create_file_from_storedfile
(
array
(
'filepath'
=>
$exfile
->
get_filepath
(),
'filename'
=>
$exfile
->
get_filename
()),
$tempfile
);
$tempfile
->
delete
();
}
}
}
else
{
}
else
{
// Directory already existed, remove temporary dir but make sure we don't remove the existing dir.
// Directory already existed, remove temporary dir but make sure we don't remove the existing dir.
$doremovedirs
[]
=
$exfile
->
get_filepath
();
$doremovedirs
[]
=
$exfile
->
get_filepath
();
...
@@ -209,7 +216,7 @@ function unzip_task_file_in_draft_area($draftareaid, $usercontext) {
...
@@ -209,7 +216,7 @@ function unzip_task_file_in_draft_area($draftareaid, $usercontext) {
}
}
// Remove remaining temporary directories.
// Remove remaining temporary directories.
foreach
(
array_diff
(
$doremovedirs
,
$donotremovedirs
)
as
$filepath
)
{
foreach
(
array_diff
(
$doremovedirs
,
$donotremovedirs
)
as
$filepath
)
{
$file
=
$fs
->
get_file
(
$
user
context
->
id
,
'user'
,
'draft'
,
$draft
areaid
,
$filepath
,
'.'
);
$file
=
$fs
->
get_file
(
$context
->
id
,
$component
,
$filearea
,
$file
areaid
,
$filepath
,
'.'
);
if
(
$file
)
{
if
(
$file
)
{
$file
->
delete
();
$file
->
delete
();
}
}
...
@@ -224,16 +231,18 @@ function unzip_task_file_in_draft_area($draftareaid, $usercontext) {
...
@@ -224,16 +231,18 @@ function unzip_task_file_in_draft_area($draftareaid, $usercontext) {
}
}
/**
/**
* Removes all files and directories from the given
draft
area except a file with the given file name
* Removes all files and directories from the given
file
area except a file with the given file name
*
*
* @param type $draftareaid
* @param type $context
* @param type $user_context
* @param type $component
* @param type $excluded_file_name
* @param type $filearea
* @param type $fileareaid
* @param type $excludedfilename
*/
*/
function
remove_all_files_from_
draft
_area
(
$
draft
area
id
,
$
usercontext
,
$excludedfilename
)
function
remove_all_files_from_
file
_area
(
$
context
,
$component
,
$file
area
,
$
fileareaid
,
$excludedfilename
)
{
{
$fs
=
get_file_storage
();
$fs
=
get_file_storage
();
$files
=
$fs
->
get_area_files
(
$
user
context
->
id
,
'user'
,
'draft'
,
$draft
areaid
);
$files
=
$fs
->
get_area_files
(
$context
->
id
,
$component
,
$filearea
,
$file
areaid
);
foreach
(
$files
as
$fi
)
{
foreach
(
$files
as
$fi
)
{
if
((
$fi
->
is_directory
()
&&
$fi
->
get_filepath
()
!=
'/'
)
||
(
$fi
->
get_filename
()
!=
$excludedfilename
&&
if
((
$fi
->
is_directory
()
&&
$fi
->
get_filepath
()
!=
'/'
)
||
(
$fi
->
get_filename
()
!=
$excludedfilename
&&
$fi
->
get_filename
()
!=
'.'
))
{
$fi
->
get_filename
()
!=
'.'
))
{
...
@@ -245,26 +254,28 @@ function remove_all_files_from_draft_area($draftareaid, $usercontext, $excludedf
...
@@ -245,26 +254,28 @@ function remove_all_files_from_draft_area($draftareaid, $usercontext, $excludedf
/**
/**
* Creates a DOMDocument object from the task.xml file in the given file area and returns it.
* Creates a DOMDocument object from the task.xml file in the given file area and returns it.
*
*
* @param type $user_context
* @param type $context
* @param type $draftareaid
* @param type $component
* @param type $filearea
* @param type $fileareaid
* @param type $xmlfilename
* @param type $xmlfilename
* @param type $zipfilename (optional, only if user uploaded a zip)
* @param type $zipfilename (optional, only if user uploaded a zip)
* @return \DOMDocument
* @return \DOMDocument
* @throws invalid_parameter_exception
* @throws invalid_parameter_exception
*/
*/
function
create_domdocument_from_task_xml
(
$
user
context
,
$
draft
areaid
,
$xmlfilename
,
$zipfilename
)
function
create_domdocument_from_task_xml
(
$context
,
$
component
,
$filearea
,
$file
areaid
,
$xmlfilename
,
$zipfilename
)
{
{
$fs
=
get_file_storage
();
$fs
=
get_file_storage
();
$file
=
$fs
->
get_file
(
$
user
context
->
id
,
'user'
,
'draft'
,
$draft
areaid
,
"/"
,
$xmlfilename
);
$file
=
$fs
->
get_file
(
$context
->
id
,
$component
,
$filearea
,
$file
areaid
,
"/"
,
$xmlfilename
);
if
(
!
$file
)
{
if
(
!
$file
)
{
remove_all_files_from_
draft
_area
(
$
draft
area
id
,
$
usercontext
,
$zipfilename
);
remove_all_files_from_
file
_area
(
$
context
,
$component
,
$file
area
,
$
fileareaid
,
$zipfilename
);
throw
new
invalid_parameter_exception
(
'Supplied zip file doesn\'t contain task.xml file.'
);
throw
new
invalid_parameter_exception
(
'Supplied zip file doesn\'t contain task.xml file.'
);
}
}
$doc
=
new
DOMDocument
();
$doc
=
new
DOMDocument
();
if
(
!
$doc
->
loadXML
(
$file
->
get_content
()))
{
if
(
!
$doc
->
loadXML
(
$file
->
get_content
()))
{
remove_all_files_from_
draft
_area
(
$
draft
area
id
,
$
usercontext
,
$zipfilename
);
remove_all_files_from_
file
_area
(
$
context
,
$component
,
$file
area
,
$
fileareaid
,
$zipfilename
);
throw
new
invalid_parameter_exception
(
'Error parsing the supplied '
.
$xmlfilename
.
' file. See server log for details.'
);
throw
new
invalid_parameter_exception
(
'Error parsing the supplied '
.
$xmlfilename
.
' file. See server log for details.'
);
}
}
...
@@ -287,7 +298,7 @@ function get_text_content_from_file($usercontext, $draftareaid, $keepfilename, $
...
@@ -287,7 +298,7 @@ function get_text_content_from_file($usercontext, $draftareaid, $keepfilename, $
$fs
=
get_file_storage
();
$fs
=
get_file_storage
();
$file
=
$fs
->
get_file
(
$usercontext
->
id
,
'user'
,
'draft'
,
$draftareaid
,
$filepath
,
$filename
);
$file
=
$fs
->
get_file
(
$usercontext
->
id
,
'user'
,
'draft'
,
$draftareaid
,
$filepath
,
$filename
);
if
(
!
$file
)
{
if
(
!
$file
)
{
remove_all_files_from_
draft
_area
(
$
draftareaid
,
$usercontext
,
$keepfilename
);
remove_all_files_from_
file
_area
(
$
usercontext
,
'user'
,
'draft'
,
$draftareaid
,
$keepfilename
);
throw
new
invalid_parameter_exception
(
'Supplied file doesn\'t contain file '
.
$filepath
.
$filename
.
'.'
);
throw
new
invalid_parameter_exception
(
'Supplied file doesn\'t contain file '
.
$filepath
.
$filename
.
'.'
);
}
}
...
@@ -316,7 +327,6 @@ function get_text_content_from_file($usercontext, $draftareaid, $keepfilename, $
...
@@ -316,7 +327,6 @@ function get_text_content_from_file($usercontext, $draftareaid, $keepfilename, $
return
$content
;
return
$content
;
}
}
/**
/**
* Get the stored_file from the file area PROFORMA_TASKXML_FILEAREA, if any.
* Get the stored_file from the file area PROFORMA_TASKXML_FILEAREA, if any.
* @return stored_file|bool the file or false, if not found.
* @return stored_file|bool the file or false, if not found.
...
@@ -334,18 +344,61 @@ function get_task_xml_file_from_filearea($question)
...
@@ -334,18 +344,61 @@ function get_task_xml_file_from_filearea($question)
}
}
/**
* @throws stored_file_creation_exception
* @throws dml_exception
* @throws file_exception
* @throws coding_exception
* @throws invalid_parameter_exception
* @throws Exception
*/
function
save_task_and_according_files
(
$question
)
function
save_task_and_according_files
(
$question
)
{
{
global
$USER
,
$DB
;
global
$USER
,
$DB
;
$fs
=
get_file_storage
();
$context
=
''
;
$component
=
''
;
$filearea
=
''
;
$fileareaid
=
''
;
$filesfordb
=
array
();
if
(
property_exists
(
$question
,
'taskfile'
)
&&
!
is_null
(
$question
->
taskfile
))
{
$context
=
$question
->
taskfile
[
'context'
];
$component
=
$question
->
taskfile
[
'component'
];
$filearea
=
$question
->
taskfile
[
'filearea'
];
$fileareaid
=
$question
->
id
;
$question
->
taskfileinfo
[
'itemid'
]
=
$fileareaid
;
$fileinfo
=
[
'contextid'
=>
$context
->
id
,
'component'
=>
$component
,
'filearea'
=>
$filearea
,
'itemid'
=>
$fileareaid
,
'filepath'
=>
$question
->
taskfile
[
'filepath'
],
'filename'
=>
$question
->
taskfile
[
'filename'
]
];
$fs
->
create_file_from_string
(
$fileinfo
,
$question
->
taskfile
[
'content'
]);
if
(
!
isset
(
$question
->
proformataskfileupload
))
{
$record
=
new
stdClass
();
$record
->
questionid
=
$question
->
id
;
$record
->
fileid
=
$filearea
==
PROFORMA_TASKZIP_FILEAREA
?
'task'
:
'taskxml'
;
$record
->
usedbygrader
=
0
;
$record
->
visibletostudents
=
'no'
;
$record
->
usagebylms
=
'download'
;
$record
->
filepath
=
'/'
;
$record
->
filename
=
$fileinfo
[
'filename'
];
$record
->
filearea
=
$filearea
;
$filesfordb
[]
=
$record
;
}
else
if
(
isset
(
$question
->
proformataskfileupload
))
{
$context
=
context_user
::
instance
(
$USER
->
id
);
$component
=
'user'
;
$filearea
=
'draft'
;
$fileareaid
=
$question
->
proformataskfileupload
;
}
else
{
return
;
return
;
}
}
$draftareaid
=
$question
->
proformataskfileupload
;
$usercontext
=
context_user
::
instance
(
$USER
->
id
);
$unzipinfo
=
unzip_task_file_in_
draft
_area
(
$
draft
area
id
,
$
usercontext
);
$unzipinfo
=
unzip_task_file_in_
file
_area
(
$
context
,
$component
,
$file
area
,
$
fileareaid
);
if
(
!
$unzipinfo
)
{
if
(
!
$unzipinfo
)
{
// Seems like no task file was submitted.
// Seems like no task file was submitted.
return
false
;
return
false
;
...
@@ -355,14 +408,35 @@ function save_task_and_according_files($question)
...
@@ -355,14 +408,35 @@ function save_task_and_according_files($question)
$keepfilename
=
$taskzipfilename
!=
null
?
$taskzipfilename
:
$taskxmlfilename
;
$keepfilename
=
$taskzipfilename
!=
null
?
$taskzipfilename
:
$taskxmlfilename
;
// Copy all extracted files to the corresponding file area.
// Copy all extracted files to the corresponding file area.
file_save_draft_area_files
(
$draftareaid
,
$question
->
context
->
id
,
COMPONENT_NAME
,
PROFORMA_ATTACHED_TASK_FILES_FILEAREA
,
if
(
$filearea
==
'draft'
)
{
file_save_draft_area_files
(
$fileareaid
,
$question
->
context
->
id
,
COMPONENT_NAME
,
PROFORMA_ATTACHED_TASK_FILES_FILEAREA
,
$question
->
id
,
array
(
'subdirs'
=>
true
));
$question
->
id
,
array
(
'subdirs'
=>
true
));
}
else
{
foreach
(
$fs
->
get_area_files
(
$context
->
id
,
$component
,
$filearea
,
$fileareaid
)
AS
$file
)
{
if
(
$file
->
get_filename
()
!=
'.'
&&
$file
->
get_filename
()
!=
$taskzipfilename
/* Skip taskfile because its already present in the correct filearea*/
)
{
$newfileinfo
=
array
(
'contextid'
=>
$context
->
id
,
'component'
=>
COMPONENT_NAME
,
'filearea'
=>
PROFORMA_ATTACHED_TASK_FILES_FILEAREA
,
'itemid'
=>
$question
->
id
,
'filepath'
=>
$file
->
get_filepath
(),
'filename'
=>
$file
->
get_filename
()
);
$doc
=
create_domdocument_from_task_xml
(
$usercontext
,
$draftareaid
,
$taskxmlfilename
,
$taskzipfilename
);
// Check if the file exists.
if
(
!
$fs
->
file_exists
(
$newfileinfo
[
'contextid'
],
$newfileinfo
[
'component'
],
$newfileinfo
[
'filearea'
],
$newfileinfo
[
'itemid'
],
$newfileinfo
[
'filepath'
],
$newfileinfo
[
'filename'
]))
{
$createdFile
=
$fs
->
create_file_from_storedfile
(
$newfileinfo
,
$file
);
if
(
!
$createdFile
)
{
throw
new
Exception
(
'Could not create task from moodle xml.'
);
}
}
}
}
}
$doc
=
create_domdocument_from_task_xml
(
$context
,
$component
,
$filearea
,
$fileareaid
,
$taskxmlfilename
,
$taskzipfilename
);
$namespace
=
detect_proforma_namespace
(
$doc
);
$namespace
=
detect_proforma_namespace
(
$doc
);
$filesfordb
=
array
();
$fs
=
get_file_storage
();
$embeddedelems
=
array
(
"embedded-bin-file"
,
"embedded-txt-file"
);
$embeddedelems
=
array
(
"embedded-bin-file"
,
"embedded-txt-file"
);
$attachedelems
=
array
(
"attached-bin-file"
,
"attached-txt-file"
);
$attachedelems
=
array
(
"attached-bin-file"
,
"attached-txt-file"
);
foreach
(
$doc
->
getElementsByTagNameNS
(
$namespace
,
'file'
)
as
$file
)
{
foreach
(
$doc
->
getElementsByTagNameNS
(
$namespace
,
'file'
)
as
$file
)
{
...
@@ -428,6 +502,7 @@ function save_task_and_according_files($question)
...
@@ -428,6 +502,7 @@ function save_task_and_according_files($question)
}
}
// Now move the task xml file to the designated area.
// Now move the task xml file to the designated area.
if
(
$filearea
==
'draft'
||
(
$taskzipfilename
!=
null
/* Taskxmlfile already present in the correct filearea */
))
{
$file
=
$fs
->
get_file
(
$question
->
context
->
id
,
COMPONENT_NAME
,
PROFORMA_ATTACHED_TASK_FILES_FILEAREA
,
$question
->
id
,
$file
=
$fs
->
get_file
(
$question
->
context
->
id
,
COMPONENT_NAME
,
PROFORMA_ATTACHED_TASK_FILES_FILEAREA
,
$question
->
id
,
'/'
,
$taskxmlfilename
);
'/'
,
$taskxmlfilename
);
$newfilerecord
=
array
(
$newfilerecord
=
array
(
...
@@ -450,8 +525,9 @@ function save_task_and_according_files($question)
...
@@ -450,8 +525,9 @@ function save_task_and_according_files($question)
$record
->
filename
=
$taskxmlfilename
;
$record
->
filename
=
$taskxmlfilename
;
$record
->
filearea
=
PROFORMA_TASKXML_FILEAREA
;
$record
->
filearea
=
PROFORMA_TASKXML_FILEAREA
;
$filesfordb
[]
=
$record
;
$filesfordb
[]
=
$record
;
}
if
(
$taskzipfilename
!=
null
)
{
if
(
$taskzipfilename
!=
null
&&
$filearea
==
'draft'
/* Taskzipfile already present in the correct filearea */
)
{
// Now move the task zip file to the designated area.
// Now move the task zip file to the designated area.
$file
=
$fs
->
get_file
(
$question
->
context
->
id
,
COMPONENT_NAME
,
PROFORMA_ATTACHED_TASK_FILES_FILEAREA
,
$question
->
id
,
'/'
,
$taskzipfilename
);
$file
=
$fs
->
get_file
(
$question
->
context
->
id
,
COMPONENT_NAME
,
PROFORMA_ATTACHED_TASK_FILES_FILEAREA
,
$question
->
id
,
'/'
,
$taskzipfilename
);
$newfilerecord
=
array
(
$newfilerecord
=
array
(
...
@@ -480,7 +556,7 @@ function save_task_and_according_files($question)
...
@@ -480,7 +556,7 @@ function save_task_and_according_files($question)
$DB
->
insert_records
(
'qtype_moopt_files'
,
$filesfordb
);
$DB
->
insert_records
(
'qtype_moopt_files'
,
$filesfordb
);
// Do a little bit of cleanup and remove everything from the file area we extracted.
// Do a little bit of cleanup and remove everything from the file area we extracted.
remove_all_files_from_
draft
_area
(
$
draft
area
id
,
$
usercontext
,
$keepfilename
);
remove_all_files_from_
file
_area
(
$
context
,
$component
,
$file
area
,
$
fileareaid
,
$keepfilename
);
}
}
/**
/**
...
...
This diff is collapsed.
Click to expand it.
questiontype.php
+
147
−
10
View file @
fb6fa2c5
...
@@ -69,15 +69,19 @@ class qtype_moopt extends question_type {
...
@@ -69,15 +69,19 @@ class qtype_moopt extends question_type {
*/
*/
public
function
save_question_options
(
$question
)
{
public
function
save_question_options
(
$question
)
{
// Convert the combined representation of the graderID to graderName and graderVersion
// Convert the combined representation of the graderID to graderName and graderVersion
if
(
property_exists
(
$question
,
'graderselect'
)
&&
!
is_null
(
$question
->
graderselect
))
{
$separatedGraderID
=
get_name_and_version_from_graderid_html_representation
(
$question
->
graderselect
);
$separatedGraderID
=
get_name_and_version_from_graderid_html_representation
(
$question
->
graderselect
);
$question
->
gradername
=
$separatedGraderID
->
gradername
;
$question
->
gradername
=
$separatedGraderID
->
gradername
;
$question
->
graderversion
=
$separatedGraderID
->
graderversion
;
$question
->
graderversion
=
$separatedGraderID
->
graderversion
;
}
if
(
!
isset
(
$question
->
internaldescription
[
'text'
]))
{
if
(
is_array
(
$question
->
internaldescription
))
{
if
(
!
array_key_exists
(
'text'
,
$question
->
internaldescription
)
||
!
isset
(
$question
->
internaldescription
[
'text'
]))
{
$question
->
internaldescription
=
''
;
$question
->
internaldescription
=
''
;
}
else
{
}
else
{
$question
->
internaldescription
=
trim
(
$question
->
internaldescription
[
'text'
]);
$question
->
internaldescription
=
trim
(
$question
->
internaldescription
[
'text'
]);
}
}
}
parent
::
save_question_options
(
$question
);
parent
::
save_question_options
(
$question
);
...
@@ -95,7 +99,9 @@ class qtype_moopt extends question_type {
...
@@ -95,7 +99,9 @@ class qtype_moopt extends question_type {
// Store custom settings for free text input fields.
// Store custom settings for free text input fields.
$DB
->
delete_records
(
'qtype_moopt_freetexts'
,
array
(
'questionid'
=>
$question
->
id
));
$DB
->
delete_records
(
'qtype_moopt_freetexts'
,
array
(
'questionid'
=>
$question
->
id
));
if
(
$question
->
{
'enablefreetextsubmissions'
}
&&
$question
->
{
'enablecustomsettingsforfreetextinputfields'
})
{
if
(
property_exists
(
$question
,
'enablefreetextsubmissions'
)
&&
$question
->
{
'enablefreetextsubmissions'
}
&&
property_exists
(
$question
,
'enablecustomsettingsforfreetextinputfields'
)
&&
$question
->
{
'enablecustomsettingsforfreetextinputfields'
})
{
$maxfts
=
$question
->
ftsmaxnumfields
;
$maxfts
=
$question
->
ftsmaxnumfields
;
// make sure this user-entered max num does not exceed the
// make sure this user-entered max num does not exceed the
// original plugin setting from when it was installed and first-time configured
// original plugin setting from when it was installed and first-time configured
...
@@ -104,7 +110,7 @@ class qtype_moopt extends question_type {
...
@@ -104,7 +110,7 @@ class qtype_moopt extends question_type {
throw
new
\coding_exception
(
"Assertion error: user-entered max free text input fields cannot be greater than the plugin's max number setting."
);
throw
new
\coding_exception
(
"Assertion error: user-entered max free text input fields cannot be greater than the plugin's max number setting."
);
for
(
$i
=
0
;
$i
<
$maxfts
;
$i
++
)
{
for
(
$i
=
0
;
$i
<
$maxfts
;
$i
++
)
{
if
(
$question
->
{
"enablecustomsettingsforfreetextinputfield
$i
"
})
{
if
(
property_exists
(
$question
,
"enablecustomsettingsforfreetextinputfield
$i
"
)
&&
$question
->
{
"enablecustomsettingsforfreetextinputfield
$i
"
})
{
$data
=
new
stdClass
();
$data
=
new
stdClass
();
$data
->
questionid
=
$question
->
id
;
$data
->
questionid
=
$question
->
id
;
$data
->
inputindex
=
$i
;
$data
->
inputindex
=
$i
;
...
@@ -135,4 +141,135 @@ class qtype_moopt extends question_type {
...
@@ -135,4 +141,135 @@ class qtype_moopt extends question_type {
parent
::
delete_question
(
$questionid
,
$contextid
);
parent
::
delete_question
(
$questionid
,
$contextid
);
}
}
/**
* Provide export functionality for xml format
* @param question object the question object
* @param format object the format object so that helper methods can be used
* @param extra mixed any additional format specific data that may be passed by the format (see format code for info)
* @return string the data to append to the output buffer or false if error
*/
function
export_to_xml
(
$question
,
$format
,
$extra
=
null
)
{
global
$DB
,
$COURSE
;
$xml
=
new
XMLWriter
();
$xml
->
openMemory
();
$xml
->
setIndent
(
1
);
$xml
->
setIndentString
(
' '
);
/* Add an empty answer-Element because Moodle-Import function expects it */
$xml
->
startElement
(
'answer'
);
$xml
->
writeAttribute
(
'fraction'
,
0
);
$xml
->
writeElement
(
'text'
,
''
);
$xml
->
endElement
();
$fs
=
get_file_storage
();
$taskFileRecord
=
$DB
->
get_record
(
'qtype_moopt_files'
,
array
(
'questionid'
=>
$question
->
id
,
'fileid'
=>
'task'
));
if
(
!
$taskFileRecord
)
{
// taskxml file without zip
$taskFileRecord
=
$DB
->
get_record
(
'qtype_moopt_files'
,
array
(
'questionid'
=>
$question
->
id
,
'fileid'
=>
'taskxml'
));
}
$context
=
context_course
::
instance
(
$COURSE
->
id
);
$taskfile
=
$fs
->
get_file
(
$context
->
id
,
COMPONENT_NAME
,
$taskFileRecord
->
filearea
,
$question
->
id
,
$taskFileRecord
->
filepath
,
$taskFileRecord
->
filename
);
$taskfilename
=
$taskfile
->
get_filename
();
$taskfilepath
=
$taskfile
->
get_filepath
();
$taskfileencoding
=
'base64'
;
$taskfilecontentbase64
=
base64_encode
(
$taskfile
->
get_content
());
$xml
->
startElement
(
'taskfile'
);
$xml
->
writeAttribute
(
'filearea'
,
$taskFileRecord
->
filearea
);
$xml
->
writeAttribute
(
'name'
,
$taskfilename
);
$xml
->
writeAttribute
(
'path'
,
$taskfilepath
);
$xml
->
writeAttribute
(
'encoding'
,
$taskfileencoding
);
$xml
->
writeRaw
(
$taskfilecontentbase64
);
$xml
->
endElement
();
/* Add freetext specific options to export */
$customOptionsForAllFreetexts
=
$DB
->
get_records
(
'qtype_moopt_freetexts'
,
array
(
'questionid'
=>
$question
->
id
));
if
(
count
(
$customOptionsForAllFreetexts
)
>
0
)
{
$xml
->
startElement
(
'customsettingsforfreetextinputfields'
);
foreach
(
$customOptionsForAllFreetexts
as
$customOptionsForOneFreetext
)
{
$inputindex
=
$customOptionsForOneFreetext
->
inputindex
;
$xml
->
startElement
(
'field'
);
$xml
->
writeAttribute
(
'index'
,
$inputindex
);
$presetfilename
=
$customOptionsForOneFreetext
->
presetfilename
?
"0"
:
"1"
;
//Invert because in the form later "0" means true
$xml
->
writeElement
(
'namesettingsforfreetextinput'
,
$presetfilename
);
$xml
->
writeElement
(
'freetextinputfieldname'
,
$customOptionsForOneFreetext
->
filename
);
$xml
->
writeElement
(
'ftsoverwrittenlang'
,
$customOptionsForOneFreetext
->
ftslang
);
$xml
->
writeElement
(
'ftsinitialdisplayrows'
,
$customOptionsForOneFreetext
->
initialdisplayrows
);
$xml
->
startElement
(
'freetextinputfieldtemplate'
);
$xml
->
writeCdata
(
$customOptionsForOneFreetext
->
filecontent
);
$xml
->
endElement
();
$xml
->
endElement
();
}
$xml
->
endElement
();
}
$xmloutput
=
$xml
->
outputMemory
();
$xmloutput
.
=
parent
::
export_to_xml
(
$question
,
$format
,
$extra
);
return
$xmloutput
;
}
/**
* Provide import functionality for xml format
* @param data mixed the segment of data containing the question
* @param question object question object processed (so far) by standard import code
* @param format object the format object so that helper methods can be used (in particular error() )
* @param extra mixed any additional format specific data that may be passed by the format (see format code for info)
* @return object question object suitable for save_options() call or false if cannot handle
*/
function
import_from_xml
(
$data
,
$question
,
$format
,
$extra
=
null
)
{
global
$COURSE
;
$ret
=
parent
::
import_from_xml
(
$data
,
$question
,
$format
,
$extra
);
$root
=
$data
[
'#'
];
/* Import Taskfile */
if
(
$ret
&&
array_key_exists
(
'taskfile'
,
$root
))
{
$taskfileattributes
=
$root
[
'taskfile'
][
0
][
'@'
];
$taskfilearea
=
$taskfileattributes
[
'filearea'
];
$taskfilename
=
$taskfileattributes
[
'name'
];
$taskfilepath
=
$taskfileattributes
[
'path'
];
$taskfileencoding
=
$taskfileattributes
[
'encoding'
];
$taskfileencoded
=
$root
[
'taskfile'
][
0
][
'#'
];
/* Check encoding of */
$taskfilecontent
=
false
;
if
(
strtolower
(
$taskfileencoding
)
==
'base64'
)
{
$taskfilecontent
=
base64_decode
(
$taskfileencoded
,
true
);
}
if
(
!
$taskfilecontent
)
{
throw
new
InvalidArgumentException
(
"The taskfile could not be encoded from moodle xml."
);
}
$context
=
context_course
::
instance
(
$COURSE
->
id
);
$taskfileinfo
=
[
'context'
=>
$context
,
'component'
=>
COMPONENT_NAME
,
'filearea'
=>
$taskfilearea
,
'filepath'
=>
$taskfilepath
,
'filename'
=>
$taskfilename
,
'content'
=>
$taskfilecontent
];
// Only save the taskfile information here and save the file later because question id is unknown until later
$ret
->
taskfile
=
$taskfileinfo
;
}
/* Import custom settings for FreetextInputFields */
if
(
$ret
&&
array_key_exists
(
'customsettingsforfreetextinputfields'
,
$root
))
{
$ret
->
{
'enablecustomsettingsforfreetextinputfields'
}
=
true
;
$customsettingsforfreetextinputfields
=
$root
[
'customsettingsforfreetextinputfields'
][
0
][
'#'
][
'field'
];
foreach
(
$customsettingsforfreetextinputfields
AS
$field
)
{
$inputIndex
=
$field
[
'@'
][
'index'
];
$ret
->
{
'enablecustomsettingsforfreetextinputfield'
.
$inputIndex
}
=
true
;
$options
=
$field
[
'#'
];
foreach
(
$options
AS
$option
=>
$optionValue
)
{
$ret
->
{
$option
.
$inputIndex
}
=
$optionValue
[
0
][
'#'
];
}
}
}
return
$ret
;
}
}
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment