From dc2c092bc7b51fe8d7fa8b20313816ac66954390 Mon Sep 17 00:00:00 2001 From: Frode Petterson Date: Tue, 3 Jun 2014 16:07:50 +0200 Subject: [PATCH] Added content upgrade. --- h5p.classes.php | 36 ++++++++++ images/throbber.gif | Bin 0 -> 4782 bytes js/h5p-content-upgrade.js | 147 ++++++++++++++++++++++++++++++++++++++ js/h5p-library-details.js | 2 +- js/h5p-library-list.js | 29 +++++--- js/h5p-utils.js | 13 ++++ styles/h5p-admin.css | 19 +++-- styles/h5p.css | 6 ++ 8 files changed, 237 insertions(+), 15 deletions(-) create mode 100644 images/throbber.gif create mode 100644 js/h5p-content-upgrade.js diff --git a/h5p.classes.php b/h5p.classes.php index 44e9aba..ba1b59a 100644 --- a/h5p.classes.php +++ b/h5p.classes.php @@ -300,6 +300,13 @@ interface H5PFrameworkInterface { * Get content without cache. */ public function getNotCached(); + + /** + * Get number of contents using library as main library. + * + * @param int $library_id + */ + public function getNumContent($library_id); } /** @@ -1719,6 +1726,35 @@ class H5PCore { 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 + */ + public function get_upgrades($library, $versions) { + $upgrades = array(); + + foreach ($versions as $upgrade) { + if ($upgrade->major_version > $library->major_version || $upgrade->major_version === $library->major_version && $upgrade->minor_version > $library->minor_version) { + $upgrades[$upgrade->id] = H5PCore::libraryVersion($upgrade); + } + } + + return $upgrades; + } } /** diff --git a/images/throbber.gif b/images/throbber.gif new file mode 100644 index 0000000000000000000000000000000000000000..0177983f3ffb789cf4556847847856e5369127c0 GIT binary patch literal 4782 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 U^wH6)Yksw`!HOq;H~zE!AJ(jliU0rr literal 0 HcmV?d00001 diff --git a/js/h5p-content-upgrade.js b/js/h5p-content-upgrade.js new file mode 100644 index 0000000..0d7315b --- /dev/null +++ b/js/h5p-content-upgrade.js @@ -0,0 +1,147 @@ +(function ($) { + var info, outData, $container, $throbber, throbberText, majorVersion, minorVersion; + + /** + * Generate html for version select. + * + * @param {Object} versions + * @returns {String} + */ + var getVersionSelect = function (versions) { + var html = ''; + for (var id in versions) { + html += ''; + } + if (html !== '') { + html = ''; + return html; + } + }; + + /** + * Process the current batch of parameters. + * + * @param {Object} params + */ + var processParameters = function (inData) { + var upgraded = {}; + + var i = 0; + for (var id in inData.params) { + if (!inData.params.hasOwnProperty(id)) { + continue; + } + + var param = JSON.parse(inData.params[id]); + for (var major in H5PUpgrades) { + if (!H5PUpgrades.hasOwnProperty(major) || major < info.majorVersion || major > majorVersion) { + continue; + } + + for (var minor in H5PUpgrades[major]) { + if (!H5PUpgrades[major].hasOwnProperty(major) || minor <= info.minorVersion || minor > minorVersion) { + continue; + } + + param = H5PUpgrades[major][minor](param); + } + } + upgraded[id] = JSON.stringify(param); + + i++; + $throbber.text(throbberText + Math.round((info.total - inData.left + i) / (info.total / 100)) + ' %') ; + } + + outData.params = JSON.stringify(upgraded); + outData.token = inData.token; + + // Get next round of data to process. + getParameters(); + }; + + /** + * Handles errors while processing parameters. + * + * @param {Object} params + */ + var process = function (inData) { + // Script is loaded. Start processing. + try { + processParameters(inData); + } + catch (err) { + $container.html('An error occurred while processing parameters: ' + err); + } + }; + + /** + * Get the next batch of parameters. + */ + var getParameters = function () { + $.post(info.url, outData, function (inData) { + if (!(inData instanceof Object)) { + // Print errors from backend + $container.html(inData); + return; + } + if (inData.left === '0') { + $container.html(info.done); + return; + } + + if (inData.script !== undefined) { + $.ajax({ + dataType: 'script', + cache: true, + url: inData.script + }).done(function () { + // Start processing + process(inData); + }).fail(function () { + $container.html('Error: Could not load upgrade script.'); + }); + return; + } + + // Continue processing + process(inData); + }); + }; + + // Initialize + $(document).ready(function () { + // Get library info + info = H5PIntegration.getLibraryInfo(); + + // Get and reset container + $container = $('#h5p-admin-container').html('

' + info.message + '

'); + + // Make it possible to select version + var $version = $(getVersionSelect(info.versions)).appendTo($container); + + // Add "go" button + $('' + - '' + library.title, + library.numContent, + library.numContentDependencies === -1 ? t.NA : library.numContentDependencies, + library.numLibraryDependencies, + '
\ + \ + \ + \ +
' ]); + if (library.upgradeUrl !== null && library.numContent !== '0') { + $('.h5p-admin-upgrade-library', $libraryRow).attr('title', t.upgradeLibrary).click(function () { + window.location.href = library.upgradeUrl; + }); + } + else { + $('.h5p-admin-upgrade-library', $libraryRow).attr('disabled', true); + } + // Open details view when clicked $('.h5p-admin-view-library', $libraryRow).on('click', function () { window.location.href = library.detailsUrl; }); var $deleteButton = $('.h5p-admin-delete-library', $libraryRow); - if (library.contentCount !== 0 || library.libraryDependencyCount !== 0) { + if (library.numContent !== '0' || library.numContentDependencies !== '0' || library.numLibraryDependencies !== '0') { // Disabled delete if content. - $deleteButton.attr('disabled', true); //.addClass('disabled'); + $deleteButton.attr('disabled', true).attr('title', t.deleteLibrary); } else { // Go to delete page om click. diff --git a/js/h5p-utils.js b/js/h5p-utils.js index 5cda763..d8faf68 100644 --- a/js/h5p-utils.js +++ b/js/h5p-utils.js @@ -66,6 +66,19 @@ var H5PUtils = H5PUtils || {}; return template; }; + /** + * Get throbber with given text. + * + * @param {String} text + * @returns {$} + */ + H5PUtils.throbber = function (text) { + return $('
', { + class: 'h5p-throbber', + text: text + }); + }; + /** * Makes it possbile to rebuild all content caches from admin UI. * @param {Object} notCached diff --git a/styles/h5p-admin.css b/styles/h5p-admin.css index 664ddab..6d63c9e 100644 --- a/styles/h5p-admin.css +++ b/styles/h5p-admin.css @@ -47,6 +47,10 @@ text-indent: -0.125em; margin: 0.125em 0.125em 0 0.125em; } +.h5p-admin-upgrade-library:before { + font-family: 'H5P'; + content: "\2191"; +} .h5p-admin-view-library:before { font-family: 'H5P'; content: "\e888"; @@ -56,19 +60,22 @@ content: "\e88e"; } -.h5p-admin-table.libraries button:hover, -.h5p-admin-table.libraries .h5p-admin-delete-library:hover { +.h5p-admin-table.libraries button:hover { background-color: #d0d0d0; } - -.h5p-admin-table.libraries .h5p-admin-delete-library:disabled:hover { +.h5p-admin-table.libraries button:disabled:hover { background-color: #e0e0e0; + cursor: default; } -.h5p-admin-table.libraries .h5p-admin-delete-library { +.h5p-admin-upgrade-library { + color: #0f01f9; +} +.h5p-admin-delete-library { color: #f9010f; } -.h5p-admin-table.libraries .h5p-admin-delete-library:disabled { +.h5p-admin-delete-library:disabled, +.h5p-admin-upgrade-library:disabled { cursor: default; color: #c0c0c0; } diff --git a/styles/h5p.css b/styles/h5p.css index 812aeda..529c4c9 100644 --- a/styles/h5p.css +++ b/styles/h5p.css @@ -313,3 +313,9 @@ div.h5p-fullscreen { margin-left: 0.25em; padding-left: 0.25em; } +.h5p-throbber { + background: url('../images/throbber.gif') left center no-repeat; + padding-left: 38px; + min-height: 30px; + line-height: 30px; +} \ No newline at end of file