diff --git a/application/loginwebpage.class.inc.php b/application/loginwebpage.class.inc.php index cd7904cf5..e047cf761 100644 --- a/application/loginwebpage.class.inc.php +++ b/application/loginwebpage.class.inc.php @@ -110,17 +110,6 @@ class LoginWebPage extends NiceWebPage return Branding::GetLoginFavIconAbsoluteUrl(); } - /** - * Return the absolute URL for the favicon - * - * @return string - * @throws \Exception - */ - protected function GetFaviconAbsoluteUrl() - { - return Branding::GetLoginFavIconAbsoluteUrl(); - } - public static function SetLoginFailedMessage($sMessage) { self::$m_sLoginFailedMessage = $sMessage; diff --git a/application/themehandler.class.inc.php b/application/themehandler.class.inc.php index a9d0887ea..150a019b0 100644 --- a/application/themehandler.class.inc.php +++ b/application/themehandler.class.inc.php @@ -73,8 +73,22 @@ class ThemeHandler */ public static function GetApplicationThemeId(): string { + //yo try { - $sThemeId = utils::GetConfig()->Get('backoffice_default_theme'); + $sThemeId = utils::GetConfig()->Get('backoffice_default_theme'); + + if (is_null($sThemeId)) { + $sWorkingPath = APPROOT.'env-'.utils::GetCurrentEnvironment().'/'; + $aThemeParameters = json_decode(@file_get_contents($sWorkingPath.'branding/theme.json'), true); + //environment type from config.php + $sEnvType = MetaModel::GetConfig()->Get('local_branding'); + if (utils::IsNullOrEmptyString($sEnvType)) { + $sEnvType = ''; + } + if (isset($aThemeParameters[$sEnvType]) && isset($aThemeParameters[$sEnvType]['default_theme'])) { + $aThemeId = $aThemeParameters[$sEnvType]['default_theme']; + } + } } catch (CoreException $oCompileException) { // Fallback on our default theme in case the config. is not available yet @@ -91,6 +105,7 @@ class ThemeHandler */ public static function GetCurrentUserThemeId(): string { + //yo $sThemeId = null; try { @@ -102,6 +117,20 @@ class ThemeHandler // Do nothing, already handled by $sThemeId null by default } + $sWorkingPath = APPROOT.'env-'.utils::GetCurrentEnvironment().'/'; + $aThemeParameters = json_decode(@file_get_contents($sWorkingPath.'branding/theme.json'), true); + //environment type from config.php + $sEnvType = MetaModel::GetConfig()->Get('local_branding'); + if (utils::IsNullOrEmptyString($sEnvType)) { + $sEnvType = ''; + } + if (isset($aThemeParameters[$sEnvType]) && isset($aThemeParameters[$sEnvType]['allowed_theme'])) { + $aThemeId = $aThemeParameters[$sEnvType]['allowed_theme']; + if (! in_array($sThemeId,$aThemeId)) { + $sThemeId = null; + } + } + // Fallback on the app. theme if (is_null($sThemeId)) { $sThemeId = static::GetApplicationThemeId(); @@ -130,8 +159,19 @@ class ThemeHandler */ public static function GetAvailableThemes(): array { + //yo $aThemes = []; + $sEnvType = MetaModel::GetConfig()->Get('local_branding'); + if (!utils::IsNullOrEmptyString($sEnvType)) { + $sWorkingPath = APPROOT . 'env-' . utils::GetCurrentEnvironment() . '/'; + $aThemeParameters = json_decode(@file_get_contents($sWorkingPath . 'branding/theme.json'), true); + //environment type from config.php + if (isset($aThemeParameters[$sEnvType])) { + + } + } + foreach (glob(static::GetCompiledThemesFolderAbsolutePath().'/*') as $sPath) { if (is_dir($sPath)) { $sThemeId = basename($sPath); diff --git a/core/config.class.inc.php b/core/config.class.inc.php index 2d1830582..542bb4d43 100644 --- a/core/config.class.inc.php +++ b/core/config.class.inc.php @@ -209,9 +209,9 @@ class Config 'source_of_value' => '', 'show_in_conf_sample' => true, ], - 'branding_environment' => [ + 'local_branding' => [ 'type' => 'string', - 'description' => 'type of branding. usefull for put different logo depending environment', + 'description' => 'type of branding. useful for put different logo depending environment', 'default' => null, 'value' => null, 'source_of_value' => '', diff --git a/datamodels/2.x/itop-structure/datamodel.itop-structure.xml b/datamodels/2.x/itop-structure/datamodel.itop-structure.xml index ea600f3ce..0707d1ac8 100644 --- a/datamodels/2.x/itop-structure/datamodel.itop-structure.xml +++ b/datamodels/2.x/itop-structure/datamodel.itop-structure.xml @@ -2000,7 +2000,7 @@ UR_ACTION_MODIFY - + @@ -2035,7 +2035,7 @@ - + diff --git a/setup/compiler.class.inc.php b/setup/compiler.class.inc.php index f152a87d9..fecfb8cb8 100644 --- a/setup/compiler.class.inc.php +++ b/setup/compiler.class.inc.php @@ -729,7 +729,7 @@ PHP; // Compile the branding // /** @var \MFElement $oBrandingNode */ - $oBrandingNode = $this->oFactory->GetNodes('brandings')->item(0); + $oBrandingNode = $this->oFactory->GetNodes('branding')->item(0); $this->CompileBranding($oBrandingNode, $sTempTargetDir, $sFinalTargetDir); if (array_key_exists('_core_', $this->aSnippets)) @@ -3565,7 +3565,27 @@ EOF; } } $this->Log(sprintf('Themes compilation took: %.3f ms for %d themes.', (microtime(true) - $fStart)*1000.0, count($aThemes))); - } + + $aDataBranding = []; + $oLocalBrandingsNodes = $oBrandingNode->GetNodes('local_brandings/local_branding/'); + foreach($oLocalBrandingsNodes as $oLocalBrandingNode) { + $sLocalBrandingId = $oLocalBrandingNode->getAttribute('id'); + $oThemesNodes = $oLocalBrandingNode->GetNodes('allowed_themes/allowed_theme/'); + foreach($oThemesNodes as $oThemesNodes) { + $sThemeId = $oThemesNodes->GetText(); + $aDataBranding[$sLocalBrandingId]['allowed_theme'][] = $sThemeId; + } + $sDefaultTheme = $oLocalBrandingNode->GetChildText('default_theme/value'); + $aDataBranding[$sLocalBrandingId]['default_theme'] = $sDefaultTheme; + } + + if ($sTempTargetDir == null) { + $sWorkingPath = APPROOT.'env-'.utils::GetCurrentEnvironment().'/'; + } else { + $sWorkingPath = $sTempTargetDir; + } + file_put_contents($sWorkingPath.'/branding/theme.json', json_encode($aDataBranding)); + } public static function SetThemeHandlerService(ThemeHandlerService $oThemeHandlerService): void { self::$oThemeHandlerService = $oThemeHandlerService; @@ -3639,22 +3659,42 @@ EOF; } /** - * @param \MFElement $oBrandingsNode + * @param \MFElement $oBrandingNode * @param string $sTempTargetDir * @param string $sFinalTargetDir * * @throws \DOMFormatException * @throws \Exception */ - protected function CompileBranding($oBrandingsNode, $sTempTargetDir, $sFinalTargetDir) + protected function CompileBranding($oBrandingNode, $sTempTargetDir, $sFinalTargetDir) { // Enable relative paths SetupUtils::builddir($sTempTargetDir.'/branding'); - if ($oBrandingsNode) { + // Transform file refs into files in the images folder + $this->CompileFiles($oBrandingNode, $sTempTargetDir.'/branding', $sFinalTargetDir.'/branding', 'branding'); + $aDataBranding = []; + + $aLogosToCompile = [ + ['sNodeName' => 'login_logo', 'sTargetFile' => 'login-logo', 'sType' => Branding::ENUM_LOGO_TYPE_LOGIN_LOGO], + ['sNodeName' => 'main_logo', 'sTargetFile' => 'main-logo-full', 'sType' => Branding::ENUM_LOGO_TYPE_MAIN_LOGO_FULL], + ['sNodeName' => 'main_logo_compact', 'sTargetFile' => 'main-logo-compact', 'sType' => Branding::ENUM_LOGO_TYPE_MAIN_LOGO_COMPACT], + ['sNodeName' => 'portal_logo', 'sTargetFile' => 'portal-logo', 'sType' => Branding::ENUM_LOGO_TYPE_PORTAL_LOGO], + ['sNodeName' => 'login_favicon', 'sTargetFile' => 'login_favicon', 'sType' => Branding::ENUM_LOGO_TYPE_LOGIN_FAVICON], + ['sNodeName' => 'main_favicon', 'sTargetFile' => 'main_favicon', 'sType' => Branding::ENUM_LOGO_TYPE_MAIN_FAVICON], + ['sNodeName' => 'portal_favicon', 'sTargetFile' => 'portal_favicon', 'sType' => Branding::ENUM_LOGO_TYPE_PORTAL_FAVICON], + ]; + foreach ($aLogosToCompile as $aLogo) { + $sLogo = $this->CompileLogo($oBrandingNode, $sTempTargetDir, $sFinalTargetDir, $aLogo['sNodeName'], $aLogo['sTargetFile']); + if ($sLogo != null) { + $aDataBranding[$aLogo['sType']] = $sLogo; + } + } + $oLocalBrandingsNode = $oBrandingNode->GetNodes('local_brandings'); + if ($oLocalBrandingsNode) { $aDataBranding = []; - foreach ($oBrandingsNode->childNodes as $oBrandingNode) { + foreach ($oLocalBrandingsNode->childNodes as $oLocalBrandingNode) { // Transform file refs into files in the images folder - $this->CompileFiles($oBrandingNode, $sTempTargetDir.'/branding', $sFinalTargetDir.'/branding', 'branding'); + $this->CompileFiles($oLocalBrandingNode, $sTempTargetDir.'/branding', $sFinalTargetDir.'/branding', 'branding'); $aLogosToCompile = [ ['sNodeName' => 'login_logo', 'sTargetFile' => 'login-logo', 'sType' => Branding::ENUM_LOGO_TYPE_LOGIN_LOGO], @@ -3665,12 +3705,12 @@ EOF; ['sNodeName' => 'main_favicon', 'sTargetFile' => 'main_favicon', 'sType' => Branding::ENUM_LOGO_TYPE_MAIN_FAVICON], ['sNodeName' => 'portal_favicon', 'sTargetFile' => 'portal_favicon', 'sType' => Branding::ENUM_LOGO_TYPE_PORTAL_FAVICON], ]; - $sEnvironment = $oBrandingNode->getAttribute('id'); + $sEnvironment = $oLocalBrandingNode->getAttribute('id'); SetupUtils::builddir($sTempTargetDir.'/branding/'.$sEnvironment); foreach ($aLogosToCompile as $aLogo) { - $sLogo = $this->CompileLogo($oBrandingNode, $sTempTargetDir, $sEnvironment, $aLogo['sNodeName'], $aLogo['sTargetFile']); + $sLogo = $this->CompileLogo($oLocalBrandingNode, $sTempTargetDir, $sEnvironment, $aLogo['sNodeName'], $aLogo['sTargetFile']); if ($sLogo != null) { - $aDataBranding[$oBrandingNode->getAttribute('id')][$aLogo['sType']] = $sLogo; + $aDataBranding[$oLocalBrandingNode->getAttribute('id')][$aLogo['sType']] = $sLogo; } } } @@ -3689,7 +3729,7 @@ EOF; } // Compile themes - $this->CompileThemes($oBrandingsNode, $sTempTargetDir); + $this->CompileThemes($oBrandingNode, $sTempTargetDir); } } diff --git a/setup/itopdesignformat.class.inc.php b/setup/itopdesignformat.class.inc.php index 7d2bdb853..405fc4713 100644 --- a/setup/itopdesignformat.class.inc.php +++ b/setup/itopdesignformat.class.inc.php @@ -1101,39 +1101,17 @@ class iTopDesignFormat /** * Upgrade the format from version 3.1 to 3.2 - * * @param \ModelFactory $oFactory - * * @return void (Errors are logged) */ protected function From31To32($oFactory) { - $oXPath = new DOMXPath($this->oDocument); - - // N°3363 - Add favicon in branding - $oNodeDesign = $oXPath->query("/itop_design")->item(0); - $oNodeBranding = $oXPath->query("/itop_design/branding")->item(0); - if ($oNodeBranding) { - $oNodeBrandings = $oNodeDesign->ownerDocument->createElement("brandings"); - $oNodeDesign->appendChild($oNodeBrandings); - $oNodeBrandingTheme = $oXPath->query("/itop_design/branding/themes")->item(0); - if ($oNodeBrandingTheme) { - $oNodeBrandings->appendChild($oNodeBrandingTheme); - } - $oNodeBrandingThemeCommon = $oXPath->query("/itop_design/branding/themes_common")->item(0); - if ($oNodeBrandingThemeCommon) { - $oNodeBrandings->appendChild($oNodeBrandingThemeCommon); - } - $oNodeBranding->setAttribute('id', 'default'); - $oNodeBrandings->appendChild($oNodeBranding); - } + // Nothing for now... } /** * Downgrade the format from version 3.2 to 3.1 - * * @param \ModelFactory $oFactory - * * @return void (Errors are logged) */ protected function From32To31($oFactory) @@ -1161,7 +1139,7 @@ class iTopDesignFormat */ protected function From33To32($oFactory) { - // Nothing for now... + $this->RemoveNodeFromXPath('/itop_design/branding/local_brandings'); } /** diff --git a/sources/Application/Branding.php b/sources/Application/Branding.php index e65d50021..25b4035ff 100644 --- a/sources/Application/Branding.php +++ b/sources/Application/Branding.php @@ -96,7 +96,7 @@ class Branding $sWorkingPath = APPROOT.'env-'.utils::GetCurrentEnvironment().'/'; $aThemeParameters = json_decode(@file_get_contents($sWorkingPath.'branding/logos.json'), true); //environment type from config.php - $sEnvType = MetaModel::GetConfig()->Get('branding_environment'); + $sEnvType = MetaModel::GetConfig()->Get('local_branding'); if (utils::IsNullOrEmptyString($sEnvType)) { $sEnvType = 'default'; } diff --git a/sources/Application/WebPage/UnauthenticatedWebPage.php b/sources/Application/WebPage/UnauthenticatedWebPage.php index 0cfbfa855..480e40169 100644 --- a/sources/Application/WebPage/UnauthenticatedWebPage.php +++ b/sources/Application/WebPage/UnauthenticatedWebPage.php @@ -60,17 +60,6 @@ class UnauthenticatedWebPage extends NiceWebPage /** @since 3.2.0 */ protected string $sPortalPublicFolderAbsUrl; - /** - * Return the absolute URL for the favicon - * - * @return string - * @throws \Exception - */ - protected function GetFaviconAbsoluteUrl() - { - return Branding::GetLoginFavIconAbsoluteUrl(); - } - /** * @inheritDoc * @throws \Exception diff --git a/tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/Convert-samples/3.3_to_3.2.expected.xml b/tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/Convert-samples/3.3_to_3.2.expected.xml index da9755d33..2d9eadcf3 100644 --- a/tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/Convert-samples/3.3_to_3.2.expected.xml +++ b/tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/Convert-samples/3.3_to_3.2.expected.xml @@ -1,3 +1,33 @@ + + + + + + + + + + + + + + $ibo-color-red-600 + $ibo-color-red-100 + "THIS IS A TEST INSTANCE" + + + ignored-because-lack-xsi-type.scss + ok-because-xsi-type-variables.scss + ok-because-xsi-type-utilities.scss + + + ../css/backoffice/main.scss + ../css/backoffice/themes/page-banner.scss + + itop-structure/precompiled-themes/test-red/main.css + + + diff --git a/tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/Convert-samples/3.3_to_3.2.input.xml b/tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/Convert-samples/3.3_to_3.2.input.xml index da9755d33..a89832069 100644 --- a/tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/Convert-samples/3.3_to_3.2.input.xml +++ b/tests/php-unit-tests/unitary-tests/setup/iTopDesignFormat/Convert-samples/3.3_to_3.2.input.xml @@ -1,3 +1,52 @@ + + + + + + + + + + + + + + $ibo-color-red-600 + $ibo-color-red-100 + "THIS IS A TEST INSTANCE" + + + ignored-because-lack-xsi-type.scss + ok-because-xsi-type-variables.scss + ok-because-xsi-type-utilities.scss + + + ../css/backoffice/main.scss + ../css/backoffice/themes/page-banner.scss + + itop-structure/precompiled-themes/test-red/main.css + + + + + + + + + + + + + + + fullmoon + + + + + + + diff --git a/tests/php-unit-tests/unitary-tests/setup/ressources/datamodels/datamodel-branding.xml b/tests/php-unit-tests/unitary-tests/setup/ressources/datamodels/datamodel-branding.xml index 88b36bd7d..ad3623175 100644 --- a/tests/php-unit-tests/unitary-tests/setup/ressources/datamodels/datamodel-branding.xml +++ b/tests/php-unit-tests/unitary-tests/setup/ressources/datamodels/datamodel-branding.xml @@ -1,6 +1,6 @@ - - + + @@ -20,5 +20,5 @@ itop-structure/precompiled-themes/test-red/main.css - + \ No newline at end of file