Merge branch 'MDL-71885-master' of git://github.com/sarjona/moodle

This commit is contained in:
Eloy Lafuente (stronk7) 2021-07-05 11:43:35 +02:00
commit 2d3798bd39
10 changed files with 856 additions and 3 deletions

View File

@ -217,6 +217,101 @@ class api {
return [$file, $h5p];
}
/**
* Get the original file and H5P DB instance for a given H5P pluginfile URL. If it doesn't exist, it's not created.
* If the file has been added as a reference, this method will return the original linked file.
*
* @param string $url H5P pluginfile URL.
* @param bool $preventredirect Set to true in scripts that can not redirect (CLI, RSS feeds, etc.), throws exceptions.
* @param bool $skipcapcheck Whether capabilities should be checked or not to get the pluginfile URL because sometimes they
* might be controlled before calling this method.
*
* @return array of [\stored_file|false, \stdClass|false, \stored_file|false]:
* - \stored_file: original local file for the given url (if it has been added as a reference, this method
* will return the linked file) or false if there isn't any H5P file with this URL.
* - \stdClass: an H5P object or false if there isn't any H5P with this URL.
* - \stored_file: file associated to the given url (if it's different from original) or false when both files
* (original and file) are the same.
* @since Moodle 4.0
*/
public static function get_original_content_from_pluginfile_url(string $url, bool $preventredirect = true,
bool $skipcapcheck = false): array {
$file = false;
list($originalfile, $h5p) = self::get_content_from_pluginfile_url($url, $preventredirect, $skipcapcheck);
if ($originalfile) {
if ($reference = $originalfile->get_reference()) {
$file = $originalfile;
// If the file has been added as a reference to any other file, get it.
$fs = new \file_storage();
$referenced = \file_storage::unpack_reference($reference);
$originalfile = $fs->get_file(
$referenced['contextid'],
$referenced['component'],
$referenced['filearea'],
$referenced['itemid'],
$referenced['filepath'],
$referenced['filename']
);
$h5p = self::get_content_from_pathnamehash($originalfile->get_pathnamehash());
if (empty($h5p)) {
$h5p = false;
}
}
}
return [$originalfile, $h5p, $file];
}
/**
* Check if the user can edit an H5P file. It will return true in the following situations:
* - The user is the author of the file.
* - The component is different from user (i.e. private files).
* - If the component is contentbank, the user can edit this file (calling the ContentBank API).
* - If the component is mod_h5pactivity, the user has the addinstance capability.
*
* @param \stored_file $file The H5P file to check.
*
* @return boolean Whether the user can edit or not the given file.
* @since Moodle 4.0
*/
public static function can_edit_content(\stored_file $file): bool {
global $USER;
// Private files.
$currentuserisauthor = $file->get_userid() == $USER->id;
$isuserfile = $file->get_component() === 'user';
if ($currentuserisauthor && $isuserfile) {
// The user can edit the content because it's a private user file and she is the owner.
return true;
}
// For mod_h5pactivity, check whether the user can add/edit them.
if ($file->get_component() === 'mod_h5pactivity') {
$context = \context::instance_by_id($file->get_contextid());
if (has_capability("mod/h5pactivity:addinstance", $context)) {
// The user can edit the content because she has the capability for creating H5P activities where the file belongs.
return true;
}
}
// For contentbank files, use the API to check if the user has access.
if ($file->get_component() == 'contentbank') {
$cb = new \core_contentbank\contentbank();
$content = $cb->get_content_from_id($file->get_itemid());
$contenttype = $content->get_content_type_instance();
if ($contenttype instanceof \contenttype_h5p\contenttype) {
// Only H5P contenttypes should be considered here.
if ($contenttype->can_edit($content)) {
// The user has permissions to edit the H5P in the content bank.
return true;
}
}
}
return false;
}
/**
* Create, if it doesn't exist, the H5P DB instance id for a H5P pluginfile URL. If it exists:
* - If the content is not the same, remove the existing content and re-deploy the H5P content again.

View File

@ -0,0 +1,83 @@
<?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/>.
namespace core_h5p\form;
use core_h5p\editor;
/**
* Form to edit an existing H5P content.
*
* @package core_h5p
* @copyright 2020 Victor Deniz <victor@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class editcontent_form extends \moodleform {
/** @var editor H5P editor object */
private $editor;
/**
* The form definition.
*/
public function definition() {
$mform = $this->_form;
$id = $this->_customdata['id'] ?? null;
$contenturl = $this->_customdata['contenturl'] ?? null;
$returnurl = $this->_customdata['returnurl'] ?? null;
$editor = new editor();
if ($id) {
$mform->addElement('hidden', 'id', $id);
$mform->setType('id', PARAM_INT);
$editor->set_content($id);
}
if ($contenturl) {
$mform->addElement('hidden', 'url', $contenturl);
$mform->setType('url', PARAM_LOCALURL);
}
if ($returnurl) {
$mform->addElement('hidden', 'returnurl', $returnurl);
$mform->setType('returnurl', PARAM_LOCALURL);
}
$this->editor = $editor;
$mformid = 'h5peditor';
$mform->setAttributes(array('id' => $mformid) + $mform->getAttributes());
$this->add_action_buttons();
$editor->add_editor_to_form($mform);
$this->add_action_buttons();
}
/**
* Updates an H5P content.
*
* @param \stdClass $data Object with all the H5P data.
*
* @return void
*/
public function save_h5p(\stdClass $data): void {
$this->editor->save_content($data);
}
}

