Support namespaces/constructor.

namespaces
Frode Petterson 2015-02-17 09:32:11 +01:00
parent 84f8fb1cff
commit 5e56b46696
2 changed files with 79 additions and 27 deletions

View File

@ -14,7 +14,7 @@ interface H5PFrameworkInterface {
* - h5pVersion: The version of the H5P plugin/module * - h5pVersion: The version of the H5P plugin/module
*/ */
public function getPlatformInfo(); public function getPlatformInfo();
/** /**
* Fetches a file from a remote server using HTTP GET * Fetches a file from a remote server using HTTP GET
@ -223,7 +223,7 @@ interface H5PFrameworkInterface {
* - language(optional): associative array containing: * - language(optional): associative array containing:
* - languageCode: Translation in json format * - languageCode: Translation in json format
*/ */
public function saveLibraryData(&$libraryData, $new = TRUE); public function saveLibraryData(&$libraryData, $preloadedJs, $preloadedCss, $dropLibraryCss, $embedTypes);
/** /**
* Insert new content. * Insert new content.
@ -610,6 +610,7 @@ class H5PValidator {
'majorVersion' => '/^[0-9]{1,5}$/', 'majorVersion' => '/^[0-9]{1,5}$/',
'minorVersion' => '/^[0-9]{1,5}$/', 'minorVersion' => '/^[0-9]{1,5}$/',
), ),
'constructor' => '/^[A-Z][a-zA-Z0-9]{1,126}$/',
); );
/** /**
@ -1308,28 +1309,28 @@ class H5PStorage {
// Find local library identifier // Find local library identifier
$libraryId = $this->h5pC->getLibraryId($library, $libString); $libraryId = $this->h5pC->getLibraryId($library, $libString);
// Assume new library
$new = TRUE;
if ($libraryId) { if ($libraryId) {
// Found old library // Found old library
$library['libraryId'] = $libraryId; $library['libraryId'] = $libraryId;
if ($this->h5pF->isPatchedLibrary($library)) { if (!$this->h5pF->isPatchedLibrary($library)) {
// This is a newer version than ours. Upgrade!
$new = FALSE;
}
else {
$library['saveDependencies'] = FALSE; $library['saveDependencies'] = FALSE;
// This is an older version, no need to save. // This is an older version, no need to save.
continue; continue;
} }
$oldOnes++;
} }
else {
$newOnes++;
}
// This is a new library or a newer version, save it!
// Indicate that the dependencies of this library should be saved. // Indicate that the dependencies of this library should be saved.
$library['saveDependencies'] = TRUE; $library['saveDependencies'] = TRUE;
// Save library meta data // Save library meta data
$this->h5pF->saveLibraryData($library, $new); $this->saveLibrary($library);
// Make sure destination dir is free // Make sure destination dir is free
$destination_path = $libraries_path . DIRECTORY_SEPARATOR . H5PCore::libraryToString($library, TRUE); $destination_path = $libraries_path . DIRECTORY_SEPARATOR . H5PCore::libraryToString($library, TRUE);
@ -1338,13 +1339,6 @@ class H5PStorage {
// Move library folder // Move library folder
$this->h5pC->copyFileTree($library['uploadDirectory'], $destination_path); $this->h5pC->copyFileTree($library['uploadDirectory'], $destination_path);
H5PCore::deleteFileTree($library['uploadDirectory']); H5PCore::deleteFileTree($library['uploadDirectory']);
if ($new) {
$newOnes++;
}
else {
$oldOnes++;
}
} }
// Go through the libraries again to save dependencies. // Go through the libraries again to save dependencies.
@ -1389,6 +1383,54 @@ class H5PStorage {
} }
} }
/**
* Write library record to database.
*
* @param array $library
*/
private function saveLibrary($library) {
// Get CSV values to store in rows.
$preloadedJs = $this->objectsToCsv($library, 'preloadedJs', 'path');
$preloadedCss = $this->objectsToCsv($library, 'preloadedCss', 'path');
$dropLibraryCss = $this->objectsToCsv($library, 'dropLibraryCss', 'machineName');
$embedTypes = $this->objectsToCsv($library, 'dropLibraryCss');
if (!isset($library['semantics'])) {
$library['semantics'] = '';
}
if (!isset($library['fullscreen'])) {
$library['fullscreen'] = 0;
}
if (!isset($library['constructor'])) {
$library['constructor'] = '';
}
$this->h5pF->saveLibraryData($library, $preloadedJs, $preloadedCss, $dropLibraryCss, $embedTypes);
}
/**
* Converts file list to comma separated values.
*
* @param array $library
* @param string $list identifier
* @param string $property (optional) Object property to use as value
* @return string
*/
private function objectsToCsv($library, $list, $property = NULL) {
$csv = '';
if (isset($library[$list])) {
foreach ($library[$list] as $object) {
if ($csv !== '') {
$csv .= ', ';
}
$csv .= $property === NULL ? $object : $object[$property];
}
}
return $csv;
}
/** /**
* Delete an H5P package * Delete an H5P package
* *
@ -1659,6 +1701,7 @@ class H5PCore {
$content['library'] = array( $content['library'] = array(
'id' => $content['libraryId'], 'id' => $content['libraryId'],
'name' => $content['libraryName'], 'name' => $content['libraryName'],
'constructor' => $content['libraryConstructor'],
'majorVersion' => $content['libraryMajorVersion'], 'majorVersion' => $content['libraryMajorVersion'],
'minorVersion' => $content['libraryMinorVersion'], 'minorVersion' => $content['libraryMinorVersion'],
'embedTypes' => $content['libraryEmbedTypes'], 'embedTypes' => $content['libraryEmbedTypes'],
@ -2709,11 +2752,16 @@ class H5PContentValidator {
$library = $this->libraries[$value->library]; $library = $this->libraries[$value->library];
} }
if ($library['constructor']) {
// Update constructor
$value->constructor = $library['constructor'];
}
$this->validateGroup($value->params, (object) array( $this->validateGroup($value->params, (object) array(
'type' => 'group', 'type' => 'group',
'fields' => $library['semantics'], 'fields' => $library['semantics'],
), FALSE); ), FALSE);
$validkeys = array('library', 'params'); $validkeys = array('library', 'constructor', 'params');
if (isset($semantics->extraAttributes)) { if (isset($semantics->extraAttributes)) {
$validkeys = array_merge($validkeys, $semantics->extraAttributes); $validkeys = array_merge($validkeys, $semantics->extraAttributes);
} }

View File

@ -55,6 +55,7 @@ H5P.init = function () {
} }
var library = { var library = {
library: contentData.library, library: contentData.library,
constructor: contentData.constructor,
params: JSON.parse(contentData.jsonContent) params: JSON.parse(contentData.jsonContent)
}; };
@ -165,7 +166,7 @@ H5P.init = function () {
* 3. Create a separate Drupal module that is able to listen for events from * 3. Create a separate Drupal module that is able to listen for events from
* both div and iframe embedded content and send them to analytics (custom for Zavango) * both div and iframe embedded content and send them to analytics (custom for Zavango)
* 4. Move the event system code to a separate file (public) * 4. Move the event system code to a separate file (public)
* 5. Make sure the helper functions provides all the relevant data, example values * 5. Make sure the helper functions provides all the relevant data, example values
* and time spent (public) * and time spent (public)
* 6. Add documentation to the functions (public) * 6. Add documentation to the functions (public)
* 7. Add xAPI events to all the basic questiontype: * 7. Add xAPI events to all the basic questiontype:
@ -396,6 +397,9 @@ H5P.newRunnable = function (library, contentId, $attachTo, skipResize) {
var constructor; var constructor;
try { try {
nameSplit = nameSplit[0].split('.'); nameSplit = nameSplit[0].split('.');
if (typeof library.constructor === 'string') {
nameSplit.push(library.constructor);
}
constructor = window; constructor = window;
for (var i = 0; i < nameSplit.length; i++) { for (var i = 0; i < nameSplit.length; i++) {
constructor = constructor[nameSplit[i]]; constructor = constructor[nameSplit[i]];
@ -409,7 +413,7 @@ H5P.newRunnable = function (library, contentId, $attachTo, skipResize) {
} }
var instance = new constructor(library.params, contentId); var instance = new constructor(library.params, contentId);
if (instance.$ === undefined) { if (instance.$ === undefined) {
instance.$ = H5P.jQuery(instance); instance.$ = H5P.jQuery(instance);
} }
@ -442,7 +446,7 @@ H5P.newRunnable = function (library, contentId, $attachTo, skipResize) {
* @returns {undefined} * @returns {undefined}
*/ */
H5P.error = function (err) { H5P.error = function (err) {
if (window['console'] !== undefined && console.error !== undefined) { if (window.console !== undefined && console.error !== undefined) {
console.error(err); console.error(err);
} }
}; };
@ -1087,7 +1091,7 @@ H5P.setFinished = function (contentId, score, maxScore, time) {
var toUnix = function (date) { var toUnix = function (date) {
return Math.round(date.getTime() / 1000); return Math.round(date.getTime() / 1000);
}; };
// Post the results // Post the results
// TODO: Should we use a variable with the complete path? // TODO: Should we use a variable with the complete path?
H5P.jQuery.post(H5P.ajaxPath + 'setFinished', { H5P.jQuery.post(H5P.ajaxPath + 'setFinished', {
@ -1134,9 +1138,9 @@ if (H5P.jQuery) {
/** /**
* Trigger an event on an instance * Trigger an event on an instance
* *
* Helper function that triggers an event if the instance supports event handling * Helper function that triggers an event if the instance supports event handling
* *
* @param {function} instance * @param {function} instance
* An H5P instance * An H5P instance
* @param {string} eventType * @param {string} eventType
@ -1155,10 +1159,10 @@ H5P.trigger = function(instance, eventType) {
/** /**
* Register an event handler * Register an event handler
* *
* Helper function that registers an event handler for an event type if * Helper function that registers an event handler for an event type if
* the instance supports event handling * the instance supports event handling
* *
* @param {function} instance * @param {function} instance
* An h5p instance * An h5p instance
* @param {string} eventType * @param {string} eventType
@ -1175,4 +1179,4 @@ H5P.on = function(instance, eventType, handler) {
else if (instance.$ !== undefined && instance.$.on !== undefined) { else if (instance.$ !== undefined && instance.$.on !== undefined) {
instance.$.on(eventType, handler) instance.$.on(eventType, handler)
} }
}; };