From b57e1c95904080c367e9f185eeb3d290285772e2 Mon Sep 17 00:00:00 2001 From: Amaia Anabitarte Date: Tue, 5 Nov 2019 00:35:51 +0100 Subject: [PATCH] MDL-67059 core_h5p: UI to manually upload H5P content type libraries Co-authored by: Mihail Geshoski --- admin/settings/h5p.php | 29 ++++++++++ admin/settings/top.php | 1 + h5p/classes/form/uploadlibraries_form.php | 57 +++++++++++++++++++ h5p/classes/helper.php | 1 - h5p/libraries.php | 67 +++++++++++++++++++++++ lang/en/h5p.php | 10 ++++ version.php | 2 +- 7 files changed, 165 insertions(+), 2 deletions(-) create mode 100644 admin/settings/h5p.php create mode 100644 h5p/classes/form/uploadlibraries_form.php create mode 100644 h5p/libraries.php diff --git a/admin/settings/h5p.php b/admin/settings/h5p.php new file mode 100644 index 0000000000000..81ac282e0ceb8 --- /dev/null +++ b/admin/settings/h5p.php @@ -0,0 +1,29 @@ +. + +/** + * H5P settings link. + * + * @package core_h5p + * @copyright 2019 Amaia Anabitarte + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +// Settings page. +$ADMIN->add('h5p', new admin_externalpage('h5psettings', get_string('h5pmanage', 'core_h5p'), + new moodle_url('/h5p/libraries.php'), ['moodle/site:config', 'moodle/h5p:updatelibraries'])); diff --git a/admin/settings/top.php b/admin/settings/top.php index 32d91c604d846..8c922d1196c8b 100644 --- a/admin/settings/top.php +++ b/admin/settings/top.php @@ -31,6 +31,7 @@ $ADMIN->add('root', new admin_category('analytics', new lang_string('analytics', 'analytics'))); $ADMIN->add('root', new admin_category('competencies', new lang_string('competencies', 'core_competency'))); $ADMIN->add('root', new admin_category('badges', new lang_string('badges'), empty($CFG->enablebadges))); +$ADMIN->add('root', new admin_category('h5p', new lang_string('h5p', 'core_h5p'))); $ADMIN->add('root', new admin_category('location', new lang_string('location','admin'))); $ADMIN->add('root', new admin_category('language', new lang_string('language'))); $ADMIN->add('root', new admin_category('messaging', new lang_string('messagingcategory', 'admin'))); diff --git a/h5p/classes/form/uploadlibraries_form.php b/h5p/classes/form/uploadlibraries_form.php new file mode 100644 index 0000000000000..a3091b73edfe3 --- /dev/null +++ b/h5p/classes/form/uploadlibraries_form.php @@ -0,0 +1,57 @@ +. + +/** + * Upload an h5p content to update the content libraries. + * + * @package core_h5p + * @copyright 2019 Amaia Anabitarte + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace core_h5p\form; + +defined('MOODLE_INTERNAL') || die(); + +/** + * Upload a zip or h5p content to update the content libraries. + * + * @copyright 2019 Amaia Anabitarte + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class uploadlibraries_form extends \moodleform { + /** + * Form definition. + */ + public function definition() { + $mform = $this->_form; + $mform->addElement('header', 'settingsheader', get_string('uploadlibraries', 'core_h5p')); + + $filemanageroptions = array( + 'accepted_types' => array('.h5p', '.zip'), + 'maxbytes' => 0, + 'maxfiles' => 1, + 'subdirs' => 0 + ); + + $mform->addElement('filepicker', 'h5ppackage', get_string('h5ppackage', 'core_h5p'), + null, $filemanageroptions); + $mform->addHelpButton('h5ppackage', 'h5ppackage', 'core_h5p'); + $mform->addRule('h5ppackage', null, 'required'); + + $this->add_action_buttons(false, get_string('uploadlibraries', 'core_h5p')); + } +} diff --git a/h5p/classes/helper.php b/h5p/classes/helper.php index 06cb26cf3f73a..d239d92b3238d 100644 --- a/h5p/classes/helper.php +++ b/h5p/classes/helper.php @@ -76,7 +76,6 @@ public static function save_h5p(factory $factory, \stored_file $file, \stdClass return $h5pstorage->contentId; } - return false; } diff --git a/h5p/libraries.php b/h5p/libraries.php new file mode 100644 index 0000000000000..ad9c6e250e827 --- /dev/null +++ b/h5p/libraries.php @@ -0,0 +1,67 @@ +. + +/** + * Manage H5P libraries settings page. + * + * @package core_h5p + * @copyright 2019 Amaia Anabitarte + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +require_once(__DIR__ . '/../config.php'); + +require_login(null, false); + +$context = context_system::instance(); +require_capability('moodle/h5p:updatelibraries', $context); + +$pagetitle = get_string('h5pmanage', 'core_h5p'); +$url = new \moodle_url("/h5p/libraries.php"); + +$PAGE->set_context($context); +$PAGE->set_url($url); +$PAGE->set_title($pagetitle); +$PAGE->set_pagelayout('admin'); +$PAGE->set_heading($pagetitle); + +echo $OUTPUT->header(); +echo $OUTPUT->heading($pagetitle); +echo $OUTPUT->box(get_string('librariesmanagerdescription', 'core_h5p')); + +$form = new \core_h5p\form\uploadlibraries_form(); +if ($data = $form->get_data()) { + require_sesskey(); + + // Get the file from the users draft area. + $usercontext = context_user::instance($USER->id); + $fs = get_file_storage(); + $files = $fs->get_area_files($usercontext->id, 'user', 'draft', $data->h5ppackage, 'id', + false); + $file = reset($files); + + // Validate and save the H5P package. + $h5pfactory = new \core_h5p\factory(); + // Because we are passing skipcontent = true to save_h5p function, the returning value is false in an error + // is encountered, null when successfully saving the package without creating the content. + if (\core_h5p\helper::save_h5p($h5pfactory, $file, new stdClass(), false, true) === false) { + echo $OUTPUT->notification(get_string('invalidpackage', 'core_h5p'), 'error'); + } else { + echo $OUTPUT->notification(get_string('uploadsuccess', 'core_h5p'), 'success'); + } +} +$form->display(); +echo $OUTPUT->footer(); diff --git a/lang/en/h5p.php b/lang/en/h5p.php index 91a2fcae9ac89..93101bb8323ea 100644 --- a/lang/en/h5p.php +++ b/lang/en/h5p.php @@ -79,6 +79,9 @@ $string['h5pfilenotfound'] = 'H5P file not found'; $string['h5pinvalidurl'] = 'Invalid H5P content URL.'; $string['h5pprivatefile'] = 'This H5P content can\'t be displayed because you don\'t have access to the .h5p file.'; +$string['h5pmanage'] = 'Manage H5P content types'; +$string['h5ppackage'] = 'H5P content type'; +$string['h5ppackage_help'] = 'An H5P content type is a file with an H5P or ZIP extension containing all libraries required to display the content.'; $string['hideadvanced'] = 'Hide advanced'; $string['invalidcontextid'] = 'H5P file not found (invalid contextid)'; $string['invalidfile'] = 'File "{$a->%filename}" not allowed. Only files with the following extensions are allowed: {$a->%files-allowed}.'; @@ -92,11 +95,16 @@ $string['invalidlibraryproperty'] = 'Can\'t read the property {$a->%property} in {$a->%library}'; $string['invalidmainjson'] = 'A valid main h5p.json file is missing'; $string['invalidmultiselectoption'] = 'Invalid selected option in multi-select.'; +$string['invalidpackage'] = 'Invalid H5P content type'; $string['invalidselectoption'] = 'Invalid selected option in select.'; $string['invalidsemanticsjson'] = 'Invalid semantics.json file has been included in the library {$a->%name}'; $string['invalidsemanticstype'] = 'H5P internal error: unknown content type "{$a->@type}" in semantics. Removing content!'; $string['invalidstring'] = 'Provided string is not valid according to regexp in semantics. (value: "{$a->%value}", regexp: "{$a->%regexp}")'; $string['librarydirectoryerror'] = 'Library directory name must match machineName or machineName-majorVersion.minorVersion (from library.json). (Directory: {$a->%directoryName} , machineName: {$a->%machineName}, majorVersion: {$a->%majorVersion}, minorVersion: {$a->%minorVersion})'; +$string['librariesmanagerdescription'] = '

H5P enables users to create interactive content by providing a range of content types.

'. + '

To ensure that only trusted H5P content types are used on your site, you need to either

'. + '
  • Upload H5P content types from h5p.org or
  • Enable the scheduled task \'Download available H5P content types from h5p.org
'. + '

Note that users will only be able to use the H5P content types which are installed on your site.

'; $string['license'] = 'License'; $string['licenseCC010'] = 'CC0 1.0 Universal (CC0 1.0) Public Domain Dedication'; $string['licenseCC010U'] = 'CC0 1.0 Universal'; @@ -155,6 +163,8 @@ $string['unpackedFilesExceedsMaxSize'] = 'The total size of the unpacked files exceeds the maximum size allowed. ({$a->%used} > {$a->%max})'; $string['updatedlibraries'] = 'Updated {$a->%old} H5P libraries.'; $string['updatedlibrary'] = 'Updated {$a->%old} H5P library.'; +$string['uploadlibraries'] = 'Upload H5P content types'; +$string['uploadsuccess'] = 'H5P content types uploaded successfully'; $string['wrongversion'] = 'The version of the H5P library {$a->%machineName} used in this content is not valid. Content contains {$a->%contentLibrary}, but it should be {$a->%semanticsLibrary}.'; $string['year'] = 'Year'; $string['years'] = 'Year(s)'; diff --git a/version.php b/version.php index 3177b09c3fb96..767843c84f112 100644 --- a/version.php +++ b/version.php @@ -29,7 +29,7 @@ defined('MOODLE_INTERNAL') || die(); -$version = 2019110500.01; // YYYYMMDD = weekly release date of this DEV branch. +$version = 2019110500.02; // YYYYMMDD = weekly release date of this DEV branch. // RR = release increments - 00 in DEV branches. // .XX = incremental changes.