* @license GPLv2 * @package generis * */ use oat\oatbox\extension\exception\ManifestNotFoundException; class helpers_ExtensionHelper { /** * Based on a list of extensions we generate an array of missing extensions * * @param common_ext_Extension[] $extensions * @return array array of missing extensions ids */ public static function getMissingExtensionIds($extensions) { $inList = []; foreach ($extensions as $ext) { $inList[] = $ext->getId(); } $missing = []; foreach ($extensions as $ext) { foreach ($ext->getDependencies() as $extId => $version) { if (!in_array($extId, $inList) && !in_array($extId, $missing)) { $missing[] = $extId; } } } return $missing; } /** * Sorts a list of extensions by dependencies, * starting with independent extensions * * @param array $extensions * @throws common_exception_Error * @return common_ext_Extension[] */ public static function sortByDependencies($extensions) { $sorted = []; $unsorted = []; foreach ($extensions as $ext) { $unsorted[$ext->getId()] = array_keys($ext->getDependencies()); } while (!empty($unsorted)) { $before = count($unsorted); foreach (array_keys($unsorted) as $id) { $missing = array_diff($unsorted[$id], $sorted); if (empty($missing)) { $sorted[] = $id; unset($unsorted[$id]); } } if (count($unsorted) == $before) { $notfound = array_diff($missing, array_keys($unsorted)); if (!empty($notfound)) { throw new common_exception_Error('Missing extensions ' . implode(',', $notfound) . ' for: ' . implode(',', array_keys($unsorted))); } else { throw new common_exception_Error('Cyclic extension dependencies for: ' . implode(',', array_keys($unsorted))); } } } $returnValue = []; foreach ($sorted as $id) { foreach ($extensions as $ext) { if ($ext->getId() == $id) { $returnValue[$id] = $ext; } } } return $returnValue; } public static function sortById($extensions) { usort($extensions, function ($a, $b) { return strcasecmp($a->getId(), $b->getId()); }); return $extensions; } /** * Whenever or not the extension is required by other installed extensions * * @param common_ext_Extension $extension * @return boolean */ public static function isRequired(common_ext_Extension $extension) { foreach (common_ext_ExtensionsManager::singleton()->getInstalledExtensions() as $ext) { foreach ($ext->getDependencies() as $extId => $version) { if ($extId == $extension->getId()) { return true; } } } return false; } /** * Whenever or not the extension is required to be enabled * by other enabled extensions * * @param common_ext_Extension $extension * @return boolean */ public static function mustBeEnabled(common_ext_Extension $extension) { foreach (common_ext_ExtensionsManager::singleton()->getEnabledExtensions() as $ext) { foreach ($ext->getDependencies() as $extId => $version) { if ($extId == $extension->getId()) { return true; } } } return false; } /** * Check if extension requirements are met * Always returns true, but throws exception on error * * @param common_ext_Extension $extension * @return boolean * @throws ManifestNotFoundException * @throws common_ext_MissingExtensionException */ public static function checkRequiredExtensions(common_ext_Extension $extension) { $extensionManager = common_ext_ExtensionsManager::singleton(); // read direct dependencies from manifest, do not check recursively foreach ($extension->getManifest()->getDependencies() as $requiredExt => $requiredVersion) { if (!$extensionManager->isInstalled($requiredExt)) { throw new common_ext_MissingExtensionException( 'Extension ' . $requiredExt . ' is needed by the extension to be installed but is missing.', 'GENERIS' ); } } // always return true, or throws an exception return true; } }