From 1d24d073ed679c3e3ab3662d3c5715cffe12ce33 Mon Sep 17 00:00:00 2001 From: Frode Petterson Date: Thu, 12 Feb 2015 15:56:31 +0100 Subject: [PATCH] Moved "libraries saving" out of savePackage to make it easier to read and handle. Added UI messages when adding and updating libraries. Minor code optimizations. --- h5p.classes.php | 238 ++++++++++++++++++++++++++++++------------------ 1 file changed, 151 insertions(+), 87 deletions(-) diff --git a/h5p.classes.php b/h5p.classes.php index f0ca139..b6d3b37 100644 --- a/h5p.classes.php +++ b/h5p.classes.php @@ -770,15 +770,14 @@ class H5PValidator { // When upgrading, we opnly add allready installed libraries, // and new dependent libraries $upgrades = array(); - foreach ($libraries as &$library) { + foreach ($libraries as $libString => &$library) { // Is this library already installed? - if ($this->h5pF->getLibraryId($library['machineName'], $library['majorVersion'], $library['minorVersion']) !== FALSE) { - $upgrades[H5PCore::libraryToString($library)] = $library; + if ($this->h5pC->getLibraryId($library, $libString) !== FALSE) { + $upgrades[$libString] = $library; } } while ($missingLibraries = $this->getMissingLibraries($upgrades)) { - foreach ($missingLibraries as $missing) { - $libString = H5PCore::libraryToString($missing); + foreach ($missingLibraries as $libString => $missing) { $library = $libraries[$libString]; if ($library) { $upgrades[$libString] = $library; @@ -798,15 +797,15 @@ class H5PValidator { } $missingLibraries = $this->getMissingLibraries($libraries); - foreach ($missingLibraries as $missing) { - if ($this->h5pF->getLibraryId($missing['machineName'], $missing['majorVersion'], $missing['minorVersion'])) { - unset($missingLibraries[H5PCore::libraryToString($missing)]); + foreach ($missingLibraries as $libString => $missing) { + if ($this->h5pC->getLibraryId($missing, $libString)) { + unset($missingLibraries[$libString]); } } if (!empty($missingLibraries)) { - foreach ($missingLibraries as $library) { - $this->h5pF->setErrorMessage($this->h5pF->t('Missing required library @library', array('@library' => H5PCore::libraryToString($library)))); + foreach ($missingLibraries as $libString => $library) { + $this->h5pF->setErrorMessage($this->h5pF->t('Missing required library @library', array('@library' => $libString))); } if (!$this->h5pF->mayUpdateLibraries()) { $this->h5pF->setInfoMessage($this->h5pF->t("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.")); @@ -937,8 +936,9 @@ class H5PValidator { private function getMissingDependencies($dependencies, $libraries) { $missing = array(); foreach ($dependencies as $dependency) { - if (!isset($libraries[H5PCore::libraryToString($dependency)])) { - $missing[H5PCore::libraryToString($dependency)] = $dependency; + $libString = H5PCore::libraryToString($dependency); + if (!isset($libraries[$libString])) { + $missing[$libString] = $dependency; } } return $missing; @@ -1238,75 +1238,15 @@ class H5PStorage { * TRUE if one or more libraries were updated * FALSE otherwise */ - public function savePackage($content = NULL, $contentMainId = NULL, $skipContent = FALSE, $upgradeOnly = FALSE) { - // Save the libraries we processed during validation - $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; - } - elseif ($this->h5pF->isPatchedLibrary($library)) { - $new = FALSE; - $library['libraryId'] = $libraryId; - } - else { - $library['libraryId'] = $libraryId; - // We already have the same or a newer version of this library - $library['saveDependencies'] = FALSE; - continue; - } - - if (!$mayUpdateLibraries) { - // This shouldn't happen, but just to be safe... - continue; - } - - $this->h5pF->saveLibraryData($library, $new); - - $libraries_path = $this->h5pF->getH5pPath() . DIRECTORY_SEPARATOR . 'libraries'; - if (!is_dir($libraries_path)) { - mkdir($libraries_path, 0777, true); - } - $destination_path = $libraries_path . DIRECTORY_SEPARATOR . H5PCore::libraryToString($library, TRUE); - H5PCore::deleteFileTree($destination_path); - $this->h5pC->copyFileTree($library['uploadDirectory'], $destination_path); - H5PCore::deleteFileTree($library['uploadDirectory']); - - $library_saved = TRUE; - } - - foreach ($this->h5pC->librariesJsonData as &$library) { - if ($library['saveDependencies']) { - $this->h5pF->deleteLibraryDependencies($library['libraryId']); - if (isset($library['preloadedDependencies'])) { - $this->h5pF->saveLibraryDependencies($library['libraryId'], $library['preloadedDependencies'], 'preloaded'); - } - if (isset($library['dynamicDependencies'])) { - $this->h5pF->saveLibraryDependencies($library['libraryId'], $library['dynamicDependencies'], 'dynamic'); - } - 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->clearFilteredParameters($library['libraryId']); - - $upgradedLibsCount++; - } + public function savePackage($content = NULL, $contentMainId = NULL, $skipContent = FALSE) { + if ($this->h5pF->mayUpdateLibraries()) { + // Save the libraries we processed during validation + $this->saveLibraries(); } if (!$skipContent) { - $current_path = $this->h5pF->getUploadedH5pFolderPath() . DIRECTORY_SEPARATOR . 'content'; - - // Find out which libraries are used by this package/content - $librariesInUse = array(); - $nextWeight = $this->h5pC->findLibraryDependencies($librariesInUse, $this->h5pC->mainJsonData); + $basePath = $this->h5pF->getUploadedH5pFolderPath(); + $current_path = $basePath . DIRECTORY_SEPARATOR . 'content'; // Save content if ($content === NULL) { @@ -1315,7 +1255,16 @@ class H5PStorage { if (!is_array($content)) { $content = array('id' => $content); } - $content['library'] = $librariesInUse['preloaded-' . $this->h5pC->mainJsonData['mainLibrary']]['library']; + + // Find main library version + foreach ($this->h5pC->mainJsonData['preloadedDependencies'] as $dep) { + if ($dep['machineName'] === $this->h5pC->mainJsonData['mainLibrary']) { + $dep['libraryId'] = $this->h5pC->getLibraryId($dep); + $content['library'] = $dep; + break; + } + } + $content['params'] = file_get_contents($current_path . DIRECTORY_SEPARATOR . 'content.json'); $contentId = $this->h5pC->saveContent($content, $contentMainId); $this->contentId = $contentId; @@ -1328,22 +1277,115 @@ class H5PStorage { // Move the content folder $destination_path = $contents_path . DIRECTORY_SEPARATOR . $contentId; $this->h5pC->copyFileTree($current_path, $destination_path); - H5PCore::deleteFileTree($current_path); - // Save the content library dependencies - $this->h5pF->saveLibraryUsage($contentId, $librariesInUse); - H5PCore::deleteFileTree($this->h5pF->getUploadedH5pFolderPath()); + // Remove temp content folder + H5PCore::deleteFileTree($basePath); } // 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))); + /** + * Helps savePackage. + * + * @return int Number of libraries saved + */ + private function saveLibraries() { + // Keep track of the number of libraries that have been saved + $newOnes = 0; + $oldOnes = 0; + + // Find libraries directory and make sure it exists + $libraries_path = $this->h5pF->getH5pPath() . DIRECTORY_SEPARATOR . 'libraries'; + if (!is_dir($libraries_path)) { + mkdir($libraries_path, 0777, true); } - return $library_saved; + // Go through libraries that came with this package + foreach ($this->h5pC->librariesJsonData as $libString => &$library) { + // Find local library identifier + $libraryId = $this->h5pC->getLibraryId($library, $libString); + + // Assume new library + $new = TRUE; + if ($libraryId) { + // Found old library + $library['libraryId'] = $libraryId; + + if ($this->h5pF->isPatchedLibrary($library)) { + // This is a newer version than ours. Upgrade! + $new = FALSE; + } + else { + $library['saveDependencies'] = FALSE; + // This is an older version, no need to save. + continue; + } + } + + // Indicate that the dependencies of this library should be saved. + $library['saveDependencies'] = TRUE; + + // Save library meta data + $this->h5pF->saveLibraryData($library, $new); + + // Make sure destination dir is free + $destination_path = $libraries_path . DIRECTORY_SEPARATOR . H5PCore::libraryToString($library, TRUE); + H5PCore::deleteFileTree($destination_path); + + // Move library folder + $this->h5pC->copyFileTree($library['uploadDirectory'], $destination_path); + H5PCore::deleteFileTree($library['uploadDirectory']); + + if ($new) { + $newOnes++; + } + else { + $oldOnes++; + } + } + + // Go through the libraries again to save dependencies. + foreach ($this->h5pC->librariesJsonData as &$library) { + if (!$library['saveDependencies']) { + continue; + } + + // TODO: Should the table be locked for this operation? + + // Remove any old dependencies + $this->h5pF->deleteLibraryDependencies($library['libraryId']); + + // Insert the different new ones + if (isset($library['preloadedDependencies'])) { + $this->h5pF->saveLibraryDependencies($library['libraryId'], $library['preloadedDependencies'], 'preloaded'); + } + if (isset($library['dynamicDependencies'])) { + $this->h5pF->saveLibraryDependencies($library['libraryId'], $library['dynamicDependencies'], 'dynamic'); + } + 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->clearFilteredParameters($library['libraryId']); + } + + // Tell the user what we've done. + if ($newOnes && $oldOnes) { + $message = $this->h5pF->t('Added %new new H5P libraries and updated %old old.', array('%new' => $newOnes, '%old' => $oldOnes)); + } + elseif ($newOnes) { + $message = $this->h5pF->t('Added %new new H5P libraries.', array('%new' => $newOnes)); + } + elseif ($oldOnes) { + $message = $this->h5pF->t('Updated %old H5P libraries.', array('%old' => $oldOnes)); + } + + if (isset($message)) { + $this->h5pF->setInfoMessage($message); + } } /** @@ -2220,6 +2262,28 @@ class H5PCore { } } } + + // Cache for getting library ids + private $libraryIdMap = array(); + + /** + * Small helper for getting the library's ID. + * + * @param array $library + * @param string [$libString] + * @return int Identifier, or FALSE if non-existent + */ + public function getLibraryId($library, $libString = NULL) { + if (!$libString) { + $libString = self::libraryToString($library); + } + + if (!isset($libraryIdMap[$libString])) { + $libraryIdMap[$libString] = $this->h5pF->getLibraryId($library['machineName'], $library['majorVersion'], $library['minorVersion']); + } + + return $libraryIdMap[$libString]; + } } /**