diff --git a/h5p-development.class.php b/h5p-development.class.php index d599ca1..75e9daf 100644 --- a/h5p-development.class.php +++ b/h5p-development.class.php @@ -30,7 +30,7 @@ class H5PDevelopment { $this->findLibraries($filesPath . '/development'); } } - + /** * Get contents of file. * @@ -41,15 +41,15 @@ class H5PDevelopment { if (file_exists($file) === FALSE) { return NULL; } - + $contents = file_get_contents($file); if ($contents === FALSE) { return NULL; } - + return $contents; } - + /** * Scans development directory and find all libraries. * @@ -57,39 +57,39 @@ class H5PDevelopment { */ private function findLibraries($path) { $this->libraries = array(); - + if (is_dir($path) === FALSE) { - return; + return; } - + $contents = scandir($path); - + for ($i = 0, $s = count($contents); $i < $s; $i++) { if ($contents[$i]{0} === '.') { continue; // Skip hidden stuff. } - + $libraryPath = $path . '/' . $contents[$i]; $libraryJSON = $this->getFileContents($libraryPath . '/library.json'); if ($libraryJSON === NULL) { continue; // No JSON file, skip. } - + $library = json_decode($libraryJSON, TRUE); if ($library === FALSE) { continue; // Invalid JSON. } - + // TODO: Validate props? Not really needed, is it? this is a dev site. - + // Save/update library. $library['libraryId'] = $this->h5pF->getLibraryId($library['machineName'], $library['majorVersion'], $library['minorVersion']); $this->h5pF->saveLibraryData($library, $library['libraryId'] === FALSE); - + $library['path'] = $libraryPath; $this->libraries[H5PDevelopment::libraryToString($library['machineName'], $library['majorVersion'], $library['minorVersion'])] = $library; } - + // TODO: Should we remove libraries without files? Not really needed, but must be cleaned up some time, right? // Go trough libraries and insert dependencies. Missing deps. will just be ignored and not available. (I guess?!) @@ -106,17 +106,17 @@ class H5PDevelopment { } // TODO: Deps must be inserted into h5p_nodes_libraries as well... ? But only if they are used?! } - + /** * @return array Libraris in development folder. */ public function getLibraries() { return $this->libraries; } - + /** * Get library - * + * * @param string $name of the library. * @param int $majorVersion of the library. * @param int $minorVersion of the library. @@ -126,10 +126,10 @@ class H5PDevelopment { $library = H5PDevelopment::libraryToString($name, $majorVersion, $minorVersion); return isset($this->libraries[$library]) === TRUE ? $this->libraries[$library] : NULL; } - + /** * Get semantics for the given library. - * + * * @param string $name of the library. * @param int $majorVersion of the library. * @param int $minorVersion of the library. @@ -137,32 +137,32 @@ class H5PDevelopment { */ public function getSemantics($name, $majorVersion, $minorVersion) { $library = H5PDevelopment::libraryToString($name, $majorVersion, $minorVersion); - + if (isset($this->libraries[$library]) === FALSE) { return NULL; } - + return $this->getFileContents($this->libraries[$library]['path'] . '/semantics.json'); } - + /** * Get translations for the given library. - * + * * @param string $name of the library. * @param int $majorVersion of the library. * @param int $minorVersion of the library. * @return string Translation */ - public function getLanguage($name, $majorVersion, $minorVersion) { + public function getLanguage($name, $majorVersion, $minorVersion, $language) { $library = H5PDevelopment::libraryToString($name, $majorVersion, $minorVersion); - + if (isset($this->libraries[$library]) === FALSE) { return NULL; } - - return $this->getFileContents($this->libraries[$library]['path'] . '/language/' . $this->language . '.json'); + + return $this->getFileContents($this->libraries[$library]['path'] . '/language/' . $language . '.json'); } - + /** * Writes library as string on the form "name majorVersion.minorVersion" * @@ -175,4 +175,3 @@ class H5PDevelopment { return $name . ' ' . $majorVersion . '.' . $minorVersion; } } - diff --git a/h5p.classes.php b/h5p.classes.php index 3cc31ac..a6de0d4 100644 --- a/h5p.classes.php +++ b/h5p.classes.php @@ -55,31 +55,31 @@ interface H5PFrameworkInterface { * @return string Path to the last uploaded h5p */ public function getUploadedH5pPath(); - + /** * Get the list of the current installed libraries - * + * * @return array Associative array containg one item per machine name. This item contains an array of libraries. */ public function loadLibraries(); - + /** * Saving the unsupported library list - * + * * @param array A list of unsupported libraries */ public function setUnsupportedLibraries($libraries); - + /** * Returns unsupported libraries - * + * * @return array A list of the unsupported libraries */ public function getUnsupportedLibraries(); - + /** * Returns the URL to the library admin page - * + * * @return string URL to admin page */ public function getAdminUrl(); @@ -108,7 +108,7 @@ interface H5PFrameworkInterface { * @param string $defaultLibraryWhitelist */ public function getWhitelist($isLibrary, $defaultContentWhitelist, $defaultLibraryWhitelist); - + /** * Is the library a patched version of an existing library? * @@ -147,23 +147,23 @@ interface H5PFrameworkInterface { * Object holding the information that is to be stored */ public function saveLibraryData(&$libraryData, $new = TRUE); - + /** * Insert new content. - * + * * @param object $content * @param int $contentMainId */ public function insertContent($content, $contentMainId = NULL); - + /** * Update old content. - * + * * @param object $content * @param int $contentMainId */ public function updateContent($content, $contentMainId = NULL); - + /** * Save what libraries a library is dependending on * @@ -219,11 +219,11 @@ interface H5PFrameworkInterface { public function saveLibraryUsage($contentId, $librariesInUse); /** - * Get number of content/nodes using a library, and the number of + * Get number of content/nodes using a library, and the number of * dependencies to other libraries - * + * * @param int $library_id - * @return array The array contains two elements, keyed by 'content' and 'libraries'. + * @return array The array contains two elements, keyed by 'content' and 'libraries'. * Each element contains a number */ public function getLibraryUsage($libraryId); @@ -249,7 +249,7 @@ interface H5PFrameworkInterface { * @return string semantics. */ public function loadLibrarySemantics($name, $majorVersion, $minorVersion); - + /** * Makes it possible to alter the semantics, adding custom fields, etc. * @@ -267,21 +267,21 @@ interface H5PFrameworkInterface { * Library Id */ public function deleteLibraryDependencies($libraryId); - + /** * Delete a library from database and file system - * + * * @param mixed $library Library */ public function deleteLibrary($library); - + /** * Load content. * * @return object Content, null if not found. */ public function loadContent($id); - + /** * Load dependencies for the given content of the given type. * @@ -290,49 +290,55 @@ interface H5PFrameworkInterface { * @return array */ public function loadContentDependencies($id, $type = NULL); - + /** - * Get data from cache. - * - * @param string $group - * @param string $key + * Get stored setting. + * + * @param string $name Identifier + * @param string $default Optional + * @return mixed data */ - public function cacheGet($group, $key); - + public function getOption($name, $default = NULL); + /** - * Store data in cache. - * - * @param string $group - * @param string $key - * @param mixed $data + * Stores the given setting. + * For example when did we last check h5p.org for updates to our libraries. + * + * @param string $name Identifier + * @param mixed $value Data */ - public function cacheSet($group, $key, $data); - + public function setOption($name, $value); + /** - * Delete data from cache. - * - * @param string $group - * @param string $key + * This will set the filtered parameters for the given content. + * + * @param int $content_id + * @param string $parameters filtered */ - public function cacheDel($group, $key = NULL); - + public function setFilteredParameters($content_id, $parameters = ''); + /** - * Will invalidate the cache for the content that uses the specified library. - * This means that the content dependencies has to be rebuilt, and the parameters refiltered. - * + * Will clear filtered params for all the content that uses the specified + * library. This means that the content dependencies will have to be rebuilt, + * and the parameters refiltered. + * * @param int $library_id */ - public function invalidateContentCache($library_id); - + public function clearFilteredParameters($library_id); + /** - * Get content without cache. + * Get number of contents that has to get their content dependencies rebuilt + * and parameters refiltered. + * + * @return int */ - public function getNotCached(); - + public function getNumNotFiltered(); + /** * Get number of contents using library as main library. - * + * * @param int $library_id + * @return int */ public function getNumContent($library_id); } @@ -447,14 +453,14 @@ class H5PValidator { // Extract and then remove the package file. $zip = new ZipArchive; - + // Only allow files with the .h5p extension: if (strtolower(substr($tmpPath, -3)) !== 'h5p') { $this->h5pF->setErrorMessage($this->h5pF->t('The file you uploaded is not a valid HTML5 Package (It does not have the .h5p file extension)')); H5PCore::deleteFileTree($tmpDir); return; } - + if ($zip->open($tmpPath) === true) { $zip->extractTo($tmpDir); $zip->close(); @@ -482,7 +488,7 @@ class H5PValidator { if ($skipContent === TRUE) { continue; } - + $mainH5pData = $this->getJsonData($filePath); if ($mainH5pData === FALSE) { $valid = FALSE; @@ -540,7 +546,7 @@ class H5PValidator { } $libraryH5PData = $this->getLibraryData($file, $filePath, $tmpDir); - + if ($libraryH5PData !== FALSE) { // Library's directory name must be: // - @@ -576,7 +582,7 @@ class H5PValidator { } if ($valid) { if ($upgradeOnly) { - // When upgrading, we opnly add allready installed libraries, + // When upgrading, we opnly add allready installed libraries, // and new dependent libraries $upgrades = array(); foreach ($libraries as &$library) { @@ -594,25 +600,25 @@ class H5PValidator { } } } - + $libraries = $upgrades; } - + $this->h5pC->librariesJsonData = $libraries; - + if ($skipContent === FALSE) { $this->h5pC->mainJsonData = $mainH5pData; $this->h5pC->contentJsonData = $contentJsonData; $libraries['mainH5pData'] = $mainH5pData; // Check for the dependencies in h5p.json as well as in the libraries } - + $missingLibraries = $this->getMissingLibraries($libraries); foreach ($missingLibraries as $missing) { if ($this->h5pF->getLibraryId($missing['machineName'], $missing['majorVersion'], $missing['minorVersion'])) { unset($missingLibraries[H5PCore::libraryToString($missing)]); } } - + if (!empty($missingLibraries)) { foreach ($missingLibraries as $library) { $this->h5pF->setErrorMessage($this->h5pF->t('Missing required library @library', array('@library' => H5PCore::libraryToString($library)))); @@ -1021,7 +1027,7 @@ class H5PStorage { public $h5pF; public $h5pC; - + public $contentId = NULL; // Quick fix so WP can get ID of new content. /** @@ -1052,11 +1058,11 @@ class H5PStorage { $library_saved = FALSE; $upgradedLibsCount = 0; $mayUpdateLibraries = $this->h5pF->mayUpdateLibraries(); - + foreach ($this->h5pC->librariesJsonData as &$library) { $libraryId = $this->h5pF->getLibraryId($library['machineName'], $library['majorVersion'], $library['minorVersion']); $library['saveDependencies'] = TRUE; - + if (!$libraryId) { $new = TRUE; } @@ -1101,21 +1107,21 @@ class H5PStorage { if (isset($library['editorDependencies'])) { $this->h5pF->saveLibraryDependencies($library['libraryId'], $library['editorDependencies'], 'editor'); } - + // Make sure libraries dependencies, parameter filtering and export files gets regenerated for all content who uses this library. - $this->h5pF->invalidateContentCache($library['libraryId']); - + $this->h5pF->clearFilteredParameters($library['libraryId']); + $upgradedLibsCount++; } } - + if (!$skipContent) { $current_path = $this->h5pF->getUploadedH5pFolderPath() . DIRECTORY_SEPARATOR . 'content'; - + // Find out which libraries are used by this package/content $librariesInUse = array(); $this->h5pC->findLibraryDependencies($librariesInUse, $this->h5pC->mainJsonData); - + // Save content if ($content === NULL) { $content = array(); @@ -1132,19 +1138,19 @@ class H5PStorage { if (!is_dir($contents_path)) { mkdir($contents_path, 0777, true); } - + // Move the content folder $destination_path = $contents_path . DIRECTORY_SEPARATOR . $contentId; @rename($current_path, $destination_path); - + // Save the content library dependencies $this->h5pF->saveLibraryUsage($contentId, $librariesInUse); H5PCore::deleteFileTree($this->h5pF->getUploadedH5pFolderPath()); } - + // Update supported library list if neccessary: $this->h5pC->validateLibrarySupport(TRUE); - + if ($upgradeOnly) { // TODO - support translation $this->h5pF->setInfoMessage($this->h5pF->t('@num libraries were upgraded!', array('@num' => $upgradedLibsCount))); @@ -1152,7 +1158,7 @@ class H5PStorage { return $library_saved; } - + /** * Delete an H5P package * @@ -1221,7 +1227,7 @@ Class H5PExport { $this->h5pF = $H5PFramework; $this->h5pC = $H5PCore; } - + /** * Return path to h5p package. * @@ -1234,7 +1240,7 @@ Class H5PExport { $h5pDir = $this->h5pF->getH5pPath() . DIRECTORY_SEPARATOR; $tempPath = $h5pDir . 'temp' . DIRECTORY_SEPARATOR . $content['id']; $zipPath = $h5pDir . 'exports' . DIRECTORY_SEPARATOR . $content['id'] . '.h5p'; - + // Temp dir to put the h5p files in @mkdir($tempPath, 0777, TRUE); @mkdir($h5pDir . 'exports', 0777, TRUE); @@ -1251,8 +1257,8 @@ Class H5PExport { // Build h5p.json $h5pJson = array ( 'title' => $content['title'], - // TODO - stop using 'und', this is not the preferred way. - // Either remove language from the json if not existing, or use "language": null + // TODO - stop using 'und', this is not the preferred way. + // Either remove language from the json if not existing, or use "language": null 'language' => isset($content['language']) ? $content['language'] : 'und', 'mainLibrary' => $content['library']['name'], 'embedTypes' => $embedTypes, @@ -1261,7 +1267,7 @@ Class H5PExport { // Add dependencies to h5p foreach ($content['dependencies'] as $dependency) { $library = $dependency['library']; - + // Copy library to h5p $source = isset($library['path']) ? $library['path'] : $h5pDir . 'libraries' . DIRECTORY_SEPARATOR . H5PCore::libraryToString($library, TRUE); $destination = $tempPath . DIRECTORY_SEPARATOR . $library['machineName']; @@ -1269,7 +1275,7 @@ Class H5PExport { // Do not add editor dependencies to h5p json. if ($dependency['type'] === 'editor') { - continue; + continue; } $h5pJson[$dependency['type'] . 'Dependencies'][] = array( @@ -1333,7 +1339,7 @@ Class H5PExport { */ private function addEditorLibraries($libraries, $editorLibraries) { foreach ($editorLibraries as $editorLibrary) { - $libraries[$editorLibrary['machineName']] = $editorLibrary; + $libraries[$editorLibrary['machineName']] = $editorLibrary; } return $libraries; } @@ -1378,12 +1384,12 @@ class H5PCore { */ public function __construct($H5PFramework, $path, $language = 'en', $export = FALSE, $development_mode = H5PDevelopment::MODE_NONE) { $this->h5pF = $H5PFramework; - + $this->h5pF = $H5PFramework; $this->path = $path; $this->exportEnabled = $export; $this->development_mode = $development_mode; - + if ($development_mode & H5PDevelopment::MODE_LIBRARY) { $this->h5pD = new H5PDevelopment($this->h5pF, $path, $language); } @@ -1391,7 +1397,7 @@ class H5PCore { /** * Save content and clear cache. - * + * * @param array $content * @return int Content ID */ @@ -1400,17 +1406,12 @@ class H5PCore { $this->h5pF->updateContent($content, $contentMainId); } else { - $content['id'] = $this->h5pF->insertContent($content, $contentMainId); + $content['id'] = $this->h5pF->insertContent($content, $contentMainId); } - - if (!isset($content['filtered'])) { - // TODO: Add filtered to all impl. and remove - $this->h5pF->cacheDel('parameters', $content['id']); - } - + return $content['id']; } - + /** * Load content. * @@ -1419,7 +1420,7 @@ class H5PCore { */ public function loadContent($id) { $content = $this->h5pF->loadContent($id); - + if ($content !== NULL) { $content['library'] = array( 'id' => $content['libraryId'], @@ -1430,7 +1431,7 @@ class H5PCore { 'fullscreen' => $content['libraryFullscreen'], ); unset($content['libraryId'], $content['libraryName'], $content['libraryEmbedTypes'], $content['libraryFullscreen']); - + // // TODO: Move to filterParameters? // if ($this->development_mode & H5PDevelopment::MODE_CONTENT) { // // TODO: Remove Drupal specific stuff @@ -1444,29 +1445,21 @@ class H5PCore { // } // } } - + return $content; } - + /** * Filter content run parameters, rebuild content dependecy cache and export file. - * + * * @param Object $content * @return Object NULL on failure. */ public function filterParameters($content) { - if (isset($content['filtered'])) { - $params = ($content['filtered'] === '' ? NULL : $content['filtered']); - } - else { - // TODO: Add filtered to all impl. and remove - $params = $this->h5pF->cacheGet('parameters', $content['id']); + if (isset($content['filtered']) && $content['filtered'] !== '') { + return $content['filtered']; } - if ($params !== NULL) { - return $params; - } - // Validate and filter against main library semantics. $validator = new H5PContentValidator($this->h5pF, $this); $params = (object) array( @@ -1476,25 +1469,25 @@ class H5PCore { $validator->validateLibrary($params, (object) array('options' => array($params->library))); $params = json_encode($params->params); - + // Update content dependencies. $content['dependencies'] = $validator->getDependencies(); $this->h5pF->deleteLibraryUsage($content['id']); $this->h5pF->saveLibraryUsage($content['id'], $content['dependencies']); - + if ($this->exportEnabled) { // Recreate export file $exporter = new H5PExport($this->h5pF, $this); $exporter->createExportFile($content); - + // TODO: Should we rather create the file once first accessed, like imagecache? } // Cache. - $this->h5pF->cacheSet('parameters', $content['id'], $params); + $this->h5pF->setFilteredParameters($content['id'], $params); return $params; } - + /** * Find the files required for this content to work. * @@ -1503,10 +1496,10 @@ class H5PCore { */ public function loadContentDependencies($id, $type = NULL) { $dependencies = $this->h5pF->loadContentDependencies($id, $type); - + if ($this->development_mode & H5PDevelopment::MODE_LIBRARY) { $developmentLibraries = $this->h5pD->getLibraries(); - + foreach ($dependencies as $key => $dependency) { $libraryString = H5PCore::libraryToString($dependency); if (isset($developmentLibraries[$libraryString])) { @@ -1515,13 +1508,13 @@ class H5PCore { } } } - + return $dependencies; } - + /** * Get all dependency assets of the given type - * + * * @param array $dependency * @param string $type * @param array $assets @@ -1531,12 +1524,12 @@ class H5PCore { if (empty($dependency[$type]) || $dependency[$type][0] === '') { return; } - + // Check if we should skip CSS. if ($type === 'preloadedCss' && (isset($dependency['dropCss']) && $dependency['dropCss'] === '1')) { return; } - + foreach ($dependency[$type] as $file) { $assets[] = (object) array( 'path' => $dependency['path'] . '/' . trim(is_array($file) ? $file['path'] : $file), @@ -1544,23 +1537,23 @@ class H5PCore { ); } } - + /** * Combines path with cache buster / version. - * + * * @param array $assets * @return array */ public function getAssetsUrls($assets) { $urls = array(); - + foreach ($assets as $asset) { $urls[] = $asset->path . $asset->version; } - + return $urls; } - + /** * Return file paths for all dependecies files. * @@ -1578,14 +1571,14 @@ class H5PCore { $dependency['preloadedJs'] = explode(',', $dependency['preloadedJs']); $dependency['preloadedCss'] = explode(',', $dependency['preloadedCss']); } - + $dependency['version'] = "?ver={$dependency['majorVersion']}.{$dependency['minorVersion']}.{$dependency['patchVersion']}"; $this->getDependencyAssets($dependency, 'preloadedJs', $files['scripts']); $this->getDependencyAssets($dependency, 'preloadedCss', $files['styles']); } return $files; } - + /** * Load library semantics. * @@ -1597,20 +1590,20 @@ class H5PCore { // Try to load from dev lib $semantics = $this->h5pD->getSemantics($name, $majorVersion, $minorVersion); } - + if ($semantics === NULL) { // Try to load from DB. $semantics = $this->h5pF->loadLibrarySemantics($name, $majorVersion, $minorVersion); } - + if ($semantics !== NULL) { $semantics = json_decode($semantics); $this->h5pF->alterLibrarySemantics($semantics, $name, $majorVersion, $minorVersion); } - + return $semantics; } - + /** * Load library. * @@ -1625,31 +1618,31 @@ class H5PCore { $library['semantics'] = $this->h5pD->getSemantics($name, $majorVersion, $minorVersion); } } - + if ($library === NULL) { // Try to load from DB. $library = $this->h5pF->loadLibrary($name, $majorVersion, $minorVersion); } - + return $library; } - + /** * Deletes a library - * + * * @param unknown $libraryId */ public function deleteLibrary($libraryId) { $this->h5pF->deleteLibrary($libraryId); - + // Force update of unsupported libraries list: $this->validateLibrarySupport(TRUE); } - + /** - * Recursive. Goes through the dependency tree for the given library and + * Recursive. Goes through the dependency tree for the given library and * adds all the dependencies to the given array in a flat format. - * + * * @param array $librariesUsed Flat list of all dependencies. * @param array $library To find all dependencies for. * @param bool $editor Used interally to force all preloaded sub dependencies of an editor dependecy to be editor dependencies. @@ -1660,18 +1653,18 @@ class H5PCore { if (!isset($library[$property])) { continue; // Skip, no such dependencies. } - + if ($type === 'preloaded' && $editor === TRUE) { // All preloaded dependencies of an editor library is set to editor. $type = 'editor'; } - + foreach ($library[$property] as $dependency) { $dependencyKey = $type . '-' . $dependency['machineName']; if (isset($dependencies[$dependencyKey]) === TRUE) { continue; // Skip, already have this. } - + $dependencyLibrary = $this->loadLibrary($dependency['machineName'], $dependency['majorVersion'], $dependency['minorVersion']); if ($dependencyLibrary) { $dependencies[$dependencyKey] = array( @@ -1800,7 +1793,7 @@ class H5PCore { } return FALSE; } - + /** * Determine the correct embed type to use. * @@ -1809,32 +1802,32 @@ class H5PCore { public static function determineEmbedType($contentEmbedType, $libraryEmbedTypes) { // Detect content embed type $embedType = strpos(strtolower($contentEmbedType), 'div') !== FALSE ? 'div' : 'iframe'; - + if ($libraryEmbedTypes !== NULL && $libraryEmbedTypes !== '') { // Check that embed type is available for library $embedTypes = strtolower($libraryEmbedTypes); if (strpos($embedTypes, $embedType) === FALSE) { // Not available, pick default. $embedType = strpos($embedTypes, 'div') !== FALSE ? 'div' : 'iframe'; - } + } } - + return $embedType; } - + /** * Get the absolute version for the library as a human readable string. - * + * * @param object $library * @return string */ public static function libraryVersion($library) { return $library->major_version . '.' . $library->minor_version . '.' . $library->patch_version; } - + /** * Detemine which versions content with the given library can be upgraded to. - * + * * @param object $library * @param array $versions * @return array @@ -1850,13 +1843,13 @@ class H5PCore { return $upgrades; } - + /** * Converts all the properties of the given object or array from * snake_case to camelCase. Useful after fetching data from the database. - * + * * Note that some databases does not support camelCase. - * + * * @param mixed $arr input * @param boolean $obj return object * @return mixed object or array @@ -1875,36 +1868,36 @@ class H5PCore { return $obj ? (object) $newArr : $newArr; } - + /** * Check if currently installed H5P libraries are supported by * the current versjon of core. Which versions of which libraries are supported is * defined in the library-support.json file. * - * @param boolean If TRUE, unsupported libraries list are rebuilt. If FALSE, list is + * @param boolean If TRUE, unsupported libraries list are rebuilt. If FALSE, list is * rebuilt only if non-existing */ public function validateLibrarySupport($force = false) { if (!($this->h5pF->getUnsupportedLibraries() === NULL || $force)) { return; } - + $minVersions = $this->getMinimumVersionsSupported(realpath(dirname(__FILE__)) . '/library-support.json'); if ($minVersions === NULL) { return; } - + // Get all libraries installed, check if any of them is not supported: $libraries = $this->h5pF->loadLibraries(); $unsupportedLibraries = array(); - + // Iterate over all installed libraries foreach ($libraries as $library_name => $versions) { if (!isset($minVersions[$library_name])) { continue; } $min = $minVersions[$library_name]; - + // For each version of this library, check if it is supported foreach ($versions as $library) { if (!$this->isLibraryVersionSupported($library, $min->versions)) { @@ -1920,23 +1913,23 @@ class H5PCore { ); } } - + $this->h5pF->setUnsupportedLibraries(empty($unsupportedLibraries) ? NULL : $unsupportedLibraries); } } - + /** * Returns a list of the minimum version of libraries that are supported. * This is needed because some old libraries are no longer supported by core. - * + * * TODO: Make it possible for the systems to cache this list between requests. - * + * * @param string $path to json file * @return array indexed using library names */ public function getMinimumVersionsSupported($path) { $minSupported = array(); - + // Get list of minimum version for libraries. Some old libraries are no longer supported. $libraries = file_get_contents($path); if ($libraries !== FALSE) { @@ -1950,13 +1943,13 @@ class H5PCore { } } } - + return empty($minSupported) ? NULL : $minSupported; } - + /** * Check if a specific version of a library is supported - * + * * @param object library * @param array An array containing versions * @return boolean TRUE if supported, otherwise FALSE @@ -1969,37 +1962,37 @@ class H5PCore { // --- minor is higher than any minimumversion for a given major // --- major and minor equals and patch is >= supported $major_supported |= ($library->major_version > $minimumVersion->major); - + if ($library->major_version == $minimumVersion->major) { $minor_supported |= ($library->minor_version > $minimumVersion->minor); } - + if ($library->major_version == $minimumVersion->major && $library->minor_version == $minimumVersion->minor) { $patch_supported |= ($library->patch_version >= $minimumVersion->patch); } } - + return ($patch_supported || $minor_supported || $major_supported); } - + /** - * Helper function for creating markup for the unsupported libraries list - * + * Helper function for creating markup for the unsupported libraries list + * * TODO: Make help text translatable - * + * * @return string Html * */ public function createMarkupForUnsupportedLibraryList($libraries) { $html = '
The following versions of H5P libraries are not supported anymore:
    '; - + foreach ($libraries as $library) { $downloadUrl = $library['downloadUrl']; $libraryName = $library['name']; $currentVersion = $library['currentVersion']['major'] . '.' . $library['currentVersion']['minor'] .'.' . $library['currentVersion']['patch']; $html .= "
  • $libraryName ($currentVersion)
  • "; } - + $html .= '

These libraries may cause problems on this site. See here for more info
'; return $html; } @@ -2038,24 +2031,24 @@ class H5PContentValidator { 'select' => 'validateSelect', 'library' => 'validateLibrary', ); - + // Keep track of the libraries we load to avoid loading it multiple times. $this->libraries = array(); // TODO: Should this possible be done in core's loadLibrary? This might be done multiple places. - + // Keep track of all dependencies for the given content. $this->dependencies = array(); } /** * Get the flat dependecy tree. - * + * * @return array */ public function getDependencies() { return $this->dependencies; } - + /** * Validate given text value against text semantics. */ @@ -2280,19 +2273,19 @@ class H5PContentValidator { $validkeys = array_merge($validkeys, $semantics->extraAttributes); // TODO: Validate extraAttributes } $this->filterParams($file, $validkeys); - + if (isset($file->width)) { $file->width = intval($file->width); } - + if (isset($file->height)) { $file->height = intval($file->height); } - + if (isset($file->codecs)) { $file->codecs = htmlspecialchars($file->codecs, ENT_QUOTES, 'UTF-8', FALSE); } - + if (isset($file->quality)) { if (!is_object($file->quality) || !isset($file->quality->level) || !isset($file->quality->label)) { unset($file->quality); @@ -2303,7 +2296,7 @@ class H5PContentValidator { $file->quality->label = htmlspecialchars($file->quality->label, ENT_QUOTES, 'UTF-8', FALSE); } } - + if (isset($file->copyright)) { $this->validateGroup($file->copyright, H5PContentValidator::getCopyrightSemantics()); } @@ -2406,11 +2399,11 @@ class H5PContentValidator { $value = new stdClass(); return; } - + if (!isset($this->libraries[$value->library])) { $libspec = H5PCore::libraryFromString($value->library); $library = $this->h5pC->loadLibrary($libspec['machineName'], $libspec['majorVersion'], $libspec['minorVersion']); - $library['semantics'] = json_decode($library['semantics']); + $library['semantics'] = $this->h5pC->loadLibrarySemantics($libspec['machineName'], $libspec['majorVersion'], $libspec['minorVersion']); $this->libraries[$value->library] = $library; // Find all dependencies for this library @@ -2700,7 +2693,7 @@ class H5PContentValidator { /** * Processes an HTML attribute value and strips dangerous protocols from URLs. - * + * * @param $string * The string with the attribute value. * @param $decode @@ -2773,10 +2766,10 @@ class H5PContentValidator { return $uri; } - + public static function getCopyrightSemantics() { static $semantics; - + if ($semantics === NULL) { $semantics = (object) array( 'name' => 'copyright', @@ -2874,7 +2867,7 @@ class H5PContentValidator { ) ); } - + return $semantics; } } diff --git a/js/h5p-content-upgrade.js b/js/h5p-content-upgrade.js index c5cd02a..ff3756f 100644 --- a/js/h5p-content-upgrade.js +++ b/js/h5p-content-upgrade.js @@ -213,18 +213,28 @@ var H5PUpgrades = H5PUpgrades || {}; var current = 0; // Track progress asyncSerial(parameters, function (id, params, next) { - // Make params possible to work with - params = JSON.parse(params); + try { + // Make params possible to work with + params = JSON.parse(params); + if (!(params instanceof Object)) { + throw true; + } + } + catch (event) { + return next(info.errorContent.replace('%id', id) + ' ' + info.errorParamsBroken); + } // Upgrade this content. self.upgrade(info.library.name, new Version(info.library.version), self.version, params, function (err, params) { - if (!err) { - upgraded[id] = JSON.stringify(params); - - current++; - self.throbber.setProgress(Math.round((info.total - self.left + current) / (info.total / 100)) + ' %'); + if (err) { + return next(info.errorContent.replace('%id', id) + ' ' + err); } - next(err); + + upgraded[id] = JSON.stringify(params); + + current++; + self.throbber.setProgress(Math.round((info.total - self.left + current) / (info.total / 100)) + ' %'); + next(); }); }, function (err) { @@ -375,14 +385,16 @@ var H5PUpgrades = H5PUpgrades || {}; } else { // We found an upgrade hook, run it - if (upgrade.contentUpgrade !== undefined && typeof upgrade.contentUpgrade === 'function') { - upgrade.contentUpgrade(params, function (err, upgradedParams) { + var unnecessaryWrapper = (upgrade.contentUpgrade !== undefined ? upgrade.contentUpgrade : upgrade); + + try { + unnecessaryWrapper(params, function (err, upgradedParams) { params = upgradedParams; nextMinor(err); }); } - else { - nextMinor(info.errorScript.replace('%lib', library.name + ' ' + newVersion)); + catch (err) { + next(err); } } }, nextMajor); diff --git a/styles/h5p-admin.css b/styles/h5p-admin.css index 44310b0..219309a 100644 --- a/styles/h5p-admin.css +++ b/styles/h5p-admin.css @@ -244,4 +244,7 @@ button.h5p-admin.disabled:hover { padding: 0 0.5em; font-size: 1.5em; font-weight: bold; -} \ No newline at end of file +} +#h5p-admin-container .h5p-admin-center { + text-align: center; +}