mirror of
https://github.com/moodle/moodle.git
synced 2025-04-14 13:02:07 +02:00
MDL-74129 h5p: Preserve metadata information
The metadata information was not restored when an H5P file was uploaded (it was saved when it was edited directly from the Content bank, but the original information in the H5P file was lost). This patch includes all the metadata fields and its values in the original H5P file to preserve this information too.
This commit is contained in:
parent
8ad9114050
commit
8974392cfa
@ -910,6 +910,13 @@ class framework implements H5PFrameworkInterface {
|
||||
$params->title = $content['title'];
|
||||
$content['params'] = json_encode($params);
|
||||
}
|
||||
// Add metadata to 'params'.
|
||||
if (!empty($content['metadata'])) {
|
||||
$params = json_decode($content['params']);
|
||||
$params->metadata = $content['metadata'];
|
||||
$content['params'] = json_encode($params);
|
||||
}
|
||||
|
||||
$data = [
|
||||
'jsoncontent' => $content['params'],
|
||||
'displayoptions' => $content['disable'],
|
||||
|
@ -66,6 +66,32 @@ class helper {
|
||||
if (!empty($h5pvalidator->h5pC->mainJsonData['title'])) {
|
||||
$content['title'] = $h5pvalidator->h5pC->mainJsonData['title'];
|
||||
}
|
||||
|
||||
// If exists, add the metadata from 'h5p.json' to avoid loosing this information.
|
||||
$data = $h5pvalidator->h5pC->mainJsonData;
|
||||
if (!empty($data)) {
|
||||
// The metadata fields are defined in 'joubel/core/h5p-metadata.class.php'.
|
||||
$metadatafields = [
|
||||
'title',
|
||||
'a11yTitle',
|
||||
'changes',
|
||||
'authors',
|
||||
'source',
|
||||
'license',
|
||||
'licenseVersion',
|
||||
'licenseExtras',
|
||||
'authorComments',
|
||||
'yearFrom',
|
||||
'yearTo',
|
||||
'defaultLanguage',
|
||||
];
|
||||
$content['metadata'] = array_reduce($metadatafields, function ($array, $field) use ($data) {
|
||||
if (array_key_exists($field, $data)) {
|
||||
$array[$field] = $data[$field];
|
||||
}
|
||||
return $array;
|
||||
}, []);
|
||||
}
|
||||
$h5pstorage->savePackage($content, null, $skipcontent, $options);
|
||||
|
||||
return $h5pstorage->contentId;
|
||||
|
BIN
h5p/tests/fixtures/guess-the-answer.h5p
vendored
BIN
h5p/tests/fixtures/guess-the-answer.h5p
vendored
Binary file not shown.
@ -20,6 +20,8 @@ use core_collator;
|
||||
use Moodle\H5PCore;
|
||||
use Moodle\H5PDisplayOptionBehaviour;
|
||||
|
||||
// phpcs:disable moodle.NamingConventions.ValidFunctionName.LowercaseMethod
|
||||
|
||||
/**
|
||||
*
|
||||
* Test class covering the H5PFrameworkInterface interface implementation.
|
||||
@ -28,6 +30,7 @@ use Moodle\H5PDisplayOptionBehaviour;
|
||||
* @category test
|
||||
* @copyright 2019 Mihail Geshoski <mihail@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @covers \core_h5p\framework
|
||||
* @runTestsInSeparateProcesses
|
||||
*/
|
||||
class framework_test extends \advanced_testcase {
|
||||
@ -1090,6 +1093,55 @@ class framework_test extends \advanced_testcase {
|
||||
$this->assertEquals($content['disable'], $h5pcontent->displayoptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the behaviour of updateContent() with metadata.
|
||||
*
|
||||
* @covers ::updateContent
|
||||
*/
|
||||
public function test_updateContent_withmetadata(): void {
|
||||
global $DB;
|
||||
|
||||
$this->resetAfterTest();
|
||||
|
||||
/** @var \core_h5p_generator $generator */
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
|
||||
|
||||
// Create a library record.
|
||||
$lib = $generator->create_library_record('TestLibrary', 'Test', 1, 1, 2);
|
||||
|
||||
// Create an h5p content with 'TestLibrary' as it's main library.
|
||||
$contentid = $generator->create_h5p_record($lib->id);
|
||||
|
||||
$params = ['param2' => 'Test2'];
|
||||
$metadata = [
|
||||
'license' => 'CC BY',
|
||||
'licenseVersion' => '4.0',
|
||||
'yearFrom' => 2000,
|
||||
'yearTo' => 2023,
|
||||
'defaultLanguage' => 'ca',
|
||||
];
|
||||
$content = [
|
||||
'id' => $contentid,
|
||||
'params' => json_encode($params),
|
||||
'library' => [
|
||||
'libraryId' => $lib->id,
|
||||
],
|
||||
'disable' => 8,
|
||||
'metadata' => $metadata,
|
||||
];
|
||||
|
||||
// Update the h5p content.
|
||||
$this->framework->updateContent($content);
|
||||
|
||||
$h5pcontent = $DB->get_record('h5p', ['id' => $contentid]);
|
||||
|
||||
// Make sure the h5p content was properly updated.
|
||||
$this->assertNotEmpty($h5pcontent);
|
||||
$this->assertEquals(json_encode(array_merge($params, ['metadata' => $metadata])), $h5pcontent->jsoncontent);
|
||||
$this->assertEquals($content['library']['libraryId'], $h5pcontent->mainlibraryid);
|
||||
$this->assertEquals($content['disable'], $h5pcontent->displayoptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the behaviour of saveLibraryDependencies().
|
||||
*/
|
||||
|
@ -200,6 +200,57 @@ class helper_test extends \advanced_testcase {
|
||||
$this->assertStringContainsString('Hello world!', $h5p->jsoncontent);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test the behaviour of save_h5p() when the H5P file contains metadata.
|
||||
*
|
||||
* @runInSeparateProcess
|
||||
* @covers ::save_h5p
|
||||
*/
|
||||
public function test_save_h5p_metadata(): void {
|
||||
global $DB;
|
||||
|
||||
$this->resetAfterTest();
|
||||
$factory = new \core_h5p\factory();
|
||||
|
||||
// Create a user.
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
$this->setUser($user);
|
||||
|
||||
// This is a valid .H5P file.
|
||||
$path = __DIR__ . '/fixtures/guess-the-answer.h5p';
|
||||
$file = helper::create_fake_stored_file_from_path($path, (int)$user->id);
|
||||
$factory->get_framework()->set_file($file);
|
||||
|
||||
$config = (object)[
|
||||
'frame' => 1,
|
||||
'export' => 1,
|
||||
'embed' => 0,
|
||||
'copyright' => 1,
|
||||
];
|
||||
// The required libraries exist in the system before saving the .h5p file.
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
|
||||
$lib = $generator->create_library_record('H5P.GuessTheAnswer', 'Guess the Answer', 1, 5);
|
||||
$generator->create_library_record('H5P.Image', 'Image', 1, 1);
|
||||
$generator->create_library_record('FontAwesome', 'Font Awesome', 4, 5);
|
||||
$h5pid = helper::save_h5p($factory, $file, $config);
|
||||
$this->assertNotEmpty($h5pid);
|
||||
|
||||
// No errors are raised.
|
||||
$errors = $factory->get_framework()->getMessages('error');
|
||||
$this->assertCount(0, $errors);
|
||||
|
||||
// And the content in the .h5p file has been saved as expected.
|
||||
$h5p = $DB->get_record('h5p', ['id' => $h5pid]);
|
||||
$this->assertEquals($lib->id, $h5p->mainlibraryid);
|
||||
$this->assertEquals(helper::get_display_options($factory->get_core(), $config), $h5p->displayoptions);
|
||||
$this->assertStringContainsString('Which fruit is this?', $h5p->jsoncontent);
|
||||
// Metadata has been also saved.
|
||||
$this->assertStringContainsString('This is licence extras information added for testing purposes.', $h5p->jsoncontent);
|
||||
$this->assertStringContainsString('H5P Author', $h5p->jsoncontent);
|
||||
$this->assertStringContainsString('Add metadata information', $h5p->jsoncontent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the behaviour of save_h5p() when the .h5p file is invalid.
|
||||
* @runInSeparateProcess
|
||||
|
@ -21,7 +21,7 @@ Feature: Add H5P activity
|
||||
And I am on "Course 1" course homepage with editing mode on
|
||||
|
||||
@javascript
|
||||
Scenario: Add a h5pactivity activity to a course
|
||||
Scenario: Add an h5pactivity to a course
|
||||
Given the following "activity" exists:
|
||||
| activity | h5pactivity |
|
||||
| course | C1 |
|
||||
@ -36,10 +36,9 @@ Feature: Add H5P activity
|
||||
And I should not see "Reuse"
|
||||
And I should not see "Rights of use"
|
||||
And I should not see "Embed"
|
||||
And I switch to the main frame
|
||||
|
||||
@javascript
|
||||
Scenario: Add a h5pactivity activity with download
|
||||
Scenario: Add an h5pactivity with download display option
|
||||
Given the following "activity" exists:
|
||||
| activity | h5pactivity |
|
||||
| course | C1 |
|
||||
@ -47,16 +46,14 @@ Feature: Add H5P activity
|
||||
| displayoptions | 12 |
|
||||
| packagefilepath | h5p/tests/fixtures/ipsums.h5p |
|
||||
When I am on the "Awesome H5P package" "h5pactivity activity" page
|
||||
And I wait until the page is ready
|
||||
Then I switch to "h5p-player" class iframe
|
||||
And I switch to "h5p-iframe" class iframe
|
||||
And I should see "Reuse"
|
||||
And "Reuse" "text" should exist in the ".h5p-actions" "css_element"
|
||||
And I should not see "Rights of use"
|
||||
And I should not see "Embed"
|
||||
And I switch to the main frame
|
||||
|
||||
@javascript
|
||||
Scenario: Add a h5pactivity activity with embed
|
||||
Scenario: Add an h5pactivity with embed display option
|
||||
Given the following "activity" exists:
|
||||
| activity | h5pactivity |
|
||||
| course | C1 |
|
||||
@ -64,33 +61,38 @@ Feature: Add H5P activity
|
||||
| displayoptions | 10 |
|
||||
| packagefilepath | h5p/tests/fixtures/ipsums.h5p |
|
||||
When I am on the "Awesome H5P package" "h5pactivity activity" page
|
||||
And I wait until the page is ready
|
||||
Then I switch to "h5p-player" class iframe
|
||||
And I switch to "h5p-iframe" class iframe
|
||||
And I should not see "Reuse"
|
||||
And "Reuse" "text" should not exist in the ".h5p-actions" "css_element"
|
||||
And I should not see "Rights of use"
|
||||
And I should see "Embed"
|
||||
And I switch to the main frame
|
||||
|
||||
@javascript
|
||||
Scenario: Add a h5pactivity activity with copyright
|
||||
Scenario: Add an h5pactivity with copyright display option using a content with copyright
|
||||
Given the following "activity" exists:
|
||||
| activity | h5pactivity |
|
||||
| course | C1 |
|
||||
| name | Awesome H5P package |
|
||||
| displayoptions | 6 |
|
||||
| packagefilepath | h5p/tests/fixtures/guess-the-answer.h5p |
|
||||
And I change window size to "large"
|
||||
When I am on the "Awesome H5P package" "h5pactivity activity" page
|
||||
And I wait until the page is ready
|
||||
Then I switch to "h5p-player" class iframe
|
||||
And I switch to "h5p-iframe" class iframe
|
||||
And I should not see "Reuse"
|
||||
And "Reuse" "text" should not exist in the ".h5p-actions" "css_element"
|
||||
And I should see "Rights of use"
|
||||
And I should not see "Embed"
|
||||
And I switch to the main frame
|
||||
And I click on "Rights of use" "button" in the ".h5p-actions" "css_element"
|
||||
And I should see "Fruits"
|
||||
And I should see "Attribution (CC BY) 4.0 International (CC BY 4.0)"
|
||||
And I should see "H5P Author"
|
||||
And I should see "https://h5p.org (Originator)"
|
||||
And I should see "2000-2023"
|
||||
And I should see "This is licence extras information added for testing purposes."
|
||||
And I should see "Add metadata information, Another user, 01-11-23"
|
||||
|
||||
@javascript
|
||||
Scenario: Add a h5pactivity activity with copyright in a content without copyright
|
||||
Scenario: Add an h5pactivity with copyright display option using a content without copyright
|
||||
Given the following "activity" exists:
|
||||
| activity | h5pactivity |
|
||||
| course | C1 |
|
||||
@ -98,16 +100,14 @@ Feature: Add H5P activity
|
||||
| displayoptions | 6 |
|
||||
| packagefilepath | h5p/tests/fixtures/ipsums.h5p |
|
||||
When I am on the "Awesome H5P package" "h5pactivity activity" page
|
||||
And I wait until the page is ready
|
||||
Then I switch to "h5p-player" class iframe
|
||||
And I switch to "h5p-iframe" class iframe
|
||||
And I should not see "Reuse"
|
||||
And "Reuse" "text" should not exist in the ".h5p-actions" "css_element"
|
||||
And I should not see "Rights of use"
|
||||
And I should not see "Embed"
|
||||
And I switch to the main frame
|
||||
|
||||
@javascript
|
||||
Scenario: Add a h5pactivity activity to a course with all display options enabled
|
||||
Scenario: Add an h5pactivity with all display options enabled
|
||||
Given the following "activity" exists:
|
||||
| activity | h5pactivity |
|
||||
| course | C1 |
|
||||
@ -115,10 +115,8 @@ Feature: Add H5P activity
|
||||
| displayoptions | 0 |
|
||||
| packagefilepath | h5p/tests/fixtures/guess-the-answer.h5p |
|
||||
When I am on the "Awesome H5P package" "h5pactivity activity" page
|
||||
And I wait until the page is ready
|
||||
Then I switch to "h5p-player" class iframe
|
||||
And I switch to "h5p-iframe" class iframe
|
||||
And I should see "Reuse"
|
||||
And "Reuse" "text" should exist in the ".h5p-actions" "css_element"
|
||||
And I should see "Rights of use"
|
||||
And I should see "Embed"
|
||||
And I switch to the main frame
|
||||
|
Loading…
x
Reference in New Issue
Block a user