View File

@ -153,12 +153,14 @@ class player {
* @param stdClass $config Configuration for H5P buttons.
* @param bool $preventredirect Set to true in scripts that can not redirect (CLI, RSS feeds, etc.), throws exceptions
* @param string $component optional moodle component to sent xAPI tracking
* @param bool $displayedit Whether the edit button should be displayed below the H5P content.
*
* @return string The embedable code to display a H5P file.
*/
public static function display(string $url, \stdClass $config, bool $preventredirect = true,
string $component = ''): string {
global $OUTPUT;
string $component = '', bool $displayedit = false): string {
global $OUTPUT, $CFG;
$params = [
'url' => $url,
'preventredirect' => $preventredirect,
@ -176,6 +178,16 @@ class player {
$template = new \stdClass();
$template->embedurl = $fileurl->out(false);
if ($displayedit) {
list($originalfile, $h5p) = api::get_original_content_from_pluginfile_url($url, $preventredirect, true);
if ($originalfile) {
// Check if the user can edit this content.
if (api::can_edit_content($originalfile)) {
$template->editurl = $CFG->wwwroot . '/h5p/edit.php?url=' . $url;
}
}
}
$result = $OUTPUT->render_from_template('core_h5p/h5pembed', $template);
$result .= self::get_resize_code();
return $result;

114
h5p/edit.php Normal file
View File

@ -0,0 +1,114 @@
<?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/>.
/**
* Open the editor to modify an H5P content from a given H5P URL.
*
* @package core_h5p
* @copyright 2021 Sara Arjona <sara@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(__DIR__ . '/../config.php');
require_once("$CFG->libdir/formslib.php");
require_once("$CFG->libdir/filestorage/file_storage.php");
require_login(null, false);
$contenturl = required_param('url', PARAM_LOCALURL);
$returnurl = optional_param('returnurl', null, PARAM_LOCALURL);
// If no returnurl is defined, use local_referer.
if (empty($returnurl)) {
$returnurl = get_local_referer(false);
if (empty($returnurl)) {
// If local referer is empty, returnurl will be set to default site page.
$returnurl = new \moodle_url('/');
}
}
$contentid = null;
$isreferenced = false;
$context = \context_system::instance();
if (!empty($contenturl)) {
list($originalfile, $h5p, $file) = \core_h5p\api::get_original_content_from_pluginfile_url($contenturl);
$isreferenced = ($file !== false);
if ($originalfile) {
// Check if the user can edit the content behind the given URL.
if (\core_h5p\api::can_edit_content($originalfile)) {
if (!$h5p) {
// This H5P file hasn't been deployed yet, so it should be saved to create the entry into the H5P DB.
\core_h5p\local\library\autoloader::register();
$factory = new \core_h5p\factory();
$config = new \stdClass();
$onlyupdatelibs = !\core_h5p\helper::can_update_library($originalfile);
$contentid = \core_h5p\helper::save_h5p($factory, $originalfile, $config, $onlyupdatelibs, false);
} else {
// The H5P content exists. Update the contentid value.
$contentid = $h5p->id;
}
}
if ($file) {
list($context, $course, $cm) = get_context_info_array($file->get_contextid());
if ($course) {
$context = \context_course::instance($course->id);
}
} else {
list($context, $course, $cm) = get_context_info_array($originalfile->get_contextid());
if ($course) {
$context = \context_course::instance($course->id);
}
}
}
}
if (empty($contentid)) {
throw new \moodle_exception('error:emptycontentid', 'core_h5p', $returnurl);
}
$pagetitle = get_string('h5peditor', 'core_h5p');
$url = new \moodle_url("/h5p/edit.php");
$PAGE->set_context($context);
$PAGE->set_url($url);
$PAGE->set_title($pagetitle);
$PAGE->set_heading($pagetitle);
$values = [
'id' => $contentid,
'contenturl' => $contenturl,
'returnurl' => $returnurl,
];
$form = new \core_h5p\form\editcontent_form(null, $values);
if ($form->is_cancelled()) {
redirect($returnurl);
} else if ($data = $form->get_data()) {
$form->save_h5p($data);
if (!empty($returnurl)) {
redirect($returnurl);
}
}
echo $OUTPUT->header();
if ($isreferenced) {
echo $OUTPUT->notification(get_string('contentinuse', 'core_h5p'), 'info');
}
$form->display();
echo $OUTPUT->footer();

View File

@ -24,6 +24,7 @@
Variables required for this template:
* embedurl - The URL with the H5P file to embed
* editurl - The URL for the edit button; if it's empty, the edit button won't be displayed.
Example context (json):
{
@ -35,3 +36,7 @@
allowfullscreen="allowfullscreen" class="h5p-player w-100 border-0"
style="height: 0px;" id="{{uniqid}}-h5player">
</iframe>
{{#editurl}}
<a href="{{editurl}}">{{#str}}editcontent, core_h5p{{/str}}</a>
{{/editurl}}

View File

@ -333,6 +333,330 @@ class api_test extends \advanced_testcase {
$this->assertFalse($h5p);
}
/**
* Test the behaviour of get_original_content_from_pluginfile_url().
*
* @covers ::get_original_content_from_pluginfile_url
*/
public function test_get_original_content_from_pluginfile_url(): void {
$this->setRunTestInSeparateProcess(true);
$this->resetAfterTest();
$this->setAdminUser();
$factory = new factory();
$syscontext = \context_system::instance();
// Create the original file.
$filename = 'greeting-card-887.h5p';
$path = __DIR__ . '/fixtures/' . $filename;
$originalfile = helper::create_fake_stored_file_from_path($path);
$originalfilerecord = [
'contextid' => $originalfile->get_contextid(),
'component' => $originalfile->get_component(),
'filearea' => $originalfile->get_filearea(),
'itemid' => $originalfile->get_itemid(),
'filepath' => $originalfile->get_filepath(),
'filename' => $originalfile->get_filename(),
];
$config = (object)[
'frame' => 1,
'export' => 1,
'embed' => 0,
'copyright' => 0,
];
$originalurl = \moodle_url::make_pluginfile_url(
$originalfile->get_contextid(),
$originalfile->get_component(),
$originalfile->get_filearea(),
$originalfile->get_itemid(),
$originalfile->get_filepath(),
$originalfile->get_filename()
);
// Create a reference to the original file.
$reffilerecord = [
'contextid' => $syscontext->id,
'component' => 'core',
'filearea' => 'phpunit',
'itemid' => 0,
'filepath' => '/',
'filename' => $filename
];
$fs = get_file_storage();
$ref = $fs->pack_reference($originalfilerecord);
$repos = \repository::get_instances(['type' => 'user']);
$userrepository = reset($repos);
$referencedfile = $fs->create_file_from_reference($reffilerecord, $userrepository->id, $ref);
$this->assertEquals($referencedfile->get_contenthash(), $originalfile->get_contenthash());
$referencedurl = \moodle_url::make_pluginfile_url(
$syscontext->id,
'core',
'phpunit',
0,
'/',
$filename
);
// Scenario 1: Original file (without any reference).
$originalh5pid = helper::save_h5p($factory, $originalfile, $config);
list($source, $h5p, $file) = api::get_original_content_from_pluginfile_url($originalurl->out());
$this->assertEquals($originalfile->get_pathnamehash(), $source->get_pathnamehash());
$this->assertEquals($originalfile->get_contenthash(), $source->get_contenthash());
$this->assertEquals($originalh5pid, $h5p->id);
$this->assertFalse($file);
// Scenario 2: Referenced file (alias to originalfile).
list($source, $h5p, $file) = api::get_original_content_from_pluginfile_url($referencedurl->out());
$this->assertEquals($originalfile->get_pathnamehash(), $source->get_pathnamehash());
$this->assertEquals($originalfile->get_contenthash(), $source->get_contenthash());
$this->assertEquals($originalfile->get_contenthash(), $source->get_contenthash());
$this->assertEquals($originalh5pid, $h5p->id);
$this->assertEquals($referencedfile->get_pathnamehash(), $file->get_pathnamehash());
$this->assertEquals($referencedfile->get_contenthash(), $file->get_contenthash());
$this->assertEquals($referencedfile->get_contenthash(), $file->get_contenthash());
// Scenario 3: Unexisting file.
$unexistingurl = \moodle_url::make_pluginfile_url(
$syscontext->id,
'core',
'phpunit',
0,
'/',
'unexisting.h5p'
);
list($source, $h5p, $file) = api::get_original_content_from_pluginfile_url($unexistingurl->out());
$this->assertFalse($source);
$this->assertFalse($h5p);
$this->assertFalse($file);
}
/**
* Test the behaviour of can_edit_content().
*
* @covers ::can_edit_content
* @dataProvider can_edit_content_provider
*
* @param string $currentuser User who will call the method.
* @param string $fileauthor Author of the file to check.
* @param string $filecomponent Component of the file to check.
* @param bool $expected Expected result after calling the can_edit_content method.
*
* @return void
*/
public function test_can_edit_content(string $currentuser, string $fileauthor, string $filecomponent, bool $expected): void {
global $USER;
$this->setRunTestInSeparateProcess(true);
$this->resetAfterTest();
// Create course.
$course = $this->getDataGenerator()->create_course();
$context = \context_course::instance($course->id);
// Create some users.
$this->setAdminUser();
$teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
$student = $this->getDataGenerator()->create_and_enrol($course, 'student');
$users = [
'admin' => $USER,
'teacher' => $teacher,
'student' => $student,
];
// Set current user.
if ($currentuser !== 'admin') {
$this->setUser($users[$currentuser]);
}
// Create the file.
$filename = 'greeting-card-887.h5p';
$path = __DIR__ . '/fixtures/' . $filename;
if ($filecomponent === 'contentbank') {
$generator = $this->getDataGenerator()->get_plugin_generator('core_contentbank');
$contents = $generator->generate_contentbank_data(
'contenttype_h5p',
1,
(int)$users[$fileauthor]->id,
$context,
true,
$path
);
$content = array_shift($contents);
$file = $content->get_file();
} else {
$filerecord = [
'contextid' => $context->id,
'component' => $filecomponent,
'filearea' => 'unittest',
'itemid' => rand(),
'filepath' => '/',
'filename' => basename($path),
'userid' => $users[$fileauthor]->id,
];
$fs = get_file_storage();
$file = $fs->create_file_from_pathname($filerecord, $path);
}
// Check if the currentuser can edit the file.
$result = api::can_edit_content($file);
$this->assertEquals($expected, $result);
}
/**
* Data provider for test_can_edit_content().
*
* @return array
*/
public function can_edit_content_provider(): array {
return [
// Component = user.
'user: Admin user is author' => [
'currentuser' => 'admin',
'fileauthor' => 'admin',
'filecomponent' => 'user',
'expected' => true,
],
'user: Admin user, teacher is author' => [
'currentuser' => 'admin',
'fileauthor' => 'teacher',
'filecomponent' => 'user',
'expected' => false,
],
'user: Teacher user, teacher is author' => [
'currentuser' => 'teacher',
'fileauthor' => 'teacher',
'filecomponent' => 'user',
'expected' => true,
],
'user: Teacher user, admin is author' => [
'currentuser' => 'teacher',
'fileauthor' => 'admin',
'filecomponent' => 'user',
'expected' => false,
],
'user: Student user, student is author' => [
'currentuser' => 'student',
'fileauthor' => 'student',
'filecomponent' => 'user',
'expected' => true,
],
'user: Student user, teacher is author' => [
'currentuser' => 'student',
'fileauthor' => 'teacher',
'filecomponent' => 'user',
'expected' => false,
],
// Component = mod_h5pactivity.
'mod_h5pactivity: Admin user is author' => [
'currentuser' => 'admin',
'fileauthor' => 'admin',
'filecomponent' => 'mod_h5pactivity',
'expected' => true,
],
'mod_h5pactivity: Admin user, teacher is author' => [
'currentuser' => 'admin',
'fileauthor' => 'teacher',
'filecomponent' => 'mod_h5pactivity',
'expected' => true,
],
'mod_h5pactivity: Teacher user, teacher is author' => [
'currentuser' => 'teacher',
'fileauthor' => 'teacher',
'filecomponent' => 'mod_h5pactivity',
'expected' => true,
],
'mod_h5pactivity: Teacher user, admin is author' => [
'currentuser' => 'teacher',
'fileauthor' => 'admin',
'filecomponent' => 'mod_h5pactivity',
'expected' => true,
],
'mod_h5pactivity: Student user, student is author' => [
'currentuser' => 'student',
'fileauthor' => 'student',
'filecomponent' => 'mod_h5pactivity',
'expected' => false,
],
'mod_h5pactivity: Student user, teacher is author' => [
'currentuser' => 'student',
'fileauthor' => 'teacher',
'filecomponent' => 'mod_h5pactivity',
'expected' => false,
],
// Component = mod_forum.
'mod_forum: Admin user is author' => [
'currentuser' => 'admin',
'fileauthor' => 'admin',
'filecomponent' => 'mod_forum',
'expected' => false,
],
'mod_forum: Admin user, teacher is author' => [
'currentuser' => 'admin',
'fileauthor' => 'teacher',
'filecomponent' => 'mod_forum',
'expected' => false,
],
// Component = contentbank.
'contentbank: Admin user is author' => [
'currentuser' => 'admin',
'fileauthor' => 'admin',
'filecomponent' => 'contentbank',
'expected' => true,
],
'contentbank: Admin user, teacher is author' => [
'currentuser' => 'admin',
'fileauthor' => 'teacher',
'filecomponent' => 'contentbank',
'expected' => true,
],
'contentbank: Teacher user, teacher is author' => [
'currentuser' => 'teacher',
'fileauthor' => 'teacher',
'filecomponent' => 'contentbank',
'expected' => true,
],
'contentbank: Teacher user, admin is author' => [
'currentuser' => 'teacher',
'fileauthor' => 'admin',
'filecomponent' => 'contentbank',
'expected' => false,
],
'contentbank: Student user, student is author' => [
'currentuser' => 'student',
'fileauthor' => 'student',
'filecomponent' => 'contentbank',
'expected' => false,
],
'contentbank: Student user, teacher is author' => [
'currentuser' => 'student',
'fileauthor' => 'teacher',
'filecomponent' => 'contentbank',
'expected' => false,
],
// Unexisting components.
'Unexisting component' => [
'currentuser' => 'admin',
'fileauthor' => 'admin',
'filecomponent' => 'unexisting_component',
'expected' => false,
],
'Unexisting module activity' => [
'currentuser' => 'admin',
'fileauthor' => 'admin',
'filecomponent' => 'mod_unexisting',
'expected' => false,
],
];
}
/**
* Test the behaviour of create_content_from_pluginfile_url().
*/

View File

@ -1,6 +1,12 @@
This files describes API changes in core libraries and APIs,
information provided here is intended especially for developers.
=== 4.0 ===
* Added new methods to api: get_original_content_from_pluginfile_url and can_edit_content.
* Added edit.php and editcontent_form class, for modifying H5P content given an H5P identifier (from the h5p table).
* Added a new parameter to the player::display method, to define whether the edit button should be displayed below the
H5P content or not. Default value for this parameter is false.
=== 3.11 ===
* Added $skipcapcheck parameter to H5P constructor, api::create_content_from_pluginfile_url() and
api::get_content_from_pluginfile_url() to let skip capabilities check to get the pluginfile URL.

View File

@ -59,6 +59,7 @@ $string['connectionLost'] = 'Connection lost. Results will be stored and sent wh
$string['connectionReestablished'] = 'Connection reestablished.';
$string['contentCopied'] = 'Content is copied to the clipboard';
$string['contentchanged'] = 'This content has changed since you last used it.';
$string['contentinuse'] = 'This content may be in use in other places.';
$string['contenttype'] = 'Content type';
$string['copyright'] = 'Rights of use';
$string['copyrightinfo'] = 'Copyright information';
@ -75,9 +76,11 @@ $string['description'] = 'Description';
$string['disablefullscreen'] = 'Disable fullscreen';
$string['download'] = 'Download';
$string['downloadtitle'] = 'Download this content as a H5P file.';
$string['editcontent'] = 'Edit H5P content';
$string['editor'] = 'Editor';
$string['embed'] = 'Embed';
$string['embedtitle'] = 'View the embed code for this content.';
$string['error:emptycontentid'] = 'The given URL is incorrect or you cannot edit this file.';
$string['eventh5pviewed'] = 'H5P content viewed';
$string['eventh5pdeleted'] = 'H5P deleted';
$string['feature'] = 'Feature';
@ -88,6 +91,7 @@ $string['filter_displayh5p_description'] = 'The Display H5P filter converts URLs
$string['fullscreen'] = 'Fullscreen';
$string['gpl'] = 'General Public License v3';
$string['h5p'] = 'H5P';
$string['h5peditor'] = 'H5P Editor';
$string['h5ptitle'] = 'Visit h5p.org to check out more content.';
$string['h5pfilenotfound'] = 'H5P file not found';
$string['h5pinvalidurl'] = 'Invalid H5P content URL.';

View File

@ -0,0 +1,210 @@
@mod @mod_h5pactivity @core_h5p @_file_upload @_switch_iframe
Feature: Inline editing H5P content
In order to edit an existing H5P activity file
As a teacher
I need to see the button and access to the H5P editor
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | 1 | teacher1@example.com |
| teacher2 | Teacher | 2 | teacher2@example.com |
| student1 | Student | 1 | student1@example.com |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| teacher2 | C1 | editingteacher |
| student1 | C1 | student |
And the following "permission overrides" exist:
| capability | permission | role | contextlevel | reference |
| moodle/h5p:updatelibraries | Allow | editingteacher | System | |
@javascript
Scenario: Add H5P activity using link to content bank file
Given the following "contentbank content" exist:
| contextlevel | reference | contenttype | user | contentname | filepath |
| Course | C1 | contenttype_h5p | teacher1 | Greeting card | /h5p/tests/fixtures/greeting-card-887.h5p |
And I log in as "admin"
# Add the navigation block.
And I am on "Course 1" course homepage with editing mode on
And I add the "Navigation" block if not present
# Create an H5P activity with a link to the content-bank file.
And I add a "H5P" to section "1"
And I set the following fields to these values:
| Name | H5P package added as link to content bank |
| Description | Description |
And I click on "Add..." "button" in the "Package file" "form_row"
And I select "Content bank" repository in file picker
And I click on "Greeting card" "file" in repository content area
And I click on "Link to the file" "radio"
And I click on "Select this file" "button"
And I click on "Save and display" "button"
And I switch to "h5p-player" class iframe
And I switch to "h5p-iframe" class iframe
And I should see "Hello world!"
And I switch to the main frame
# Modify the H5P content using the edit button (which opens the H5P editor).
And I follow "Edit H5P content"
And I should see "This content may be in use in other places."
And I switch to "h5p-editor-iframe" class iframe
And I set the field "Greeting text" to "It's a Wonderful Life!"
And I switch to the main frame
And I click on "Save changes" "button"
And I switch to "h5p-player" class iframe
And I switch to "h5p-iframe" class iframe
# Check the H5P content has changed.
And I should not see "Hello world!"
And I should see "It's a Wonderful Life!"
And I switch to the main frame
# Check the H5P has also changed into the content bank.
And I am on "Course 1" course homepage
And I click on "Site pages" "list_item" in the "Navigation" "block"
And I click on "Content bank" "link" in the "Navigation" "block"
And I click on "Greeting card" "link"
And I switch to "h5p-player" class iframe
And I switch to "h5p-iframe" class iframe
And I should not see "Hello world!"
And I should see "It's a Wonderful Life!"
And I switch to the main frame
And I log out
# Check teacher1 can see the Edit button (because she is the author of this file in the content bank).
And I log in as "teacher1"
And I am on "Course 1" course homepage with editing mode on
And I follow "H5P package added as link to content bank"
And I should see "Edit H5P content"
And I log out
# Check teacher2 can't see the Edit button (because the file was created by the teacher1).
And I log in as "teacher2"
And I am on "Course 1" course homepage with editing mode on
When I follow "H5P package added as link to content bank"
Then I should not see "Edit H5P content"
And I log out
# Check student1 can't see the Edit button.
And I log in as "student1"
And I am on "Course 1" course homepage with editing mode on
And I follow "H5P package added as link to content bank"
And I should not see "Edit H5P content"
@javascript
Scenario: Add H5P activity using copy to content bank file
Given the following "contentbank content" exist:
| contextlevel | reference | contenttype | user | contentname | filepath |
| Course | C1 | contenttype_h5p | admin | Greeting card | /h5p/tests/fixtures/greeting-card-887.h5p |
And I log in as "admin"
# Add the navigation block.
And I am on "Course 1" course homepage with editing mode on
And I add the "Navigation" block if not present
# Create an H5P activity with a copy to the content-bank file.
And I add a "H5P" to section "1"
And I set the following fields to these values:
| Name | H5P package added as copy to content bank |
| Description | Description |
And I click on "Add..." "button" in the "Package file" "form_row"
And I select "Content bank" repository in file picker
And I click on "Greeting card" "file" in repository content area
And I click on "Make a copy of the file" "radio"
And I click on "Select this file" "button"
And I click on "Save and display" "button"
And I switch to "h5p-player" class iframe
And I switch to "h5p-iframe" class iframe
And I should see "Hello world!"
And I switch to the main frame
# Modify the H5P content using the edit button (which opens the H5P editor).
And I follow "Edit H5P content"
And I should not see "This content may be in use in other places."
And I switch to "h5p-editor-iframe" class iframe
And I set the field "Greeting text" to "The nightmare before Christmas"
And I switch to the main frame
And I click on "Save changes" "button"
# Check the H5P content has changed.
And I switch to "h5p-player" class iframe
And I switch to "h5p-iframe" class iframe
And I should not see "Hello world!"
And I should see "The nightmare before Christmas"
And I switch to the main frame
# Check the H5P has also changed into the content bank.
And I am on "Course 1" course homepage
And I click on "Site pages" "list_item" in the "Navigation" "block"
And I click on "Content bank" "link" in the "Navigation" "block"
And I click on "Greeting card" "link"
And I switch to "h5p-player" class iframe
And I switch to "h5p-iframe" class iframe
And I should see "Hello world!"
And I should not see "The nightmare before Christmas"
And I switch to the main frame
And I log out
# Check teacher1 can see the Edit button (because the file is a copy).
And I log in as "teacher1"
And I am on "Course 1" course homepage with editing mode on
And I follow "H5P package added as copy to content bank"
And I should see "Edit H5P content"
And I log out
# Check teacher2 can also see the Edit button (because the file is a copy).
And I log in as "teacher2"
And I am on "Course 1" course homepage with editing mode on
When I follow "H5P package added as copy to content bank"
Then I should see "Edit H5P content"
And I log out
# Check student1 can't see the Edit button.
And I log in as "student1"
And I am on "Course 1" course homepage with editing mode on
And I follow "H5P package added as copy to content bank"
And I should not see "Edit H5P content"
@javascript
Scenario: Add H5P activity using private user file
Given I log in as "teacher1"
# Upload the H5P to private user files.
And I follow "Manage private files..."
And I upload "h5p/tests/fixtures/greeting-card-887.h5p" file to "Files" filemanager
And I click on "Save changes" "button"
# Create an H5P activity with a private user file.
And I am on "Course 1" course homepage with editing mode on
And I add a "H5P" to section "1"
And I set the following fields to these values:
| Name | H5P package added as private user file |
| Description | Description |
And I click on "Add..." "button" in the "Package file" "form_row"
And I select "Private files" repository in file picker
And I click on "greeting-card-887.h5p" "file" in repository content area
And I click on "Link to the file" "radio"
And I click on "Select this file" "button"
And I click on "Save and display" "button"
And I switch to "h5p-player" class iframe
And I switch to "h5p-iframe" class iframe
And I should see "Hello world!"
And I switch to the main frame
# Modify the H5P content using the edit button (which opens the H5P editor).
And I follow "Edit H5P content"
And I should see "This content may be in use in other places."
And I switch to "h5p-editor-iframe" class iframe
And I set the field "Greeting text" to "Little women"
And I switch to the main frame
And I click on "Save changes" "button"
# Check the H5P content has changed.
And I switch to "h5p-player" class iframe
And I switch to "h5p-iframe" class iframe
And I should not see "Hello world!"
And I should see "Little women"
And I switch to the main frame
And I log out
# Check admin can't see the Edit button (because the file belongs to teacher1).
And I log in as "admin"
And I am on "Course 1" course homepage with editing mode on
And I follow "H5P package added as private user file"
And I should not see "Edit H5P content"
And I log out
# Check teacher2 can't see the Edit button (because the file belongs to teacher1).
And I log in as "teacher2"
And I am on "Course 1" course homepage with editing mode on
When I follow "H5P package added as private user file"
Then I should not see "Edit H5P content"
And I log out
# Check student1 can't see the Edit button.
And I log in as "student1"
And I am on "Course 1" course homepage with editing mode on
And I follow "H5P package added as private user file"
And I should not see "Edit H5P content"

View File

@ -98,6 +98,6 @@ if (!$manager->is_tracking_enabled()) {
echo $OUTPUT->notification($message, \core\output\notification::NOTIFY_WARNING);
}
echo player::display($fileurl, $config, true, 'mod_h5pactivity');
echo player::display($fileurl, $config, true, 'mod_h5pactivity', true);
echo $OUTPUT->footer();