mirror of
https://github.com/moodle/moodle.git
synced 2025-04-19 07:25:30 +02:00
Merge branch 'MDL-68448-master' of git://github.com/cescobedo/moodle
This commit is contained in:
commit
51b3feb2e9
@ -502,4 +502,43 @@ class api {
|
||||
|
||||
return ($h5p) ? $h5p : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the H5P export information file when the file has been deployed.
|
||||
* Otherwise, return null if H5P file:
|
||||
* i) has not been deployed.
|
||||
* ii) has changed the content.
|
||||
*
|
||||
* The information returned will be:
|
||||
* - filename, filepath, mimetype, filesize, timemodified and fileurl.
|
||||
*
|
||||
* @param int $contextid ContextId of the H5P activity.
|
||||
* @param factory $factory The \core_h5p\factory object.
|
||||
* @param string $component component
|
||||
* @param string $filearea file area
|
||||
* @return array|null Return file info otherwise null.
|
||||
*/
|
||||
public static function get_export_info_from_context_id(int $contextid,
|
||||
factory $factory,
|
||||
string $component,
|
||||
string $filearea): ?array {
|
||||
|
||||
$core = $factory->get_core();
|
||||
$fs = get_file_storage();
|
||||
$files = $fs->get_area_files($contextid, $component, $filearea, 0, 'id', false);
|
||||
$file = reset($files);
|
||||
|
||||
if ($h5p = self::get_content_from_pathnamehash($file->get_pathnamehash())) {
|
||||
if ($h5p->contenthash == $file->get_contenthash()) {
|
||||
$content = $core->loadContent($h5p->id);
|
||||
$slug = $content['slug'] ? $content['slug'] . '-' : '';
|
||||
$filename = "{$slug}{$content['id']}.h5p";
|
||||
$deployedfile = helper::get_export_info($filename, null, $factory);
|
||||
|
||||
return $deployedfile;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -429,4 +429,50 @@ class helper {
|
||||
|
||||
return $strings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the information related to the H5P export file.
|
||||
* The information returned will be:
|
||||
* - filename, filepath, mimetype, filesize, timemodified and fileurl.
|
||||
*
|
||||
* @param string $exportfilename The H5P export filename (with slug).
|
||||
* @param \moodle_url $url The URL of the exported file.
|
||||
* @param factory $factory The \core_h5p\factory object
|
||||
* @return array|null The information export file otherwise null.
|
||||
*/
|
||||
public static function get_export_info(string $exportfilename, \moodle_url $url = null, ?factory $factory = null): ?array {
|
||||
|
||||
if (!$factory) {
|
||||
$factory = new factory();
|
||||
}
|
||||
$core = $factory->get_core();
|
||||
|
||||
// Get export file.
|
||||
if (!$fileh5p = $core->fs->get_export_file($exportfilename)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Build the export info array.
|
||||
$file = [];
|
||||
$file['filename'] = $fileh5p->get_filename();
|
||||
$file['filepath'] = $fileh5p->get_filepath();
|
||||
$file['mimetype'] = $fileh5p->get_mimetype();
|
||||
$file['filesize'] = $fileh5p->get_filesize();
|
||||
$file['timemodified'] = $fileh5p->get_timemodified();
|
||||
|
||||
if (!$url) {
|
||||
$url = \moodle_url::make_webservice_pluginfile_url(
|
||||
$fileh5p->get_contextid(),
|
||||
$fileh5p->get_component(),
|
||||
$fileh5p->get_filearea(),
|
||||
'',
|
||||
'',
|
||||
$fileh5p->get_filename()
|
||||
);
|
||||
}
|
||||
|
||||
$file['fileurl'] = $url->out(false);
|
||||
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
@ -456,7 +456,7 @@ class player {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the export file for Mobile App.
|
||||
* Return the info export file for Mobile App.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@ -467,23 +467,8 @@ class player {
|
||||
$path = $exporturl->out_as_local_url();
|
||||
$parts = explode('/', $path);
|
||||
$filename = array_pop($parts);
|
||||
// Get the the export file.
|
||||
$systemcontext = \context_system::instance();
|
||||
$fs = get_file_storage();
|
||||
$fileh5p = $fs->get_file($systemcontext->id,
|
||||
\core_h5p\file_storage::COMPONENT,
|
||||
\core_h5p\file_storage::EXPORT_FILEAREA,
|
||||
0,
|
||||
'/',
|
||||
$filename);
|
||||
// Get the options that the Mobile App needs.
|
||||
$file = [];
|
||||
$file['filename'] = $fileh5p->get_filename();
|
||||
$file['filepath'] = $fileh5p->get_filepath();
|
||||
$file['mimetype'] = $fileh5p->get_mimetype();
|
||||
$file['filesize'] = $fileh5p->get_filesize();
|
||||
$file['timemodified'] = $fileh5p->get_timemodified();
|
||||
$file['fileurl'] = $exporturl->out(false);
|
||||
// Get the required info from the export file to be able to get the export file by third apps.
|
||||
$file = helper::get_export_info($filename, $exporturl);
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
@ -451,4 +451,56 @@ class api_testcase extends \advanced_testcase {
|
||||
api::delete_content_from_pluginfile_url($url->out(), $factory);
|
||||
$this->assertEquals(0, $DB->count_records('h5p'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the behaviour of get_export_info_from_context_id().
|
||||
*/
|
||||
public function test_get_export_info_from_context_id(): void {
|
||||
global $DB;
|
||||
|
||||
$this->setRunTestInSeparateProcess(true);
|
||||
$this->resetAfterTest();
|
||||
$factory = new factory();
|
||||
|
||||
// Create the H5P data.
|
||||
$filename = 'find-the-words.h5p';
|
||||
$syscontext = \context_system::instance();
|
||||
|
||||
// Test scenario 1: H5P exists and deployed.
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
|
||||
$fakeexportfile = $generator->create_export_file($filename,
|
||||
$syscontext->id,
|
||||
\core_h5p\file_storage::COMPONENT,
|
||||
\core_h5p\file_storage::EXPORT_FILEAREA);
|
||||
|
||||
$exportfile = api::get_export_info_from_context_id($syscontext->id,
|
||||
$factory,
|
||||
\core_h5p\file_storage::COMPONENT,
|
||||
\core_h5p\file_storage::EXPORT_FILEAREA);
|
||||
$this->assertEquals($fakeexportfile['filename'], $exportfile['filename']);
|
||||
$this->assertEquals($fakeexportfile['filepath'], $exportfile['filepath']);
|
||||
$this->assertEquals($fakeexportfile['filesize'], $exportfile['filesize']);
|
||||
$this->assertEquals($fakeexportfile['timemodified'], $exportfile['timemodified']);
|
||||
$this->assertEquals($fakeexportfile['fileurl'], $exportfile['fileurl']);
|
||||
|
||||
// Test scenario 2: H5P exist, deployed but the content has changed.
|
||||
// We need to change the contenthash to simulate the H5P file was changed.
|
||||
$h5pfile = $DB->get_record('h5p', []);
|
||||
$h5pfile->contenthash = sha1('testedit');
|
||||
$DB->update_record('h5p', $h5pfile);
|
||||
$exportfile = api::get_export_info_from_context_id($syscontext->id,
|
||||
$factory,
|
||||
\core_h5p\file_storage::COMPONENT,
|
||||
\core_h5p\file_storage::EXPORT_FILEAREA);
|
||||
$this->assertNull($exportfile);
|
||||
|
||||
// Tests scenario 3: H5P is not deployed.
|
||||
// We need to delete the H5P record to simulate the H5P was not deployed.
|
||||
$DB->delete_records('h5p', ['id' => $h5pfile->id]);
|
||||
$exportfile = api::get_export_info_from_context_id($syscontext->id,
|
||||
$factory,
|
||||
\core_h5p\file_storage::COMPONENT,
|
||||
\core_h5p\file_storage::EXPORT_FILEAREA);
|
||||
$this->assertNull($exportfile);
|
||||
}
|
||||
}
|
||||
|
@ -55,56 +55,45 @@ class core_h5p_external_testcase extends externallib_advanced_testcase {
|
||||
* test_get_trusted_h5p_file description
|
||||
*/
|
||||
public function test_get_trusted_h5p_file() {
|
||||
global $DB;
|
||||
$this->resetAfterTest(true);
|
||||
$this->setAdminUser();
|
||||
|
||||
// This is a valid .H5P file.
|
||||
$filename = 'find-the-words.h5p';
|
||||
$path = __DIR__ . '/fixtures/'.$filename;
|
||||
$syscontext = \context_system::instance();
|
||||
$filerecord = [
|
||||
'contextid' => $syscontext->id,
|
||||
'component' => \core_h5p\file_storage::COMPONENT,
|
||||
'filearea' => 'unittest',
|
||||
'itemid' => 0,
|
||||
'filepath' => '/',
|
||||
'filename' => $filename,
|
||||
];
|
||||
// Load the h5p file into DB.
|
||||
$fs = get_file_storage();
|
||||
$file = $fs->create_file_from_pathname($filerecord, $path);
|
||||
|
||||
// Create a fake export H5P file with normal pluginfile call.
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
|
||||
$deployedfile = $generator->create_export_file($filename,
|
||||
$syscontext->id,
|
||||
\core_h5p\file_storage::COMPONENT,
|
||||
\core_h5p\file_storage::EXPORT_FILEAREA,
|
||||
$generator::PLUGINFILE);
|
||||
|
||||
// Make the URL to pass to the WS.
|
||||
$url = \moodle_url::make_pluginfile_url(
|
||||
$syscontext->id,
|
||||
\core_h5p\file_storage::COMPONENT,
|
||||
'unittest',
|
||||
\core_h5p\file_storage::EXPORT_FILEAREA,
|
||||
0,
|
||||
'/',
|
||||
$filename
|
||||
);
|
||||
|
||||
// Call the WS.
|
||||
$result = external::get_trusted_h5p_file($url->out(), 0, 0, 0, 0);
|
||||
$result = external::get_trusted_h5p_file($url->out(false), 0, 0, 0, 0);
|
||||
$result = external_api::clean_returnvalue(external::get_trusted_h5p_file_returns(), $result);
|
||||
// Expected result: Just 1 record on files and none on warnings.
|
||||
$this->assertCount(1, $result['files']);
|
||||
$this->assertCount(0, $result['warnings']);
|
||||
// Get the export file in the DB to compare with the ws's results.
|
||||
$fileh5p = $this->get_export_file($filename, $file->get_pathnamehash());
|
||||
$fileh5purl = \moodle_url::make_pluginfile_url(
|
||||
$syscontext->id,
|
||||
\core_h5p\file_storage::COMPONENT,
|
||||
\core_h5p\file_storage::EXPORT_FILEAREA,
|
||||
'',
|
||||
'',
|
||||
$fileh5p->get_filename()
|
||||
);
|
||||
$this->assertEquals($fileh5p->get_filepath(), $result['files'][0]['filepath']);
|
||||
$this->assertEquals($fileh5p->get_mimetype(), $result['files'][0]['mimetype']);
|
||||
$this->assertEquals($fileh5p->get_filesize(), $result['files'][0]['filesize']);
|
||||
$this->assertEquals($fileh5p->get_timemodified(), $result['files'][0]['timemodified']);
|
||||
$this->assertEquals($fileh5p->get_filename(), $result['files'][0]['filename']);
|
||||
$this->assertEquals($fileh5purl->out(), $result['files'][0]['fileurl']);
|
||||
|
||||
// Check info export file to compare with the ws's results.
|
||||
$this->assertEquals($deployedfile['filepath'], $result['files'][0]['filepath']);
|
||||
$this->assertEquals($deployedfile['mimetype'], $result['files'][0]['mimetype']);
|
||||
$this->assertEquals($deployedfile['filesize'], $result['files'][0]['filesize']);
|
||||
$this->assertEquals($deployedfile['timemodified'], $result['files'][0]['timemodified']);
|
||||
$this->assertEquals($deployedfile['filename'], $result['files'][0]['filename']);
|
||||
$this->assertEquals($deployedfile['fileurl'], $result['files'][0]['fileurl']);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -170,56 +159,41 @@ class core_h5p_external_testcase extends externallib_advanced_testcase {
|
||||
* using webservice/pluginfile.php as url param.
|
||||
*/
|
||||
public function test_allow_webservice_pluginfile_in_url_param() {
|
||||
global $DB;
|
||||
$this->resetAfterTest(true);
|
||||
$this->setAdminUser();
|
||||
|
||||
// This is a valid .H5P file.
|
||||
$filename = 'find-the-words.h5p';
|
||||
$path = __DIR__ . '/fixtures/'.$filename;
|
||||
$syscontext = \context_system::instance();
|
||||
$filerecord = [
|
||||
'contextid' => $syscontext->id,
|
||||
'component' => \core_h5p\file_storage::COMPONENT,
|
||||
'filearea' => 'unittest',
|
||||
'itemid' => 0,
|
||||
'filepath' => '/',
|
||||
'filename' => $filename,
|
||||
];
|
||||
// Load the h5p file into DB.
|
||||
$fs = get_file_storage();
|
||||
$file = $fs->create_file_from_pathname($filerecord, $path);
|
||||
|
||||
// Create a fake export H5P file with webservice call.
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
|
||||
$deployedfile = $generator->create_export_file($filename,
|
||||
$syscontext->id,
|
||||
\core_h5p\file_storage::COMPONENT,
|
||||
\core_h5p\file_storage::EXPORT_FILEAREA);
|
||||
|
||||
// Make the URL to pass to the WS.
|
||||
$url = \moodle_url::make_webservice_pluginfile_url(
|
||||
$syscontext->id,
|
||||
\core_h5p\file_storage::COMPONENT,
|
||||
'unittest',
|
||||
\core_h5p\file_storage::EXPORT_FILEAREA,
|
||||
0,
|
||||
'/',
|
||||
$filename
|
||||
);
|
||||
|
||||
// Call the WS.
|
||||
$result = external::get_trusted_h5p_file($url->out(), 0, 0, 0, 0);
|
||||
$result = external_api::clean_returnvalue(external::get_trusted_h5p_file_returns(), $result);
|
||||
// Expected result: Just 1 record on files and none on warnings.
|
||||
$this->assertCount(1, $result['files']);
|
||||
$this->assertCount(0, $result['warnings']);
|
||||
// Get the export file in the DB to compare with the ws's results.
|
||||
$fileh5p = $this->get_export_file($filename, $file->get_pathnamehash());
|
||||
$fileh5purl = \moodle_url::make_webservice_pluginfile_url(
|
||||
$syscontext->id,
|
||||
\core_h5p\file_storage::COMPONENT,
|
||||
\core_h5p\file_storage::EXPORT_FILEAREA,
|
||||
'',
|
||||
'',
|
||||
$fileh5p->get_filename()
|
||||
);
|
||||
$this->assertEquals($fileh5p->get_filepath(), $result['files'][0]['filepath']);
|
||||
$this->assertEquals($fileh5p->get_mimetype(), $result['files'][0]['mimetype']);
|
||||
$this->assertEquals($fileh5p->get_filesize(), $result['files'][0]['filesize']);
|
||||
$this->assertEquals($fileh5p->get_timemodified(), $result['files'][0]['timemodified']);
|
||||
$this->assertEquals($fileh5p->get_filename(), $result['files'][0]['filename']);
|
||||
$this->assertEquals($fileh5purl->out(), $result['files'][0]['fileurl']);
|
||||
|
||||
// Check info export file to compare with the ws's results.
|
||||
$this->assertEquals($deployedfile['filepath'], $result['files'][0]['filepath']);
|
||||
$this->assertEquals($deployedfile['mimetype'], $result['files'][0]['mimetype']);
|
||||
$this->assertEquals($deployedfile['filesize'], $result['files'][0]['filesize']);
|
||||
$this->assertEquals($deployedfile['timemodified'], $result['files'][0]['timemodified']);
|
||||
$this->assertEquals($deployedfile['filename'], $result['files'][0]['filename']);
|
||||
$this->assertEquals($deployedfile['fileurl'], $result['files'][0]['fileurl']);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -227,83 +201,46 @@ class core_h5p_external_testcase extends externallib_advanced_testcase {
|
||||
* using tokenpluginfile.php as url param.
|
||||
*/
|
||||
public function test_allow_tokenluginfile_in_url_param() {
|
||||
global $DB;
|
||||
$this->resetAfterTest(true);
|
||||
$this->setAdminUser();
|
||||
|
||||
// This is a valid .H5P file.
|
||||
$filename = 'find-the-words.h5p';
|
||||
$path = __DIR__ . '/fixtures/'.$filename;
|
||||
$syscontext = \context_system::instance();
|
||||
$filerecord = [
|
||||
'contextid' => $syscontext->id,
|
||||
'component' => \core_h5p\file_storage::COMPONENT,
|
||||
'filearea' => 'unittest',
|
||||
'itemid' => 0,
|
||||
'filepath' => '/',
|
||||
'filename' => $filename,
|
||||
];
|
||||
// Load the h5p file into DB.
|
||||
$fs = get_file_storage();
|
||||
$file = $fs->create_file_from_pathname($filerecord, $path);
|
||||
|
||||
// Create a fake export H5P file with tokenfile call.
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
|
||||
$deployedfile = $generator->create_export_file($filename,
|
||||
$syscontext->id,
|
||||
\core_h5p\file_storage::COMPONENT,
|
||||
\core_h5p\file_storage::EXPORT_FILEAREA,
|
||||
$generator::TOKENPLUGINFILE);
|
||||
|
||||
// Make the URL to pass to the WS.
|
||||
$url = \moodle_url::make_pluginfile_url(
|
||||
$syscontext->id,
|
||||
\core_h5p\file_storage::COMPONENT,
|
||||
'unittest',
|
||||
\core_h5p\file_storage::EXPORT_FILEAREA,
|
||||
0,
|
||||
'/',
|
||||
$filename,
|
||||
false,
|
||||
true
|
||||
);
|
||||
|
||||
// Call the WS.
|
||||
$result = external::get_trusted_h5p_file($url->out(), 0, 0, 0, 0);
|
||||
$result = external::get_trusted_h5p_file($url->out(false), 0, 0, 0, 0);
|
||||
$result = external_api::clean_returnvalue(external::get_trusted_h5p_file_returns(), $result);
|
||||
// Expected result: Just 1 record on files and none on warnings.
|
||||
$this->assertCount(1, $result['files']);
|
||||
$this->assertCount(0, $result['warnings']);
|
||||
// Get the export file in the DB to compare with the ws's results.
|
||||
$fileh5p = $this->get_export_file($filename, $file->get_pathnamehash());
|
||||
$fileh5purl = \moodle_url::make_pluginfile_url(
|
||||
$syscontext->id,
|
||||
\core_h5p\file_storage::COMPONENT,
|
||||
\core_h5p\file_storage::EXPORT_FILEAREA,
|
||||
'',
|
||||
'',
|
||||
$fileh5p->get_filename(),
|
||||
false,
|
||||
true
|
||||
);
|
||||
$this->assertEquals($fileh5p->get_filepath(), $result['files'][0]['filepath']);
|
||||
$this->assertEquals($fileh5p->get_mimetype(), $result['files'][0]['mimetype']);
|
||||
$this->assertEquals($fileh5p->get_filesize(), $result['files'][0]['filesize']);
|
||||
$this->assertEquals($fileh5p->get_timemodified(), $result['files'][0]['timemodified']);
|
||||
$this->assertEquals($fileh5p->get_filename(), $result['files'][0]['filename']);
|
||||
$this->assertEquals($fileh5purl->out(), $result['files'][0]['fileurl']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the H5P export file.
|
||||
*
|
||||
* @param string $filename
|
||||
* @param string $pathnamehash
|
||||
* @return stored_file
|
||||
*/
|
||||
protected function get_export_file($filename, $pathnamehash) {
|
||||
global $DB;
|
||||
|
||||
// Simulate the filenameexport using slug as H5P does.
|
||||
$id = $DB->get_field('h5p', 'id', ['pathnamehash' => $pathnamehash]);
|
||||
$filenameexport = basename($filename, '.h5p').'-'.$id.'-'.$id.'.h5p';
|
||||
$syscontext = \context_system::instance();
|
||||
$fs = get_file_storage();
|
||||
$fileh5p = $fs->get_file($syscontext->id,
|
||||
\core_h5p\file_storage::COMPONENT,
|
||||
\core_h5p\file_storage::EXPORT_FILEAREA,
|
||||
0,
|
||||
'/',
|
||||
$filenameexport);
|
||||
return $fileh5p;
|
||||
// Check info export file to compare with the ws's results.
|
||||
$this->assertEquals($deployedfile['filepath'], $result['files'][0]['filepath']);
|
||||
$this->assertEquals($deployedfile['mimetype'], $result['files'][0]['mimetype']);
|
||||
$this->assertEquals($deployedfile['filesize'], $result['files'][0]['filesize']);
|
||||
$this->assertEquals($deployedfile['timemodified'], $result['files'][0]['timemodified']);
|
||||
$this->assertEquals($deployedfile['filename'], $result['files'][0]['filename']);
|
||||
$this->assertEquals($deployedfile['fileurl'], $result['files'][0]['fileurl']);
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,8 @@
|
||||
|
||||
use core_h5p\local\library\autoloader;
|
||||
use core_h5p\core;
|
||||
use core_h5p\player;
|
||||
use core_h5p\factory;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@ -38,6 +40,13 @@ defined('MOODLE_INTERNAL') || die();
|
||||
*/
|
||||
class core_h5p_generator extends \component_generator_base {
|
||||
|
||||
/** Url pointing to webservice plugin file. */
|
||||
public const WSPLUGINFILE = 0;
|
||||
/** Url pointing to token plugin file. */
|
||||
public const TOKENPLUGINFILE = 1;
|
||||
/** Url pointing to plugin file. */
|
||||
public const PLUGINFILE = 2;
|
||||
|
||||
/**
|
||||
* Convenience function to create a file.
|
||||
*
|
||||
@ -428,4 +437,121 @@ class core_h5p_generator extends \component_generator_base {
|
||||
$fs = new file_storage();
|
||||
return $fs->create_file_from_string($filerecord, $content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a fake export H5P deployed file.
|
||||
*
|
||||
* @param string $filename Name of the H5P file to deploy.
|
||||
* @param int $contextid Context id of the H5P activity.
|
||||
* @param string $component component.
|
||||
* @param string $filearea file area.
|
||||
* @param int $typeurl Type of url to create the export url plugin file.
|
||||
* @return array return deployed file information.
|
||||
*/
|
||||
public function create_export_file(string $filename, int $contextid,
|
||||
string $component,
|
||||
string $filearea,
|
||||
int $typeurl = self::WSPLUGINFILE): array {
|
||||
global $CFG;
|
||||
|
||||
// We need the autoloader for H5P player.
|
||||
autoloader::register();
|
||||
|
||||
$path = $CFG->dirroot.'/h5p/tests/fixtures/'.$filename;
|
||||
$filerecord = [
|
||||
'contextid' => $contextid,
|
||||
'component' => $component,
|
||||
'filearea' => $filearea,
|
||||
'itemid' => 0,
|
||||
'filepath' => '/',
|
||||
'filename' => $filename,
|
||||
];
|
||||
// Load the h5p file into DB.
|
||||
$fs = get_file_storage();
|
||||
if (!$fs->get_file($contextid, $component, $filearea, $filerecord['itemid'], $filerecord['filepath'], $filename)) {
|
||||
$fs->create_file_from_pathname($filerecord, $path);
|
||||
}
|
||||
|
||||
// Make the URL to pass to the player.
|
||||
if ($typeurl == self::WSPLUGINFILE) {
|
||||
$url = \moodle_url::make_webservice_pluginfile_url(
|
||||
$filerecord['contextid'],
|
||||
$filerecord['component'],
|
||||
$filerecord['filearea'],
|
||||
$filerecord['itemid'],
|
||||
$filerecord['filepath'],
|
||||
$filerecord['filename']
|
||||
);
|
||||
} else {
|
||||
$includetoken = false;
|
||||
if ($typeurl == self::TOKENPLUGINFILE) {
|
||||
$includetoken = true;
|
||||
}
|
||||
$url = \moodle_url::make_pluginfile_url(
|
||||
$filerecord['contextid'],
|
||||
$filerecord['component'],
|
||||
$filerecord['filearea'],
|
||||
$filerecord['itemid'],
|
||||
$filerecord['filepath'],
|
||||
$filerecord['filename'],
|
||||
false,
|
||||
$includetoken
|
||||
);
|
||||
}
|
||||
|
||||
$config = new stdClass();
|
||||
$h5pplayer = new player($url->out(false), $config);
|
||||
// We need to add assets to page to create the export file.
|
||||
$h5pplayer->add_assets_to_page();
|
||||
|
||||
// Call the method. We need the id of the new H5P content.
|
||||
$rc = new \ReflectionClass(player::class);
|
||||
$rcp = $rc->getProperty('h5pid');
|
||||
$rcp->setAccessible(true);
|
||||
$h5pid = $rcp->getValue($h5pplayer);
|
||||
|
||||
// Get the info export file.
|
||||
$factory = new factory();
|
||||
$core = $factory->get_core();
|
||||
$content = $core->loadContent($h5pid);
|
||||
$slug = $content['slug'] ? $content['slug'] . '-' : '';
|
||||
$exportfilename = "{$slug}{$h5pid}.h5p";
|
||||
$fileh5p = $core->fs->get_export_file($exportfilename);
|
||||
$deployedfile = [];
|
||||
$deployedfile['filename'] = $fileh5p->get_filename();
|
||||
$deployedfile['filepath'] = $fileh5p->get_filepath();
|
||||
$deployedfile['mimetype'] = $fileh5p->get_mimetype();
|
||||
$deployedfile['filesize'] = $fileh5p->get_filesize();
|
||||
$deployedfile['timemodified'] = $fileh5p->get_timemodified();
|
||||
|
||||
// Create the url depending the request was made through typeurl.
|
||||
if ($typeurl == self::WSPLUGINFILE) {
|
||||
$url = \moodle_url::make_webservice_pluginfile_url(
|
||||
$fileh5p->get_contextid(),
|
||||
$fileh5p->get_component(),
|
||||
$fileh5p->get_filearea(),
|
||||
'',
|
||||
'',
|
||||
$fileh5p->get_filename()
|
||||
);
|
||||
} else {
|
||||
$includetoken = false;
|
||||
if ($typeurl == self::TOKENPLUGINFILE) {
|
||||
$includetoken = true;
|
||||
}
|
||||
$url = \moodle_url::make_pluginfile_url(
|
||||
$fileh5p->get_contextid(),
|
||||
$fileh5p->get_component(),
|
||||
$fileh5p->get_filearea(),
|
||||
'',
|
||||
'',
|
||||
$fileh5p->get_filename(),
|
||||
false,
|
||||
$includetoken
|
||||
);
|
||||
}
|
||||
$deployedfile['fileurl'] = $url->out(false);
|
||||
|
||||
return $deployedfile;
|
||||
}
|
||||
}
|
||||
|
@ -328,4 +328,55 @@ class helper_testcase extends \advanced_testcase {
|
||||
$this->assertCount(7, $messages->error);
|
||||
$this->assertCount(2, $messages->info);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the behaviour of get_export_info().
|
||||
*/
|
||||
public function test_get_export_info(): void {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$filename = 'guess-the-answer.h5p';
|
||||
$syscontext = \context_system::instance();
|
||||
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
|
||||
$deployedfile = $generator->create_export_file($filename,
|
||||
$syscontext->id,
|
||||
file_storage::COMPONENT,
|
||||
file_storage::EXPORT_FILEAREA);
|
||||
|
||||
// Test scenario 1: Get export information from correct filename.
|
||||
$helperfile = helper::get_export_info($deployedfile['filename']);
|
||||
$this->assertEquals($deployedfile['filename'], $helperfile['filename']);
|
||||
$this->assertEquals($deployedfile['filepath'], $helperfile['filepath']);
|
||||
$this->assertEquals($deployedfile['filesize'], $helperfile['filesize']);
|
||||
$this->assertEquals($deployedfile['timemodified'], $helperfile['timemodified']);
|
||||
$this->assertEquals($deployedfile['fileurl'], $helperfile['fileurl']);
|
||||
|
||||
// Test scenario 2: Get export information from correct filename and url.
|
||||
$url = \moodle_url::make_pluginfile_url(
|
||||
$syscontext->id,
|
||||
file_storage::COMPONENT,
|
||||
'unittest',
|
||||
0,
|
||||
'/',
|
||||
$deployedfile['filename'],
|
||||
false,
|
||||
true
|
||||
);
|
||||
$helperfile = helper::get_export_info($deployedfile['filename'], $url);
|
||||
$this->assertEquals($url, $helperfile['fileurl']);
|
||||
|
||||
// Test scenario 3: Get export information from correct filename and factory.
|
||||
$factory = new \core_h5p\factory();
|
||||
$helperfile = helper::get_export_info($deployedfile['filename'], null, $factory);
|
||||
$this->assertEquals($deployedfile['filename'], $helperfile['filename']);
|
||||
$this->assertEquals($deployedfile['filepath'], $helperfile['filepath']);
|
||||
$this->assertEquals($deployedfile['filesize'], $helperfile['filesize']);
|
||||
$this->assertEquals($deployedfile['timemodified'], $helperfile['timemodified']);
|
||||
$this->assertEquals($deployedfile['fileurl'], $helperfile['fileurl']);
|
||||
|
||||
// Test scenario 4: Get export information from wrong filename.
|
||||
$helperfile = helper::get_export_info('nofileexist.h5p', $url);
|
||||
$this->assertNull($helperfile);
|
||||
}
|
||||
}
|
||||
|
136
mod/h5pactivity/classes/external/get_h5pactivities_by_courses.php
vendored
Normal file
136
mod/h5pactivity/classes/external/get_h5pactivities_by_courses.php
vendored
Normal file
@ -0,0 +1,136 @@
|
||||
<?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 is the external method for returning a list of h5p activities.
|
||||
*
|
||||
* @package mod_h5pactivity
|
||||
* @since Moodle 3.9
|
||||
* @copyright 2020 Carlos Escobedo <carlos@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace mod_h5pactivity\external;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
require_once($CFG->libdir . '/externallib.php');
|
||||
|
||||
use external_api;
|
||||
use external_function_parameters;
|
||||
use external_value;
|
||||
use external_single_structure;
|
||||
use external_multiple_structure;
|
||||
use external_util;
|
||||
use external_warnings;
|
||||
use context_module;
|
||||
use core_h5p\factory;
|
||||
|
||||
/**
|
||||
* This is the external method for returning a list of h5p activities.
|
||||
*
|
||||
* @copyright 2020 Carlos Escobedo <carlos@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class get_h5pactivities_by_courses extends external_api {
|
||||
/**
|
||||
* Parameters.
|
||||
*
|
||||
* @return external_function_parameters
|
||||
*/
|
||||
public static function execute_parameters(): external_function_parameters {
|
||||
return new external_function_parameters (
|
||||
[
|
||||
'courseids' => new external_multiple_structure(
|
||||
new external_value(PARAM_INT, 'Course id'), 'Array of course ids', VALUE_DEFAULT, []
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of h5p activities in a provided list of courses.
|
||||
* If no list is provided all h5p activities that the user can view will be returned.
|
||||
*
|
||||
* @param array $courseids course ids
|
||||
* @return array of h5p activities and warnings
|
||||
* @since Moodle 3.9
|
||||
*/
|
||||
public static function execute(array $courseids): array {
|
||||
global $PAGE;
|
||||
|
||||
$warnings = [];
|
||||
$returnedh5pactivities = [];
|
||||
|
||||
$params = external_api::validate_parameters(self::execute_parameters(), [
|
||||
'courseids' => $courseids
|
||||
]);
|
||||
|
||||
$mycourses = [];
|
||||
if (empty($params['courseids'])) {
|
||||
$mycourses = enrol_get_my_courses();
|
||||
$params['courseids'] = array_keys($mycourses);
|
||||
}
|
||||
|
||||
// Ensure there are courseids to loop through.
|
||||
if (!empty($params['courseids'])) {
|
||||
|
||||
$factory = new factory();
|
||||
|
||||
list($courses, $warnings) = external_util::validate_courses($params['courseids'], $mycourses);
|
||||
$output = $PAGE->get_renderer('core');
|
||||
|
||||
// Get the h5p activities in this course, this function checks users visibility permissions.
|
||||
// We can avoid then additional validate_context calls.
|
||||
$h5pactivities = get_all_instances_in_courses('h5pactivity', $courses);
|
||||
foreach ($h5pactivities as $h5pactivity) {
|
||||
$context = context_module::instance($h5pactivity->coursemodule);
|
||||
// Remove fields that are not from the h5p activity (added by get_all_instances_in_courses).
|
||||
unset($h5pactivity->coursemodule, $h5pactivity->context,
|
||||
$h5pactivity->visible, $h5pactivity->section,
|
||||
$h5pactivity->groupmode, $h5pactivity->groupingid);
|
||||
|
||||
$exporter = new h5pactivity_summary_exporter($h5pactivity,
|
||||
['context' => $context, 'factory' => $factory]);
|
||||
$summary = $exporter->export($output);
|
||||
$returnedh5pactivities[] = $summary;
|
||||
}
|
||||
}
|
||||
|
||||
$result = [
|
||||
'h5pactivities' => $returnedh5pactivities,
|
||||
'warnings' => $warnings
|
||||
];
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes the get_h5pactivities_by_courses return value.
|
||||
*
|
||||
* @return external_single_structure
|
||||
* @since Moodle 3.9
|
||||
*/
|
||||
public static function execute_returns() {
|
||||
return new external_single_structure(
|
||||
[
|
||||
'h5pactivities' => new external_multiple_structure(
|
||||
h5pactivity_summary_exporter::get_read_structure()
|
||||
),
|
||||
'warnings' => new external_warnings(),
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
241
mod/h5pactivity/classes/external/h5pactivity_summary_exporter.php
vendored
Normal file
241
mod/h5pactivity/classes/external/h5pactivity_summary_exporter.php
vendored
Normal file
@ -0,0 +1,241 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Class for exporting h5p activity data.
|
||||
*
|
||||
* @package mod_h5pactivity
|
||||
* @since Moodle 3.9
|
||||
* @copyright 2020 Carlos Escobedo <carlos@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
namespace mod_h5pactivity\external;
|
||||
|
||||
use core\external\exporter;
|
||||
use renderer_base;
|
||||
use external_util;
|
||||
use external_files;
|
||||
use core_h5p\factory;
|
||||
use core_h5p\api;
|
||||
|
||||
/**
|
||||
* Class for exporting h5p activity data.
|
||||
*
|
||||
* @copyright 2020 Carlos Escobedo <carlos@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class h5pactivity_summary_exporter extends exporter {
|
||||
|
||||
/**
|
||||
* Properties definition.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected static function define_properties() {
|
||||
|
||||
return [
|
||||
'id' => [
|
||||
'type' => PARAM_INT,
|
||||
'description' => 'The primary key of the record.',
|
||||
],
|
||||
'course' => [
|
||||
'type' => PARAM_INT,
|
||||
'description' => 'Course id this h5p activity is part of.',
|
||||
],
|
||||
'name' => [
|
||||
'type' => PARAM_TEXT,
|
||||
'description' => 'The name of the activity module instance.',
|
||||
],
|
||||
'timecreated' => [
|
||||
'type' => PARAM_INT,
|
||||
'description' => 'Timestamp of when the instance was added to the course.',
|
||||
'optional' => true,
|
||||
],
|
||||
'timemodified' => [
|
||||
'type' => PARAM_INT,
|
||||
'description' => 'Timestamp of when the instance was last modified.',
|
||||
'optional' => true,
|
||||
],
|
||||
'intro' => [
|
||||
'default' => '',
|
||||
'type' => PARAM_RAW,
|
||||
'description' => 'H5P activity description.',
|
||||
'null' => NULL_ALLOWED,
|
||||
],
|
||||
'introformat' => [
|
||||
'choices' => [FORMAT_HTML, FORMAT_MOODLE, FORMAT_PLAIN, FORMAT_MARKDOWN],
|
||||
'type' => PARAM_INT,
|
||||
'default' => FORMAT_MOODLE,
|
||||
'description' => 'The format of the intro field.',
|
||||
],
|
||||
'grade' => [
|
||||
'type' => PARAM_INT,
|
||||
'default' => 0,
|
||||
'description' => 'The maximum grade for submission.',
|
||||
'optional' => true,
|
||||
],
|
||||
'displayoptions' => [
|
||||
'type' => PARAM_INT,
|
||||
'default' => 0,
|
||||
'description' => 'H5P Button display options.',
|
||||
],
|
||||
'enabletracking' => [
|
||||
'type' => PARAM_INT,
|
||||
'default' => 1,
|
||||
'description' => 'Enable xAPI tracking.',
|
||||
],
|
||||
'grademethod' => [
|
||||
'type' => PARAM_INT,
|
||||
'default' => 1,
|
||||
'description' => 'Which H5P attempt is used for grading.',
|
||||
],
|
||||
'contenthash' => [
|
||||
'type' => PARAM_ALPHANUM,
|
||||
'description' => 'Sha1 hash of file content.',
|
||||
'optional' => true,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Related objects definition.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected static function define_related() {
|
||||
return [
|
||||
'context' => 'context',
|
||||
'factory' => 'core_h5p\\factory'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Other properties definition.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected static function define_other_properties() {
|
||||
return [
|
||||
'coursemodule' => [
|
||||
'type' => PARAM_INT
|
||||
],
|
||||
'introfiles' => [
|
||||
'type' => external_files::get_properties_for_exporter(),
|
||||
'multiple' => true
|
||||
],
|
||||
'package' => [
|
||||
'type' => external_files::get_properties_for_exporter(),
|
||||
'multiple' => true
|
||||
],
|
||||
'deployedfile' => [
|
||||
'optional' => true,
|
||||
'description' => 'H5P file deployed.',
|
||||
'type' => [
|
||||
'filename' => array(
|
||||
'type' => PARAM_FILE,
|
||||
'description' => 'File name.',
|
||||
'optional' => true,
|
||||
'null' => NULL_NOT_ALLOWED,
|
||||
),
|
||||
'filepath' => array(
|
||||
'type' => PARAM_PATH,
|
||||
'description' => 'File path.',
|
||||
'optional' => true,
|
||||
'null' => NULL_NOT_ALLOWED,
|
||||
),
|
||||
'filesize' => array(
|
||||
'type' => PARAM_INT,
|
||||
'description' => 'File size.',
|
||||
'optional' => true,
|
||||
'null' => NULL_NOT_ALLOWED,
|
||||
),
|
||||
'fileurl' => array(
|
||||
'type' => PARAM_URL,
|
||||
'description' => 'Downloadable file url.',
|
||||
'optional' => true,
|
||||
'null' => NULL_NOT_ALLOWED,
|
||||
),
|
||||
'timemodified' => array(
|
||||
'type' => PARAM_INT,
|
||||
'description' => 'Time modified.',
|
||||
'optional' => true,
|
||||
'null' => NULL_NOT_ALLOWED,
|
||||
),
|
||||
'mimetype' => array(
|
||||
'type' => PARAM_RAW,
|
||||
'description' => 'File mime type.',
|
||||
'optional' => true,
|
||||
'null' => NULL_NOT_ALLOWED,
|
||||
)
|
||||
]
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign values to the defined other properties.
|
||||
*
|
||||
* @param renderer_base $output The output renderer object.
|
||||
* @return array
|
||||
*/
|
||||
protected function get_other_values(renderer_base $output) {
|
||||
$context = $this->related['context'];
|
||||
$factory = $this->related['factory'];
|
||||
|
||||
$values = [
|
||||
'coursemodule' => $context->instanceid,
|
||||
];
|
||||
|
||||
$values['introfiles'] = external_util::get_area_files($context->id, 'mod_h5pactivity', 'intro', false, false);
|
||||
|
||||
$values['package'] = external_util::get_area_files($context->id, 'mod_h5pactivity', 'package', false, false);
|
||||
|
||||
// Only if this H5P activity has been deployed, return the exported file.
|
||||
$fileh5p = api::get_export_info_from_context_id($context->id, $factory, 'mod_h5pactivity', 'package');
|
||||
if ($fileh5p) {
|
||||
$values['deployedfile'] = $fileh5p;
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the formatting parameters for the intro.
|
||||
*
|
||||
* @return array with the formatting parameters
|
||||
*/
|
||||
protected function get_format_parameters_for_intro() {
|
||||
return [
|
||||
'component' => 'mod_h5pactivity',
|
||||
'filearea' => 'intro',
|
||||
'options' => ['noclean' => true],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the formatting parameters for the package.
|
||||
*
|
||||
* @return array with the formatting parameters
|
||||
*/
|
||||
protected function get_format_parameters_for_package() {
|
||||
return [
|
||||
'component' => 'mod_h5pactivity',
|
||||
'filearea' => 'package',
|
||||
'itemid' => 0,
|
||||
'options' => ['noclean' => true],
|
||||
];
|
||||
}
|
||||
}
|
@ -62,4 +62,15 @@ $functions = [
|
||||
'capabilities' => 'mod/h5pactivity:view',
|
||||
'services' => [MOODLE_OFFICIAL_MOBILE_SERVICE],
|
||||
],
|
||||
'mod_h5pactivity_get_h5pactivities_by_courses' => [
|
||||
'classname' => 'mod_h5pactivity\external\get_h5pactivities_by_courses',
|
||||
'methodname' => 'execute',
|
||||
'classpath' => '',
|
||||
'description' => 'Returns a list of h5p activities in a list of
|
||||
provided courses, if no list is provided all h5p activities
|
||||
that the user can view will be returned.',
|
||||
'type' => 'read',
|
||||
'capabilities' => 'mod/h5pactivity:view',
|
||||
'services' => [MOODLE_OFFICIAL_MOBILE_SERVICE],
|
||||
],
|
||||
];
|
||||
|
182
mod/h5pactivity/tests/external/get_h5pactivities_by_courses_test.php
vendored
Normal file
182
mod/h5pactivity/tests/external/get_h5pactivities_by_courses_test.php
vendored
Normal file
@ -0,0 +1,182 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* External function test for get_h5pactivities_by_courses.
|
||||
*
|
||||
* @package mod_h5pactivity
|
||||
* @category external
|
||||
* @since Moodle 3.9
|
||||
* @copyright 2020 Carlos Escobedo <carlos@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace mod_h5pactivity\external;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
|
||||
require_once($CFG->dirroot . '/webservice/tests/helpers.php');
|
||||
|
||||
use external_api;
|
||||
use externallib_advanced_testcase;
|
||||
use stdClass;
|
||||
use context_module;
|
||||
|
||||
/**
|
||||
* External function test for get_h5pactivities_by_courses.
|
||||
*
|
||||
* @package mod_h5pactivity
|
||||
* @copyright 2020 Carlos Escobedo <carlos@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class get_h5pactivities_by_courses_testcase extends externallib_advanced_testcase {
|
||||
|
||||
/**
|
||||
* Test test_get_h5pactivities_by_courses user student.
|
||||
*/
|
||||
public function test_get_h5pactivities_by_courses() {
|
||||
global $CFG, $DB;
|
||||
|
||||
$this->resetAfterTest();
|
||||
$this->setAdminUser();
|
||||
|
||||
// Create 2 courses.
|
||||
// Course 1 -> 2 activities with H5P files package without deploy.
|
||||
// Course 2 -> 1 activity with H5P file package deployed.
|
||||
$course1 = $this->getDataGenerator()->create_course();
|
||||
$params = [
|
||||
'course' => $course1->id,
|
||||
'packagefilepath' => $CFG->dirroot.'/h5p/tests/fixtures/filltheblanks.h5p',
|
||||
'introformat' => 1
|
||||
];
|
||||
$activities[] = $this->getDataGenerator()->create_module('h5pactivity', $params);
|
||||
// Add filename to make easier the asserts.
|
||||
$activities[0]->filename = 'filltheblanks.h5p';
|
||||
$params = [
|
||||
'course' => $course1->id,
|
||||
'packagefilepath' => $CFG->dirroot.'/h5p/tests/fixtures/greeting-card-887.h5p',
|
||||
'introformat' => 1
|
||||
];
|
||||
$activities[] = $this->getDataGenerator()->create_module('h5pactivity', $params);
|
||||
// Add filename to make easier the asserts.
|
||||
$activities[1]->filename = 'greeting-card-887.h5p';
|
||||
|
||||
$course2 = $this->getDataGenerator()->create_course();
|
||||
$params = [
|
||||
'course' => $course2->id,
|
||||
'packagefilepath' => $CFG->dirroot.'/h5p/tests/fixtures/guess-the-answer.h5p',
|
||||
'introformat' => 1
|
||||
];
|
||||
$activities[] = $this->getDataGenerator()->create_module('h5pactivity', $params);
|
||||
$activities[2]->filename = 'guess-the-answer.h5p';
|
||||
|
||||
$context = context_module::instance($activities[2]->cmid);
|
||||
// Create a fake deploy H5P file.
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
|
||||
$deployedfile = $generator->create_export_file($activities[2]->filename, $context->id, 'mod_h5pactivity', 'package');
|
||||
|
||||
// Create a user and enrol as student in both courses.
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
$studentrole = $DB->get_record('role', ['shortname' => 'student']);
|
||||
$maninstance1 = $DB->get_record('enrol', ['courseid' => $course1->id, 'enrol' => 'manual'], '*', MUST_EXIST);
|
||||
$maninstance2 = $DB->get_record('enrol', ['courseid' => $course2->id, 'enrol' => 'manual'], '*', MUST_EXIST);
|
||||
$manual = enrol_get_plugin('manual');
|
||||
$manual->enrol_user($maninstance1, $user->id, $studentrole->id);
|
||||
$manual->enrol_user($maninstance2, $user->id, $studentrole->id);
|
||||
|
||||
// Check the activities returned by the first course.
|
||||
$this->setUser($user);
|
||||
$courseids = [$course1->id];
|
||||
$result = get_h5pactivities_by_courses::execute($courseids);
|
||||
$result = external_api::clean_returnvalue(get_h5pactivities_by_courses::execute_returns(), $result);
|
||||
$this->assertCount(0, $result['warnings']);
|
||||
$this->assertCount(2, $result['h5pactivities']);
|
||||
$this->assert_activities($activities, $result);
|
||||
$this->assertNotContains('deployedfile', $result['h5pactivities'][0]);
|
||||
$this->assertNotContains('deployedfile', $result['h5pactivities'][1]);
|
||||
|
||||
// Call the external function without passing course id.
|
||||
// Expected result, all the courses, course1 and course2.
|
||||
$result = get_h5pactivities_by_courses::execute([]);
|
||||
$result = external_api::clean_returnvalue(get_h5pactivities_by_courses::execute_returns(), $result);
|
||||
$this->assertCount(0, $result['warnings']);
|
||||
$this->assertCount(3, $result['h5pactivities']);
|
||||
// We need to sort the $result by id.
|
||||
// Because we are not sure how it is ordered with more than one course.
|
||||
array_multisort(array_map(function($element) {
|
||||
return $element['id'];
|
||||
}, $result['h5pactivities']), SORT_ASC, $result['h5pactivities']);
|
||||
$this->assert_activities($activities, $result);
|
||||
$this->assertNotContains('deployedfile', $result['h5pactivities'][0]);
|
||||
$this->assertNotContains('deployedfile', $result['h5pactivities'][1]);
|
||||
// Only the activity from the second course has been deployed.
|
||||
$this->assertEquals($deployedfile['filename'], $result['h5pactivities'][2]['deployedfile']['filename']);
|
||||
$this->assertEquals($deployedfile['filepath'], $result['h5pactivities'][2]['deployedfile']['filepath']);
|
||||
$this->assertEquals($deployedfile['filesize'], $result['h5pactivities'][2]['deployedfile']['filesize']);
|
||||
$this->assertEquals($deployedfile['timemodified'], $result['h5pactivities'][2]['deployedfile']['timemodified']);
|
||||
$this->assertEquals($deployedfile['mimetype'], $result['h5pactivities'][2]['deployedfile']['mimetype']);
|
||||
$this->assertEquals($deployedfile['fileurl'], $result['h5pactivities'][2]['deployedfile']['fileurl']);
|
||||
|
||||
// Unenrol user from second course.
|
||||
$manual->unenrol_user($maninstance2, $user->id);
|
||||
// Remove the last activity from the array.
|
||||
array_pop($activities);
|
||||
|
||||
// Call the external function without passing course id.
|
||||
$result = get_h5pactivities_by_courses::execute([]);
|
||||
$result = external_api::clean_returnvalue(get_h5pactivities_by_courses::execute_returns(), $result);
|
||||
$this->assertCount(0, $result['warnings']);
|
||||
$this->assertCount(2, $result['h5pactivities']);
|
||||
$this->assert_activities($activities, $result);
|
||||
|
||||
// Call for the second course we unenrolled the user from, expected warning.
|
||||
$result = get_h5pactivities_by_courses::execute([$course2->id]);
|
||||
$result = external_api::clean_returnvalue(get_h5pactivities_by_courses::execute_returns(), $result);
|
||||
$this->assertCount(1, $result['warnings']);
|
||||
$this->assertEquals('1', $result['warnings'][0]['warningcode']);
|
||||
$this->assertEquals($course2->id, $result['warnings'][0]['itemid']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a scenario to use into the tests.
|
||||
*
|
||||
* @param array $activities list of H5P activities.
|
||||
* @param array $result list of H5P activities by WS.
|
||||
* @return void
|
||||
*/
|
||||
protected function assert_activities(array $activities, array $result): void {
|
||||
|
||||
$total = count($result);
|
||||
for ($i = 0; $i < $total; $i++) {
|
||||
$this->assertEquals($activities[$i]->id, $result['h5pactivities'][$i]['id']);
|
||||
$this->assertEquals($activities[$i]->course, $result['h5pactivities'][$i]['course']);
|
||||
$this->assertEquals($activities[$i]->name, $result['h5pactivities'][$i]['name']);
|
||||
$this->assertEquals($activities[$i]->timecreated, $result['h5pactivities'][$i]['timecreated']);
|
||||
$this->assertEquals($activities[$i]->timemodified, $result['h5pactivities'][$i]['timemodified']);
|
||||
$this->assertEquals($activities[$i]->intro, $result['h5pactivities'][$i]['intro']);
|
||||
$this->assertEquals($activities[$i]->introformat, $result['h5pactivities'][$i]['introformat']);
|
||||
$this->assertEquals([], $result['h5pactivities'][$i]['introfiles']);
|
||||
$this->assertEquals($activities[$i]->grade, $result['h5pactivities'][$i]['grade']);
|
||||
$this->assertEquals($activities[$i]->displayoptions, $result['h5pactivities'][$i]['displayoptions']);
|
||||
$this->assertEquals($activities[$i]->enabletracking, $result['h5pactivities'][$i]['enabletracking']);
|
||||
$this->assertEquals($activities[$i]->grademethod, $result['h5pactivities'][$i]['grademethod']);
|
||||
$this->assertEquals($activities[$i]->cmid, $result['h5pactivities'][$i]['coursemodule']);
|
||||
$this->assertEquals($activities[$i]->filename, $result['h5pactivities'][$i]['package'][0]['filename']);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user