Newer
Older
// 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/>.
* \mod_hvp\framework class
* @package mod_hvp
* @copyright 2016 Joubel AS
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_hvp;
defined('MOODLE_INTERNAL') || die();
require_once(__DIR__ . '/../autoloader.php');
require_once($CFG->libdir . '/adminlib.php');
* Moodle's implementation of the H5P framework interface.
* @package mod_hvp
* @copyright 2016 Joubel AS
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*
* @SuppressWarnings(PHPMD)
class framework implements \H5PFrameworkInterface {
/**
* Get type of hvp instance
*
* @param string $type Type of hvp instance to get
* @return \H5PContentValidator|\H5PCore|\H5PStorage|\H5PValidator|\mod_hvp\framework|\H5peditor
public static function instance($type = null) {
static $interface, $core, $editor, $editorinterface, $editorajaxinterface;
if (!isset($interface)) {
$interface = new \mod_hvp\framework();
$fs = new \mod_hvp\file_storage();
$context = \context_system::instance();
$url = "{$CFG->httpswwwroot}/pluginfile.php/{$context->id}/mod_hvp";
$language = self::get_language();
$export = !(isset($CFG->mod_hvp_export) && $CFG->mod_hvp_export === '0');
$core = new \H5PCore($interface, $fs, $url, $language, $export);
$core->aggregateAssets = !(isset($CFG->mod_hvp_aggregate_assets) && $CFG->mod_hvp_aggregate_assets === '0');
}
switch ($type) {
case 'validator':
return new \H5PValidator($interface, $core);
case 'storage':
return new \H5PStorage($interface, $core);
case 'contentvalidator':
return new \H5PContentValidator($interface, $core);
case 'interface':
return $interface;
case 'editor':
if (empty($editorinterface)) {
$editorinterface = new \mod_hvp\editor_framework();
}
if (empty($editorajaxinterface)) {
$editorajaxinterface = new editor_ajax();
}
if (empty($editor)) {
$editor = new \H5peditor($core, $editorinterface, $editorajaxinterface);
}
return $editor;
case 'core':
default:
return $core;
}
}
* Check if the current user has editor access, if not then return the
* given error message.
*
* @param string $error
* @return boolean
*/
public static function has_editor_access($error) {
$context = \context::instance_by_id(required_param('contextId', PARAM_RAW));
$cap = ($context->contextlevel === CONTEXT_COURSE ? 'addinstance' : 'manage');
if (!has_capability("mod/hvp:$cap", $context)) {
\H5PCore::ajaxError(get_string($error, 'hvp'));
http_response_code(403);
return false;
}
/**
* Get current H5P language code.
*
* @return string Language Code
*/
public static function get_language() {
static $map;
if (empty($map)) {
// Create mapping for "converting" language codes.
$map = array(
'no' => 'nb'
);
}
// Get current language in Moodle.
$language = str_replace('_', '-', strtolower(\current_language()));
return isset($map[$language]) ? $map[$language] : $language;
}
/**
* Implements getPlatformInfo
*/
// @codingStandardsIgnoreLine
public function getPlatformInfo() {
global $CFG;
return array(
'name' => 'Moodle',
'version' => $CFG->version,
'h5pVersion' => get_component_version('mod_hvp'),
);
}
/**
// @codingStandardsIgnoreLine
public function fetchExternalData($url, $data = null, $blocking = true, $stream = null) {
if ($stream !== null) {
// Download file.
// Generate local tmp file path.
$localfolder = $CFG->tempdir . uniqid('/hvp-');
$stream = $localfolder . '.h5p';
// Add folder and file paths to H5P Core.
$interface = self::instance('interface');
$interface->getUploadedH5pFolderPath($localfolder);
$interface->getUploadedH5pPath($stream);
}
$response = download_file_content($url, null, $data, true, 300, 20, false, $stream);
if (empty($response->error)) {
return $response->results;
$this->setErrorMessage($response->error, 'failed-fetching-external-data');
}
}
/**
* Implements setLibraryTutorialUrl
*
* Set the tutorial URL for a library. All versions of the library is set
*
* @param string $libraryname
* @param string $url
*/
// @codingStandardsIgnoreLine
public function setLibraryTutorialUrl($libraryname, $url) {
global $DB;
$DB->execute("UPDATE {hvp_libraries} SET tutorial_url = ? WHERE machine_name = ?", array($url, $libraryname));
}
/**
* Implements setErrorMessage
*
* @param string $message translated error message
// @codingStandardsIgnoreLine
public function setErrorMessage($message, $code = null) {
if ($message !== null) {
self::messages('error', $message, $code);
}
/**
* Implements setInfoMessage
*/
// @codingStandardsIgnoreLine
public function setInfoMessage($message) {
if ($message !== null) {
self::messages('info', $message);
}
}
/**
* Store messages until they can be printed to the current user
*
* @param string $type Type of messages, e.g. 'info' or 'error'
* @param string $newmessage Optional
* @return array Array of stored messages
public static function messages($type, $newmessage = null, $code = null) {
static $m = 'mod_hvp_messages';
if ($newmessage === null) {
$messages = isset($_SESSION[$m][$type]) ? $_SESSION[$m][$type] : array();
unset($_SESSION[$m][$type]);
if (empty($_SESSION[$m])) {
unset($_SESSION[$m]);
}
return $messages;
}
// We expect to get out an array of strings when getting info
// and an array of objects when getting errors for consistency across platforms.
// This implementation should be improved for consistency across the data type returned here.
if ($type === 'error') {
$_SESSION[$m][$type][] = (object)array(
'code' => $code,
'message' => $newmessage
);
$_SESSION[$m][$type][] = $newmessage;
}
}
/**
* Simple print of given messages.
*
* @param string $type One of error|info
* @param array $messages
*/
// @codingStandardsIgnoreLine
public static function printMessages($type, $messages) {
global $OUTPUT;
foreach ($messages as $message) {
$out = $type === 'error' ? $message->message : $message;
print $OUTPUT->notification($out, ($type === 'error' ? 'notifyproblem' : 'notifymessage'));
/**
* Implements getMessages
*/
// @codingStandardsIgnoreLine
public function getMessages($type) {
return self::messages($type);
/**
* Implements t
*/
public function t($message, $replacements = array()) {
if (empty($translationsmap)) {
// Create mapping.
// @codingStandardsIgnoreStart
'Your PHP version does not support ZipArchive.' => 'noziparchive',
'The file you uploaded is not a valid HTML5 Package (It does not have the .h5p file extension)' => 'noextension',
'The file you uploaded is not a valid HTML5 Package (We are unable to unzip it)' => 'nounzip',
'Could not parse the main h5p.json file' => 'noparse',
'The main h5p.json file is not valid' => 'nojson',
'Invalid content folder' => 'invalidcontentfolder',
'Could not find or parse the content.json file' => 'nocontent',
'Library directory name must match machineName or machineName-majorVersion.minorVersion (from library.json). (Directory: %directoryName , machineName: %machineName, majorVersion: %majorVersion, minorVersion: %minorVersion)' => 'librarydirectoryerror',
'A valid content folder is missing' => 'missingcontentfolder',
'A valid main h5p.json file is missing' => 'invalidmainjson',
'Missing required library @library' => 'missinglibrary',
"Note that the libraries may exist in the file you uploaded, but you're not allowed to upload new libraries. Contact the site administrator about this." => 'missinguploadpermissions',
'Invalid library name: %name' => 'invalidlibraryname',
'Could not find library.json file with valid json format for library %name' => 'missinglibraryjson',
'Invalid semantics.json file has been included in the library %name' => 'invalidsemanticsjson',
'Invalid language file %file in library %library' => 'invalidlanguagefile',
'Invalid language file %languageFile has been included in the library %name' => 'invalidlanguagefile2',
'The file "%file" is missing from library: "%name"' => 'missinglibraryfile',
'The system was unable to install the <em>%component</em> component from the package, it requires a newer version of the H5P plugin. This site is currently running version %current, whereas the required version is %required or higher. You should consider upgrading and then try again.' => 'missingcoreversion',
"Invalid data provided for %property in %library. Boolean expected." => 'invalidlibrarydataboolean',
"Invalid data provided for %property in %library" => 'invalidlibrarydata',
"Can't read the property %property in %library" => 'invalidlibraryproperty',
'The required property %property is missing from %library' => 'missinglibraryproperty',
'Illegal option %option in %library' => 'invalidlibraryoption',
'Added %new new H5P library and updated %old old one.' => 'addedandupdatedss',
'Added %new new H5P library and updated %old old ones.' => 'addedandupdatedsp',
'Added %new new H5P libraries and updated %old old one.' => 'addedandupdatedps',
'Added %new new H5P libraries and updated %old old ones.' => 'addedandupdatedpp',
'Added %new new H5P library.' => 'addednewlibrary',
'Added %new new H5P libraries.' => 'addednewlibraries',
'Updated %old H5P library.' => 'updatedlibrary',
'Updated %old H5P libraries.' => 'updatedlibraries',
'Missing dependency @dep required by @lib.' => 'missingdependency',
'Provided string is not valid according to regexp in semantics. (value: \"%value\", regexp: \"%regexp\")' => 'invalidstring',
'File "%filename" not allowed. Only files with the following extensions are allowed: %files-allowed.' => 'invalidfile',
'Invalid selected option in multi-select.' => 'invalidmultiselectoption',
'Invalid selected option in select.' => 'invalidselectoption',
'H5P internal error: unknown content type "@type" in semantics. Removing content!' => 'invalidsemanticstype',
'Copyright information' => 'copyrightinfo',
'Title' => 'title',
'Author' => 'author',
'Year(s)' => 'years',
'Source' => 'source',
'License' => 'license',
'Undisclosed' => 'undisclosed',
'Attribution 4.0' => 'attribution',
'Attribution-ShareAlike 4.0' => 'attributionsa',
'Attribution-NoDerivs 4.0' => 'attributionnd',
'Attribution-NonCommercial 4.0' => 'attributionnc',
'Attribution-NonCommercial-ShareAlike 4.0' => 'attributionncsa',
'Attribution-NonCommercial-NoDerivs 4.0' => 'attributionncnd',
'Attribution' => 'noversionattribution',
'Attribution-ShareAlike' => 'noversionattributionsa',
'Attribution-NoDerivs' => 'noversionattributionnd',
'Attribution-NonCommercial' => 'noversionattributionnc',
'Attribution-NonCommercial-ShareAlike' => 'noversionattributionncsa',
'Attribution-NonCommercial-NoDerivs' => 'noversionattributionncnd',
'General Public License v3' => 'gpl',
'Public Domain' => 'pd',
'Public Domain Dedication and Licence' => 'pddl',
'Public Domain Mark' => 'pdm',
'Copyright' => 'copyrightstring',
'Unable to create directory.' => 'unabletocreatedir',
'Unable to get field type.' => 'unabletogetfieldtype',
"File type isn't allowed." => 'filetypenotallowed',
'Invalid field type.' => 'invalidfieldtype',
'Invalid image file format. Use jpg, png or gif.' => 'invalidimageformat',
'File is not an image.' => 'filenotimage',
'Invalid audio file format. Use mp3 or wav.' => 'invalidaudioformat',
'Invalid video file format. Use mp4 or webm.' => 'invalidvideoformat',
'Could not save file.' => 'couldnotsave',
'Could not copy file.' => 'couldnotcopy',
'The mbstring PHP extension is not loaded. H5P need this to function properly' => 'missingmbstring',
'The version of the H5P library %machineName used in this content is not valid. Content contains %contentLibrary, but it should be %semanticsLibrary.' => 'wrongversion',
'The H5P library %library used in the content is not valid' => 'invalidlibrarynamed',
'Your PHP version is outdated. H5P requires version 5.2 to function properly. Version 5.6 or later is recommended.' => 'oldphpversion',
'Your PHP max upload size is quite small. With your current setup, you may not upload files larger than %number MB. This might be a problem when trying to upload H5Ps, images and videos. Please consider to increase it to more than 5MB.' => 'maxuploadsizetoosmall',
'Your PHP max post size is quite small. With your current setup, you may not upload files larger than %number MB. This might be a problem when trying to upload H5Ps, images and videos. Please consider to increase it to more than 5MB' => 'maxpostsizetoosmall',
'Your server does not have SSL enabled. SSL should be enabled to ensure a secure connection with the H5P hub.' => 'sslnotenabled',
'H5P hub communication has been disabled because one or more H5P requirements failed.' => 'hubcommunicationdisabled',
'When you have revised your server setup you may re-enable H5P hub communication in H5P Settings.' => 'reviseserversetupandretry',
'A problem with the server write access was detected. Please make sure that your server can write to your data folder.' => 'nowriteaccess',
'Your PHP max upload size is bigger than your max post size. This is known to cause issues in some installations.' => 'uploadsizelargerthanpostsize',
'Library cache was successfully updated!' => 'ctcachesuccess',
'No content types were received from the H5P Hub. Please try again later.' => 'ctcachenolibraries',
"Couldn't communicate with the H5P Hub. Please try again later." => 'ctcacheconnectionfailed',
'The hub is disabled. You can re-enable it in the H5P settings.' => 'hubisdisabled',
'File not found on server. Check file upload settings.' => 'filenotfoundonserver',
'Invalid security token.' => 'invalidtoken',
'No content type was specified.' => 'nocontenttype',
'The chosen content type is invalid.' => 'invalidcontenttype',
'You do not have permission to install content types. Contact the administrator of your site.' => 'installdenied',
'You do not have permission to install content types.' => 'installdenied',
'Validating h5p package failed.' => 'validatingh5pfailed',
'Failed to download the requested H5P.' => 'failedtodownloadh5p',
'A post message is required to access the given endpoint' => 'postmessagerequired',
'Could not get posted H5P.' => 'invalidh5ppost',
'Site could not be registered with the hub. Please contact your site administrator.' => 'sitecouldnotberegistered',
'The H5P Hub has been disabled until this problem can be resolved. You may still upload libraries through the "H5P Libraries" page.' => 'hubisdisableduploadlibraries',
'Your site was successfully registered with the H5P Hub.' => 'successfullyregisteredwithhub',
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
'You have been provided a unique key that identifies you with the Hub when receiving new updates. The key is available for viewing in the "H5P Settings" page.' => 'sitekeyregistered',
'Fullscreen' => 'fullscreen',
'Disable fullscreen' => 'disablefullscreen',
'Download' => 'download',
'Rights of use' => 'copyright',
'Embed' => 'embed',
'Size' => 'size',
'Show advanced' => 'showadvanced',
'Hide advanced' => 'hideadvanced',
'Include this script on your website if you want dynamic sizing of the embedded content:' => 'resizescript',
'Close' => 'close',
'Thumbnail' => 'thumbnail',
'No copyright information available for this content.' => 'nocopyright',
'Download this content as a H5P file.' => 'downloadtitle',
'View copyright information for this content.' => 'copyrighttitle',
'View the embed code for this content.' => 'embedtitle',
'Visit H5P.org to check out more cool content.' => 'h5ptitle',
'This content has changed since you last used it.' => 'contentchanged',
"You'll be starting over." => 'startingover',
'by' => 'by',
'Show more' => 'showmore',
'Show less' => 'showless',
'Sublevel' => 'sublevel',
'Confirm action' => 'confirmdialogheader',
'Please confirm that you wish to proceed. This action is not reversible.' => 'confirmdialogbody',
'Cancel' => 'cancellabel',
'Confirm' => 'confirmlabel',
'4.0 International' => 'licenseCC40',
'3.0 Unported' => 'licenseCC30',
'2.5 Generic' => 'licenseCC25',
'2.0 Generic' => 'licenseCC20',
'1.0 Generic' => 'licenseCC10',
'General Public License' => 'licenseGPL',
'Version 3' => 'licenseV3',
'Version 2' => 'licenseV2',
'Version 1' => 'licenseV1',
'CC0 1.0 Universal (CC0 1.0) Public Domain Dedication' => 'licenseCC010',
'CC0 1.0 Universal' => 'licenseCC010U',
'License Version' => 'licenseversion',
'Creative Commons' => 'creativecommons',
'Attribution (CC BY)' => 'ccattribution',
'Attribution-ShareAlike' => 'ccattributionsa',
'Attribution-ShareAlike (CC BY-SA)' => 'ccattributionsa',
'Attribution-NoDerivs' => 'ccattributionnd',
'Attribution-NoDerivs (CC BY-ND)' => 'ccattributionnd',
'Attribution-NonCommercial' => 'ccattributionnc',
'Attribution-NonCommercial (CC BY-NC)' => 'ccattributionnc',
'Attribution-NonCommercial-ShareAlike' => 'ccattributionncsa',
'Attribution-NonCommercial-ShareAlike (CC BY-NC-SA)' => 'ccattributionncsa',
'Attribution-NonCommercial-NoDerivs' => 'ccattributionncnd',
'Attribution-NonCommercial-NoDerivs (CC BY-NC-ND)' => 'ccattributionncnd',
'Public Domain Dedication' => 'ccpdd',
'Public Domain Dedication (CC0)' => 'ccpdd',
'Years (from)' => 'yearsfrom',
'Years (to)' => 'yearsto',
"Author's name" => 'authorname',
"Author's role" => 'authorrole',
'Editor' => 'editor',
'Licensee' => 'licensee',
'Originator' => 'originator',
'Any additional information about the license' => 'additionallicenseinfo',
'License Extras' => 'licenseextras',
'Changelog' => 'changelog',
'Content Type' => 'contenttype',
'Question' => 'question',
'Date' => 'date',
'Changed by' => 'changedby',
'Description of change' => 'changedescription',
'Photo cropped, text changed, etc.' => 'changeplaceholder',
'Additional Information' => 'additionalinfo',
'Author comments' => 'authorcomments',
'Comments for the editor of the content (This text will not be published as a part of copyright info)' => 'authorcommentsdescription',
// @codingStandardsIgnoreEnd
return get_string($translationsmap[$message], 'hvp', $replacements);
}
/**
* Implements getH5PPath
*/
// @codingStandardsIgnoreLine
public function getH5pPath() {
global $CFG;
return $CFG->dirroot . '/mod/hvp/files';
}
/**
* Implements getLibraryFileUrl
*/
// @codingStandardsIgnoreLine
public function getLibraryFileUrl($libraryfoldername, $fileName) {
global $CFG;
$context = \context_system::instance();
$basepath = $CFG->httpswwwroot . '/';
return "{$basepath}pluginfile.php/{$context->id}/mod_hvp/libraries/{$libraryfoldername}/{$fileName}";
/**
* Implements getUploadedH5PFolderPath
*/
// @codingStandardsIgnoreLine
public function getUploadedH5pFolderPath($setpath = null) {
static $path;
if ($setpath !== null) {
$path = $setpath;
}
if (!isset($path)) {
throw new \coding_exception('Using getUploadedH5pFolderPath() before path is set');
}
return $path;
}
/**
* Implements getUploadedH5PPath
*/
// @codingStandardsIgnoreLine
public function getUploadedH5pPath($setpath = null) {
static $path;
if ($setpath !== null) {
$path = $setpath;
}
return $path;
}
/**
* Implements loadLibraries
*/
// @codingStandardsIgnoreLine
public function loadLibraries() {
$results = $DB->get_records_sql(
"SELECT id, machine_name, title, major_version, minor_version,
patch_version, runnable, restricted
FROM {hvp_libraries}
ORDER BY title ASC, major_version ASC, minor_version ASC");
$libraries = array();
foreach ($results as $library) {
$libraries[$library->machine_name][] = $library;
}
// @codingStandardsIgnoreLine
public function setUnsupportedLibraries($libraries) {
/**
* Implements getUnsupportedLibraries.
*/
// @codingStandardsIgnoreLine
public function getUnsupportedLibraries() {
/**
* Implements getAdminUrl.
*/
// @codingStandardsIgnoreLine
public function getAdminUrl() {
// @codingStandardsIgnoreLine
public function getLibraryId($machinename, $majorversion = null, $minorversion = null) {
global $DB;
// Look for specific library.
$sqlwhere = 'WHERE machine_name = ?';
$sqlargs = array($machinename);
if ($majorversion !== null) {
// Look for major version.
$sqlwhere .= ' AND major_version = ?';
$sqlargs[] = $majorversion;
if ($minorversion !== null) {
// Look for minor version.
$sqlwhere .= ' AND minor_version = ?';
$sqlargs[] = $minorversion;
// Get the lastest version which matches the input parameters.
SELECT id
FROM {hvp_libraries}
ORDER BY major_version DESC,
minor_version DESC,
patch_version DESC
return $library ? $library->id : false;
}
/**
* Implements isPatchedLibrary
*/
// @codingStandardsIgnoreLine
public function isPatchedLibrary($library) {
global $DB, $CFG;
if (isset($CFG->mod_hvp_dev) && $CFG->mod_hvp_dev) {
// Makes sure libraries are updated, patch version does not matter.
}
$operator = $this->isInDevMode() ? '<=' : '<';
$library = $DB->get_record_sql(
'SELECT id
FROM {hvp_libraries}
WHERE machine_name = ?
AND major_version = ?
AND minor_version = ?
AND patch_version ' . $operator . ' ?',
array($library['machineName'],
$library['majorVersion'],
$library['minorVersion'],
$library['patchVersion'])
);
return $library ? true : false;
}
/**
* Implements isInDevMode
*/
// @codingStandardsIgnoreLine
public function isInDevMode() {
return false; // Not supported (Files in moodle not editable).
}
/**
* Implements mayUpdateLibraries
*/
// @codingStandardsIgnoreLine
public function mayUpdateLibraries($allow = false) {
static $override;
// Allow overriding the permission check. Needed when installing.
// since caps hasn't been set.
if ($allow) {
$override = true;
}
if ($override) {
return true;
}
$context = \context_system::instance();
if (!has_capability('mod/hvp:updatelibraries', $context)) {
return false;
}
}
/**
* Implements getLibraryUsage
*
* Get number of content/nodes using a library, and the number of
* dependencies to other libraries
*
* @param boolean $skipcontent Optional. Set as true to get number of content instances for library.
* @return array The array contains two elements, keyed by 'content' and 'libraries'.
* Each element contains a number
*/
// @codingStandardsIgnoreLine
public function getLibraryUsage($id, $skipcontent = false) {
global $DB;
$content = intval($DB->get_field_sql(
"SELECT COUNT(distinct c.id)
FROM {hvp_libraries} l
JOIN {hvp_contents_libraries} cl ON l.id = cl.library_id
JOIN {hvp} c ON cl.hvp_id = c.id
WHERE l.id = ?", array($id)
));
}
$libraries = intval($DB->get_field_sql(
"SELECT COUNT(*)
FROM {hvp_libraries_libraries}
WHERE required_library_id = ?", array($id)
));
return array(
'content' => $content,
'libraries' => $libraries,
);
}
/**
Thomas Marstrander
committed
* Implements getLibraryContentCount
*/
// @codingStandardsIgnoreLine
Thomas Marstrander
committed
public function getLibraryContentCount() {
global $DB;
Thomas Marstrander
committed
// Count content using the same content type.
$res = $DB->get_records_sql(
"SELECT c.main_library_id,
l.machine_name,
l.major_version,
l.minor_version,
c.count
FROM (SELECT main_library_id,
count(id) as count
FROM {hvp}
GROUP BY main_library_id) c,
{hvp_libraries} l
WHERE c.main_library_id = l.id"
);
Thomas Marstrander
committed
// Extract results.
foreach ($res as $lib) {
$contentcount["{$lib->machine_name} {$lib->major_version}.{$lib->minor_version}"] = $lib->count;
Thomas Marstrander
committed
}
Thomas Marstrander
committed
}
/**
* Implements saveLibraryData
*/
// @codingStandardsIgnoreLine
public function saveLibraryData(&$librarydata, $new = true) {
global $DB;
// Some special properties needs some checking and converting before they can be saved.
$preloadedjs = $this->pathsToCsv($librarydata, 'preloadedJs');
$preloadedcss = $this->pathsToCsv($librarydata, 'preloadedCss');
if (isset($librarydata['dropLibraryCss'])) {
$libs = array();
foreach ($librarydata['dropLibraryCss'] as $lib) {
$libs[] = $lib['machineName'];
}
$droplibrarycss = implode(', ', $libs);
if (isset($librarydata['embedTypes'])) {
$embedtypes = implode(', ', $librarydata['embedTypes']);
if (!isset($librarydata['semantics'])) {
$librarydata['semantics'] = '';
if (!isset($librarydata['fullscreen'])) {
$librarydata['fullscreen'] = 0;
if (!isset($librarydata['hasIcon'])) {
$librarydata['hasIcon'] = 0;
// TODO: Can we move the above code to H5PCore? It's the same for multiple
// implementations. Perhaps core can update the data objects before calling
// this function?
// I think maybe it's best to do this when classes are created for
// library, content, etc.
$library = (object) array(
'title' => $librarydata['title'],
'machine_name' => $librarydata['machineName'],
'major_version' => $librarydata['majorVersion'],
'minor_version' => $librarydata['minorVersion'],
'patch_version' => $librarydata['patchVersion'],
'runnable' => $librarydata['runnable'],
'fullscreen' => $librarydata['fullscreen'],
'embed_types' => $embedtypes,
'preloaded_js' => $preloadedjs,
'preloaded_css' => $preloadedcss,
'drop_library_css' => $droplibrarycss,
'semantics' => $librarydata['semantics'],
'has_icon' => $librarydata['hasIcon'],
'metadata_settings' => $librarydata['metadataSettings'],
'add_to' => isset($librarydata['addTo']) ? json_encode($librarydata['addTo']) : null,
);
if ($new) {
// Create new library and keep track of id.
$library->id = $DB->insert_record('hvp_libraries', $library);
$librarydata['libraryId'] = $library->id;
} else {
// Update library data.
$library->id = $librarydata['libraryId'];
$DB->update_record('hvp_libraries', (object) $library);
$this->deleteLibraryDependencies($librarydata['libraryId']);
// Log library successfully installed/upgraded.
new \mod_hvp\event(
'library', ($new ? 'create' : 'update'),
$library->machine_name, $library->major_version . '.' . $library->minor_version
);
$DB->delete_records('hvp_libraries_languages', array('library_id' => $librarydata['libraryId']));
if (isset($librarydata['language'])) {
foreach ($librarydata['language'] as $languagecode => $languagejson) {
$DB->insert_record('hvp_libraries_languages', array(
'library_id' => $librarydata['libraryId'],
'language_code' => $languagecode,
'language_json' => $languagejson,
));
}
}
}
/**
* Convert list of file paths to csv
*
* @param array $librarydata
* Library data as found in library.json files
* @param string $key
* Key that should be found in $librarydata
* @return string
* file paths separated by ', '
*/
// @codingStandardsIgnoreLine
private function pathsToCsv($librarydata, $key) {
if (isset($librarydata[$key])) {
$paths = array();
foreach ($librarydata[$key] as $file) {
$paths[] = $file['path'];
}
return implode(', ', $paths);
}
return '';
}
/**
* Implements lockDependencyStorage
*/
// @codingStandardsIgnoreLine
public function lockDependencyStorage() {
// Library development mode not supported.
}
/**
* Implements unlockDependencyStorage
*/
// @codingStandardsIgnoreLine
public function unlockDependencyStorage() {
// Library development mode not supported.
}
/**
* Implements deleteLibrary
*/
// @codingStandardsIgnoreLine
public function deleteLibrary($library) {
global $DB;
// Delete library files.
$librarybase = $this->getH5pPath() . '/libraries/';
$libname = "{$library->name}-{$library->major_version}.{$library->minor_version}";
\H5PCore::deleteFileTree("{$librarybase}{$libname}");
// Remove library data from database.
$DB->delete('hvp_libraries_libraries', array('library_id' => $library->id));
$DB->delete('hvp_libraries_languages', array('library_id' => $library->id));
$DB->delete('hvp_libraries', array('id' => $library->id));
}
/**
* Implements saveLibraryDependencies
// @codingStandardsIgnoreLine
public function saveLibraryDependencies($libraryid, $dependencies, $dependencytype) {
global $DB;
foreach ($dependencies as $dependency) {
// Find dependency library.
$dependencylibrary = $DB->get_record('hvp_libraries', array(
'machine_name' => $dependency['machineName'],
'major_version' => $dependency['majorVersion'],
'minor_version' => $dependency['minorVersion']
));
// Create relation.
$DB->insert_record('hvp_libraries_libraries', array(
'library_id' => $libraryid,
'required_library_id' => $dependencylibrary->id,
'dependency_type' => $dependencytype
));
}
}
/**
// @codingStandardsIgnoreLine
public function updateContent($content, $contentmainid = null) {
global $DB;
if (!isset($content['disable'])) {
$content['disable'] = \H5PCore::DISABLE_NONE;
}
$data = array_merge(\H5PMetadata::toDBArray($content['metadata'], false), array(
'name' => isset($content['metadata']->title) ? $content['metadata']->title : $content['name'],
'course' => $content['course'],
'intro' => $content['intro'],
'introformat' => $content['introformat'],
'json_content' => $content['params'],
'embed_type' => 'div',
'main_library_id' => $content['library']['libraryId'],
'filtered' => '',
'disable' => $content['disable'],
if (!isset($content['id'])) {
$data['slug'] = '';
$data['timecreated'] = $data['timemodified'];
$data['id'] = $content['id'];
$DB->update_record('hvp', $data);
// Log content create/update/upload.
$id, $content['name'],
$content['library']['machineName'],
$content['library']['majorVersion'] . '.' . $content['library']['minorVersion']
);
return $id;
// @codingStandardsIgnoreLine
public function insertContent($content, $contentmainid = null) {
return $this->updateContent($content);
}
/**
// @codingStandardsIgnoreLine
public function resetContentUserData($contentid) {
global $DB;
// Reset user data for this content.
$DB->execute("UPDATE {hvp_content_user_data}
SET data = 'RESET'
WHERE hvp_id = ?
AND delete_on_content_change = 1",
// @codingStandardsIgnoreLine
public function getWhitelist($islibrary, $defaultcontentwhitelist, $defaultlibrarywhitelist) {
return $defaultcontentwhitelist . ($islibrary ? ' ' . $defaultlibrarywhitelist : '');
// @codingStandardsIgnoreLine
public function copyLibraryUsage($contentid, $copyfromid, $contentmainid = null) {