diff --git a/setup/modulediscovery.class.inc.php b/setup/modulediscovery.class.inc.php index bb642eb8d..fc86576d4 100644 --- a/setup/modulediscovery.class.inc.php +++ b/setup/modulediscovery.class.inc.php @@ -76,7 +76,7 @@ class ModuleDiscovery 'doc.manual_setup' => 'url', 'doc.more_information' => 'url', ); - + // Cache the results and the source directories protected static $m_aSearchDirs = null; @@ -148,7 +148,7 @@ class ModuleDiscovery self::$m_aModuleVersionByName[$sModuleName]['version'] = $sModuleVersion; self::$m_aModuleVersionByName[$sModuleName]['id'] = $sId; } - + self::$m_aModules[$sId] = $aArgs; // Now keep the relative paths, as provided @@ -220,8 +220,8 @@ class ModuleDiscovery public static function OrderModulesByDependencies($aModules, $bAbortOnMissingDependency = false, $aModulesToLoad = null) { // Order the modules to take into account their inter-dependencies - $aDependencies = array(); - $aSelectedModules = array(); + $aDependencies = []; + $aSelectedModules = []; foreach($aModules as $sId => $aModule) { list($sModuleName, ) = self::GetModuleName($sId); @@ -232,7 +232,7 @@ class ModuleDiscovery } } ksort($aDependencies); - $aOrderedModules = array(); + $aOrderedModules = []; $iLoopCount = 1; while(($iLoopCount < count($aModules)) && (count($aDependencies) > 0) ) { @@ -256,13 +256,24 @@ class ModuleDiscovery } if ($bAbortOnMissingDependency && count($aDependencies) > 0) { - $aModulesInfo = array(); - $aModuleDeps = array(); + $aModulesInfo = []; + $aModuleDeps = []; foreach($aDependencies as $sId => $aDeps) { $aModule = $aModules[$sId]; - $aModuleDeps[] = "{$aModule['label']} (id: $sId) depends on: ".implode(' + ', $aDeps); - $aModulesInfo[$sId] = array('module' => $aModule, 'dependencies' => $aDeps); + $aDepsWithIcons = []; + foreach($aDeps as $sIndex => $sDepId) + { + if (self::DependencyIsResolved($sDepId, $aOrderedModules, $aSelectedModules)) + { + $aDepsWithIcons[$sIndex] = '✅ ' . $sDepId; + } else + { + $aDepsWithIcons[$sIndex] = '❌ ' . $sDepId; + } + } + $aModuleDeps[] = "{$aModule['label']} (id: $sId) depends on: ".implode(' + ', $aDepsWithIcons); + $aModulesInfo[$sId] = array('module' => $aModule, 'dependencies' => $aDepsWithIcons); } $sMessage = "The following modules have unmet dependencies:\n".implode(",\n", $aModuleDeps); $oException = new MissingDependencyException($sMessage); @@ -289,7 +300,7 @@ class ModuleDiscovery // The de-duplication is now done directly by the AddModule method return $aModules; } - + protected static function DependencyIsResolved($sDepString, $aOrderedModules, $aSelectedModules) { $bResult = false; @@ -336,12 +347,12 @@ class ModuleDiscovery if (version_compare($sCurrentVersion, $sExpectedVersion, $sOperator)) { $aReplacements[$sModuleId] = '(true)'; // Add parentheses to protect against invalid condition causing - // a function call that results in a runtime fatal error + // a function call that results in a runtime fatal error } else { $aReplacements[$sModuleId] = '(false)'; // Add parentheses to protect against invalid condition causing - // a function call that results in a runtime fatal error + // a function call that results in a runtime fatal error } } else @@ -400,20 +411,20 @@ class ModuleDiscovery { self::ResetCache(); } - + if (is_null(self::$m_aSearchDirs)) { self::$m_aSearchDirs = $aSearchDirs; - + // Not in cache, let's scan the disk foreach($aSearchDirs as $sSearchDir) { - $sLookupDir = realpath($sSearchDir); + $sLookupDir = realpath($sSearchDir); if ($sLookupDir == '') { throw new Exception("Invalid directory '$sSearchDir'"); } - + clearstatcache(); self::ListModuleFiles(basename($sSearchDir), dirname($sSearchDir)); } @@ -425,7 +436,7 @@ class ModuleDiscovery return self::GetModules($bAbortOnMissingDependency, $aModulesToLoad); } } - + public static function ResetCache() { self::$m_aSearchDirs = null; @@ -437,7 +448,7 @@ class ModuleDiscovery * Helper function to interpret the name of a module * @param $sModuleId string Identifier of the module, in the form 'name/version' * @return array(name, version) - */ + */ public static function GetModuleName($sModuleId) { $aMatches = array(); @@ -466,7 +477,7 @@ class ModuleDiscovery { static $iDummyClassIndex = 0; $sDirectory = $sRootDir.'/'.$sRelDir; - + if ($hDir = opendir($sDirectory)) { // This is the correct way to loop over the directory. (according to the documentation) @@ -502,12 +513,12 @@ class ModuleDiscovery $idx++; } $bRet = eval($sModuleFileContents); - + if ($bRet === false) { SetupLog::Warning("Eval of $sRelDir/$sFile returned false"); } - + //echo "

Done.

\n"; } catch(ParseError $e) @@ -535,7 +546,7 @@ class ModuleDiscovery /** Alias for backward compatibility with old module files in which * the declaration of a module invokes SetupWebPage::AddModule() * whereas the new form is ModuleDiscovery::AddModule() - */ + */ class SetupWebPage extends ModuleDiscovery { // For backward compatibility with old modules... @@ -562,9 +573,9 @@ class SetupWebPage extends ModuleDiscovery public static function log($sText) { SetupLog::Ok($sText); - } + } } - + /** Ugly patch !!! * In order to be able to analyse / load several times * the same module file, we rename the class (to avoid duplicate class definitions)