Get('steps', []); if (!is_array($aSteps)) { return []; } $aInstalledModuleNames = $this->FindInstalledPackageModules($aPackageModules, $aInstallationChoices, $aSteps); } else { $aInstalledModuleNames = $this->FindInstalledPackageModules($aPackageModules, $aInstallationChoices); } $aInstalledModules = []; foreach (array_keys($aPackageModules) as $sModuleId) { list($sModuleName) = ModuleDiscovery::GetModuleName($sModuleId); if (in_array($sModuleName, $aInstalledModuleNames)) { $aInstalledModules[] = $sModuleId; } } return $aInstalledModules; } private function FindInstalledPackageModules(array $aPackageModules, array $aInstallationChoices, array $aInstallationDescription = null): array { $aInstalledModules = []; $this->ProcessDefaultModules($aPackageModules, $aInstalledModules); if (is_null($aInstallationDescription)) { //in legacy usecase: choices are flat modules list already foreach ($aInstallationChoices as $sModuleName) { $aInstalledModules[$sModuleName] = true; } } else { $this->ProcessInstallationChoices($aInstallationChoices, $aInstallationDescription, $aInstalledModules); } $this->ProcessAutoSelectModules($aPackageModules, $aInstalledModules); return array_keys($aInstalledModules); } private function IsDefaultModule(string $sModuleId, array $aModule): bool { if (($sModuleId === ROOT_MODULE)) { return false; } if (isset($aModule['auto_select'])) { return false; } if ($aModule['category'] === 'authentication') { return true; } return !$aModule['visible']; } private function ProcessDefaultModules(array &$aPackageModules, array &$aInstalledModules): void { foreach ($aPackageModules as $sModuleId => $aModule) { if ($this->IsDefaultModule($sModuleId, $aModule)) { list($sModuleName) = ModuleDiscovery::GetModuleName($sModuleId); $aInstalledModules[$sModuleName] = true; unset($aPackageModules[$sModuleId]); } } } private function IsAutoSelectedModule(array $aInstalledModules, string $sModuleId, array $aModule): bool { if (($sModuleId === ROOT_MODULE)) { return false; } if (!isset($aModule['auto_select'])) { return false; } try { SetupInfo::SetSelectedModules($aInstalledModules); return DependencyExpression::GetPhpExpressionEvaluator()->ParseAndEvaluateBooleanExpression($aModule['auto_select']); } catch (Exception $e) { IssueLog::Error('Error evaluating module auto-select', null, [ 'module' => $sModuleId, 'error' => $e->getMessage(), 'evaluated code' => $aModule['auto_select'], 'stacktrace' => $e->getTraceAsString(), ]); } return false; } private function ProcessAutoSelectModules(array $aPackageModules, array &$aInstalledModules): void { foreach ($aPackageModules as $sModuleId => $aModule) { if ($this->IsAutoSelectedModule($aInstalledModules, $sModuleId, $aModule)) { list($sModuleName) = ModuleDiscovery::GetModuleName($sModuleId); $aInstalledModules[$sModuleName] = true; } } } private function ProcessInstallationChoices(array $aInstallationChoices, array $aInstallationDescription, array &$aInstalledModules): void { foreach ($aInstallationDescription as $aStepInfo) { $aOptions = $aStepInfo['options'] ?? null; if (is_array($aOptions)) { foreach ($aOptions as $aChoiceInfo) { $this->ProcessSelectedChoice($aInstallationChoices, $aChoiceInfo, $aInstalledModules); } } $aOptions = $aStepInfo['alternatives'] ?? null; if (is_array($aOptions)) { foreach ($aOptions as $aChoiceInfo) { $this->ProcessSelectedChoice($aInstallationChoices, $aChoiceInfo, $aInstalledModules); } } } } private function ProcessSelectedChoice(array $aInstallationChoices, array $aChoiceInfo, array &$aInstalledModules) { if (!is_array($aChoiceInfo)) { return; } $sMandatory = $aChoiceInfo['mandatory'] ?? 'false'; $aCurrentModules = $aChoiceInfo['modules'] ?? []; $sExtensionCode = $aChoiceInfo['extension_code']; $bSelected = ($sMandatory === 'true') || in_array($sExtensionCode, $aInstallationChoices); if (!$bSelected) { return; } foreach ($aCurrentModules as $sModuleId) { $aInstalledModules[$sModuleId] = true; } $aAlternatives = $aChoiceInfo['alternatives'] ?? null; if (is_array($aAlternatives)) { foreach ($aAlternatives as $aSubChoiceInfo) { $this->ProcessSelectedChoice($aInstallationChoices, $aSubChoiceInfo, $aInstalledModules); } } $aSubOptionsChoiceInfo = $aChoiceInfo['sub_options'] ?? null; if (is_array($aSubOptionsChoiceInfo)) { $aSubOptions = $aSubOptionsChoiceInfo['options'] ?? null; if (is_array($aSubOptions)) { foreach ($aSubOptions as $aSubChoiceInfo) { $this->ProcessSelectedChoice($aInstallationChoices, $aSubChoiceInfo, $aInstalledModules); } } $aSubAlternatives = $aSubOptionsChoiceInfo['alternatives'] ?? null; if (is_array($aSubAlternatives)) { foreach ($aSubAlternatives as $aSubChoiceInfo) { $this->ProcessSelectedChoice($aInstallationChoices, $aSubChoiceInfo, $aInstalledModules); } } } } }