Compare commits

...

3 Commits

Author SHA1 Message Date
Anne-Cath
1c1bfaa4a8 WIP 2025-01-27 14:09:56 +01:00
Anne-Cath
2f54f0a253 WIP 2025-01-20 14:02:11 +01:00
Anne-Cath
27022ed93a N°3777 - favicon: change easily favicon 2025-01-17 09:23:37 +01:00
9 changed files with 299 additions and 84 deletions

View File

@@ -73,15 +73,42 @@ class ThemeHandler
*/ */
public static function GetApplicationThemeId(): string public static function GetApplicationThemeId(): string
{ {
$sThemeId = null;
try { try {
$sThemeId = utils::GetConfig()->Get('backoffice_default_theme'); //environment type from config.php
$sEnvType = MetaModel::GetConfig()->Get('local_branding');
//environment type from config.php
if (utils::IsNotNullOrEmptyString($sEnvType)) {
$sWorkingPath = APPROOT.'env-'.utils::GetCurrentEnvironment().'/';
$aThemeParameters = json_decode(@file_get_contents($sWorkingPath.'branding/themes.json'), true);
if ( isset($aThemeParameters[$sEnvType]) ) {
if (isset($aThemeParameters[$sEnvType]['allowed_theme'])) {
$aThemeId = $aThemeParameters[$sEnvType]['allowed_theme'];
if (in_array($sThemeId, $aThemeId) == false) {
$sThemeId = null;
}
}
if (is_null($sThemeId)) {
//environment type from config.php
if (isset($aThemeParameters[$sEnvType]['default_theme'])) {
$sThemeId = $aThemeParameters[$sEnvType]['default_theme'];
} else {
$aDefaultTheme = ThemeHandler::GetDefaultThemeInformation();
$sThemeId = $aDefaultTheme['name'];
}
}
}
}
if (is_null($sThemeId)) {
$sThemeId = utils::GetConfig()->Get('backoffice_default_theme');
}
} }
catch (CoreException $oCompileException) { catch (CoreException $oCompileException) {
// Fallback on our default theme in case the config. is not available yet // Fallback on our default theme in case the config. is not available yet
$aDefaultTheme = ThemeHandler::GetDefaultThemeInformation(); $aDefaultTheme = ThemeHandler::GetDefaultThemeInformation();
$sThemeId = $aDefaultTheme['name']; $sThemeId = $aDefaultTheme['name'];
} }
IssueLog::Error("GetApplicationThemeId: ".$sThemeId);
return $sThemeId; return $sThemeId;
} }
@@ -101,11 +128,24 @@ class ThemeHandler
catch (Exception $oException) { catch (Exception $oException) {
// Do nothing, already handled by $sThemeId null by default // Do nothing, already handled by $sThemeId null by default
} }
$sEnvType = MetaModel::GetConfig()->Get('local_branding');
//environment type from config.php
if (utils::IsNotNullOrEmptyString($sEnvType)) {
$sWorkingPath = APPROOT.'env-'.utils::GetCurrentEnvironment().'/';
$aThemeParameters = json_decode(@file_get_contents($sWorkingPath.'branding/themes.json'), true);
if (isset($aThemeParameters[$sEnvType]) && isset($aThemeParameters[$sEnvType]['allowed_theme'])) {
$aThemeId = $aThemeParameters[$sEnvType]['allowed_theme'];
if ( in_array($sThemeId,$aThemeId) == false) {
$sThemeId = null;
}
}
}
// Fallback on the app. theme // Fallback on the app. theme
if (is_null($sThemeId)) { if (is_null($sThemeId)) {
$sThemeId = static::GetApplicationThemeId(); $sThemeId = static::GetApplicationThemeId();
} }
IssueLog::Error("GetCurrentUserThemeId: ".$sThemeId);
return $sThemeId; return $sThemeId;
} }
@@ -142,6 +182,25 @@ class ThemeHandler
} }
asort($aThemes); asort($aThemes);
$sEnvType = MetaModel::GetConfig()->Get('local_branding');
if (!utils::IsNullOrEmptyString($sEnvType)) {
$sWorkingPath = APPROOT . 'env-' . utils::GetCurrentEnvironment() . '/';
$aThemeParameters = json_decode(@file_get_contents($sWorkingPath . 'branding/themes.json'), true);
//environment type from config.php
if (isset($aThemeParameters[$sEnvType])) {
$aThemeId = $aThemeParameters[$sEnvType]['allowed_theme'];
$aAvailableThemes = [];
foreach ($aThemeId as $sThemeId) {
if (isset($aThemes[$sThemeId])) {
$aAvailableThemes[$sThemeId] = $aThemes[$sThemeId];
}
}
if (count($aAvailableThemes) > 0) {
$aThemes = $aAvailableThemes;
}
}
}
return $aThemes; return $aThemes;
} }

View File

@@ -185,7 +185,7 @@ class Config
'source_of_value' => '', 'source_of_value' => '',
'show_in_conf_sample' => false, 'show_in_conf_sample' => false,
], ],
'temporary_object.garbage_interval' => [ 'temporary_object.garbage_interval' => [
'type' => 'integer', 'type' => 'integer',
'description' => 'Seconds between garbage collections', 'description' => 'Seconds between garbage collections',
'default' => 60, 'default' => 60,
@@ -193,7 +193,7 @@ class Config
'source_of_value' => '', 'source_of_value' => '',
'show_in_conf_sample' => false, 'show_in_conf_sample' => false,
], ],
'app_env_label' => [ 'app_env_label' => [
'type' => 'string', 'type' => 'string',
'description' => 'Label displayed to describe the current application environment, defaults to the environment name (e.g. "production")', 'description' => 'Label displayed to describe the current application environment, defaults to the environment name (e.g. "production")',
'default' => '', 'default' => '',
@@ -201,7 +201,7 @@ class Config
'source_of_value' => '', 'source_of_value' => '',
'show_in_conf_sample' => false, 'show_in_conf_sample' => false,
], ],
'app_root_url' => [ 'app_root_url' => [
'type' => 'string', 'type' => 'string',
'description' => 'Root URL used for navigating within the application, or from an email to the application (you can put $SERVER_NAME$ as a placeholder for the server\'s name)', 'description' => 'Root URL used for navigating within the application, or from an email to the application (you can put $SERVER_NAME$ as a placeholder for the server\'s name)',
'default' => '', 'default' => '',
@@ -209,7 +209,15 @@ class Config
'source_of_value' => '', 'source_of_value' => '',
'show_in_conf_sample' => true, 'show_in_conf_sample' => true,
], ],
'app_icon_url' => [ 'local_branding' => [
'type' => 'string',
'description' => 'type of branding. useful for put different logo depending environment',
'default' => null,
'value' => null,
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'app_icon_url' => [
'type' => 'string', 'type' => 'string',
'description' => 'Hyperlink to redirect the user when clicking on the application icon (in the main window, or login/logoff pages)', 'description' => 'Hyperlink to redirect the user when clicking on the application icon (in the main window, or login/logoff pages)',
'default' => 'http://www.combodo.com/itop', 'default' => 'http://www.combodo.com/itop',
@@ -217,50 +225,50 @@ class Config
'source_of_value' => '', 'source_of_value' => '',
'show_in_conf_sample' => false, 'show_in_conf_sample' => false,
], ],
'db_host' => [ 'db_host' => [
'type' => 'string', 'type' => 'string',
'default' => null, 'default' => null,
'value' => '', 'value' => '',
'source_of_value' => '', 'source_of_value' => '',
'show_in_conf_sample' => true, 'show_in_conf_sample' => true,
], ],
'db_user' => [ 'db_user' => [
'type' => 'string', 'type' => 'string',
'default' => null, 'default' => null,
'value' => '', 'value' => '',
'source_of_value' => '', 'source_of_value' => '',
'show_in_conf_sample' => true, 'show_in_conf_sample' => true,
], ],
'db_pwd' => [ 'db_pwd' => [
'type' => 'string', 'type' => 'string',
'default' => null, 'default' => null,
'value' => '', 'value' => '',
'source_of_value' => '', 'source_of_value' => '',
'show_in_conf_sample' => true, 'show_in_conf_sample' => true,
], ],
'db_name' => [ 'db_name' => [
'type' => 'string', 'type' => 'string',
'default' => null, 'default' => null,
'value' => '', 'value' => '',
'source_of_value' => '', 'source_of_value' => '',
'show_in_conf_sample' => true, 'show_in_conf_sample' => true,
], ],
'db_subname' => [ 'db_subname' => [
'type' => 'string', 'type' => 'string',
'default' => null, 'default' => null,
'value' => '', 'value' => '',
'source_of_value' => '', 'source_of_value' => '',
'show_in_conf_sample' => true, 'show_in_conf_sample' => true,
], ],
'db_tls.enabled' => [ 'db_tls.enabled' => [
'type' => 'bool', 'type' => 'bool',
'description' => 'If true then the connection to the DB will be encrypted', 'description' => 'If true then the connection to the DB will be encrypted',
'default' => false, 'default' => false,
'value' => false, 'value' => false,
'source_of_value' => '', 'source_of_value' => '',
'show_in_conf_sample' => false, 'show_in_conf_sample' => false,
], ],
'db_tls.ca' => [ 'db_tls.ca' => [
'type' => 'string', 'type' => 'string',
'description' => 'Path to certificate authority file for SSL', 'description' => 'Path to certificate authority file for SSL',
'default' => null, 'default' => null,
@@ -268,7 +276,7 @@ class Config
'source_of_value' => '', 'source_of_value' => '',
'show_in_conf_sample' => false, 'show_in_conf_sample' => false,
], ],
'db_core_transactions_enabled' => [ 'db_core_transactions_enabled' => [
'type' => 'bool', 'type' => 'bool',
'description' => 'If true, CRUD transactions in iTop core will be enabled', 'description' => 'If true, CRUD transactions in iTop core will be enabled',
'default' => true, 'default' => true,
@@ -1888,6 +1896,7 @@ class Config
*/ */
public function Get($sPropCode) public function Get($sPropCode)
{ {
return $this->m_aSettings[$sPropCode]['value']; return $this->m_aSettings[$sPropCode]['value'];
} }

View File

@@ -72,6 +72,7 @@ class Basic extends AbstractConfiguration
*/ */
private function GetInitialPortalConf() private function GetInitialPortalConf()
{ {
$aPortalConf = array( $aPortalConf = array(
'properties' => array( 'properties' => array(
'id' => $_ENV['PORTAL_ID'], 'id' => $_ENV['PORTAL_ID'],
@@ -81,15 +82,15 @@ class Basic extends AbstractConfiguration
'favicon' => Branding::GetPortalFavIconAbsoluteUrl(), 'favicon' => Branding::GetPortalFavIconAbsoluteUrl(),
'themes' => array( 'themes' => array(
'bootstrap' => 'itop-portal-base/portal/public/css/bootstrap-theme-combodo.scss', 'bootstrap' => 'itop-portal-base/portal/public/css/bootstrap-theme-combodo.scss',
'portal' => 'itop-portal-base/portal/public/css/portal.scss', 'portal' => 'itop-portal-base/portal/public/css/portal.scss',
'others' => array(), 'others' => array(),
), ),
'templates' => array( 'templates' => array(
'layout' => 'itop-portal-base/portal/templates/layout.html.twig', 'layout' => 'itop-portal-base/portal/templates/layout.html.twig',
'home' => 'itop-portal-base/portal/templates/home/layout.html.twig', 'home' => 'itop-portal-base/portal/templates/home/layout.html.twig',
), ),
'urlmaker_class' => null, 'urlmaker_class' => null,
'triggers_query' => null, 'triggers_query' => null,
'attachments' => array( 'attachments' => array(
'allow_delete' => true, 'allow_delete' => true,
), ),

View File

@@ -25,7 +25,7 @@
{% block pPageExtraMetas %} {% block pPageExtraMetas %}
{% endblock %} {% endblock %}
<title>{% block pPageTitle %}{% if sPageTitle is defined and sPageTitle is not null %}{{ sPageTitle }} - {{ constant('ITOP_APPLICATION_SHORT') }}{% else %}{{ 'Page:DefaultTitle'|dict_format(constant('ITOP_APPLICATION_SHORT')) }}{% endif %}{% endblock %}</title> <title>{% block pPageTitle %}{% if sPageTitle is defined and sPageTitle is not null %}{{ sPageTitle }} - {{ constant('ITOP_APPLICATION_SHORT') }}{% else %}{{ 'Page:DefaultTitle'|dict_format(constant('ITOP_APPLICATION_SHORT')) }}{% endif %}{% endblock %}</title>
<link rel="shortcut icon" href="{{ app['combodo.portal.instance.conf'].properties.favicon|add_itop_version }}"/> <link rel="shortcut icon" href="{{ app['combodo.portal.instance.conf'].properties.favicon|add_itop_version }}"/>
{% block pPageStylesheets %} {% block pPageStylesheets %}
{# First bootstrap core, lib themes, then bootstrap theme, portal adjustements #} {# First bootstrap core, lib themes, then bootstrap theme, portal adjustements #}
@@ -251,7 +251,7 @@
</nav> </nav>
{% endblock %} {% endblock %}
{# Sidebar navigation menu for normal screens #} {# Sidebar navigation menu for normal screens #}
{% block pNavigationSideMenuWrapper %} {% block pNavigationSideMenuWrapper %}
<nav class="navbar-default hidden-xs col-sm-3 col-md-2" id="sidebar" role="navigation"> <nav class="navbar-default hidden-xs col-sm-3 col-md-2" id="sidebar" role="navigation">
<div class="user_card bg-primary"> <div class="user_card bg-primary">

View File

@@ -3330,27 +3330,27 @@ EOF;
/** /**
* @param \MFElement $oBrandingNode * @param \MFElement $oBrandingNode
* @param string $sTempTargetDir * @param string $sTempTargetDir
* @param string $sFinalTargetDir * @param string $sLocalBrandingId
* @param string $sNodeName * @param string $sNodeName
* @param string $sTargetFile * @param string $sTargetFile
* *
* @throws \Exception * @throws \Exception
*/ */
protected function CompileLogo($oBrandingNode, $sTempTargetDir, $sFinalTargetDir, $sNodeName, $sTargetFile) protected function CompileLogo($oBrandingNode, $sTempTargetDir, $sLocalBrandingId, $sNodeName, $sTargetFile)
{ {
$sIcon = trim($oBrandingNode->GetChildText($sNodeName) ?? ''); $sIcon = trim($oBrandingNode->GetChildText($sNodeName) ?? '');
if (strlen($sIcon) > 0) { if (strlen($sIcon) > 0) {
$sSourceFile = $sTempTargetDir.'/'.$sIcon; $sSourceFile = $sTempTargetDir.'/'.$sIcon;
$aIconName=explode(".", $sIcon); $aIconName = explode(".", $sIcon);
$sIconExtension=$aIconName[count($aIconName)-1]; $sIconExtension = $aIconName[count($aIconName) - 1];
$sTargetFile = '/branding/'.$sTargetFile.'.'.$sIconExtension; $sTargetFile = '/branding/'.$sLocalBrandingId.'/'.$sTargetFile.'.'.$sIconExtension;
if (!file_exists($sSourceFile)) if (!file_exists($sSourceFile)) {
{
throw new Exception("Branding $sNodeName: could not find the file $sIcon ($sSourceFile)"); throw new Exception("Branding $sNodeName: could not find the file $sIcon ($sSourceFile)");
} }
copy($sSourceFile, $sTempTargetDir.$sTargetFile); copy($sSourceFile, $sTempTargetDir.$sTargetFile);
return $sTargetFile; return $sTargetFile;
} }
return null; return null;
@@ -3380,8 +3380,7 @@ EOF;
// Build compiled themes folder // Build compiled themes folder
$sThemesRelDirPath = 'branding/themes/'; $sThemesRelDirPath = 'branding/themes/';
$sThemesAbsDirPath = $sTempTargetDir.$sThemesRelDirPath; $sThemesAbsDirPath = $sTempTargetDir.$sThemesRelDirPath;
if(!is_dir($sThemesAbsDirPath)) if (!is_dir($sThemesAbsDirPath)) {
{
SetupUtils::builddir($sThemesAbsDirPath); SetupUtils::builddir($sThemesAbsDirPath);
} }
@@ -3565,7 +3564,30 @@ EOF;
} }
} }
$this->Log(sprintf('Themes compilation took: %.3f ms for %d themes.', (microtime(true) - $fStart)*1000.0, count($aThemes))); $this->Log(sprintf('Themes compilation took: %.3f ms for %d themes.', (microtime(true) - $fStart)*1000.0, count($aThemes)));
}
$aDataBranding = [];
$oLocalBrandingsNode = $oBrandingNode->GetUniqueElement('local_brandings', false);
if ($oLocalBrandingsNode != null ) {
foreach ($oLocalBrandingsNode->GetNodes('local_branding') as $oLocalBrandingNode) {
$sLocalBrandingId = $oLocalBrandingNode->getAttribute('id');
$oLocalThemesNode = $oLocalBrandingNode->GetUniqueElement('allowed_themes', false);
if ($oLocalThemesNode != null ) {
foreach ($oLocalThemesNode->GetNodes('allowed_theme') as $oThemesNodes) {
$sThemeId = $oThemesNodes->getAttribute('id');
$aDataBranding[$sLocalBrandingId]['allowed_theme'][] = $sThemeId;
}
}
$sDefaultTheme = $oLocalBrandingNode->GetUniqueElement('default_theme', false)->GetChildText('value');
$aDataBranding[$sLocalBrandingId]['default_theme'] = $sDefaultTheme;
}
}
if ($sTempTargetDir == null) {
$sWorkingPath = APPROOT.'env-'.utils::GetCurrentEnvironment().'/';
} else {
$sWorkingPath = $sTempTargetDir;
}
file_put_contents($sWorkingPath.'/branding/themes.json', json_encode($aDataBranding));
}
public static function SetThemeHandlerService(ThemeHandlerService $oThemeHandlerService): void { public static function SetThemeHandlerService(ThemeHandlerService $oThemeHandlerService): void {
self::$oThemeHandlerService = $oThemeHandlerService; self::$oThemeHandlerService = $oThemeHandlerService;
@@ -3650,27 +3672,50 @@ EOF;
{ {
// Enable relative paths // Enable relative paths
SetupUtils::builddir($sTempTargetDir.'/branding'); SetupUtils::builddir($sTempTargetDir.'/branding');
if ($oBrandingNode) if ($oBrandingNode) {
{ // Transform file refs into files in the images folder
// Transform file refs into files in the images folder $this->CompileFiles($oBrandingNode, $sTempTargetDir.'/branding', $sFinalTargetDir.'/branding', 'branding');
$this->CompileFiles($oBrandingNode, $sTempTargetDir.'/branding', $sFinalTargetDir.'/branding', 'branding'); $aDataBranding = [];
$aDataBranding = [];
$aLogosToCompile = [ $aLogosToCompile = [
['sNodeName' => 'login_logo', 'sTargetFile' => 'login-logo', 'sType' => Branding::ENUM_LOGO_TYPE_LOGIN_LOGO], ['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', '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' => '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' => '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' => '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' => '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], ['sNodeName' => 'portal_favicon', 'sTargetFile' => 'portal_favicon', 'sType' => Branding::ENUM_LOGO_TYPE_PORTAL_FAVICON],
]; ];
foreach ($aLogosToCompile as $aLogo) { foreach ($aLogosToCompile as $aLogo) {
$sLogo = $this->CompileLogo($oBrandingNode, $sTempTargetDir, $sFinalTargetDir, $aLogo['sNodeName'], $aLogo['sTargetFile']); $sLogo = $this->CompileLogo($oBrandingNode, $sTempTargetDir, null, $aLogo['sNodeName'], $aLogo['sTargetFile']);
if ($sLogo != null) { if ($sLogo != null) {
$aDataBranding[$aLogo['sType']] = $sLogo; $aDataBranding['default'][$aLogo['sType']] = $sLogo;
} }
} }
$oLocalBrandingsNode = $oBrandingNode->GetUniqueElement('local_brandings', false);
if ($oLocalBrandingsNode != null ) {
foreach ($oLocalBrandingsNode->GetNodes('local_branding') as $oLocalBrandingNode) {
// Transform file refs into files in the images folder
$this->CompileFiles($oLocalBrandingNode, $sTempTargetDir.'/branding', $sFinalTargetDir.'/branding', 'branding');
$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],
];
$sLocalBrandingId = $oLocalBrandingNode->getAttribute('id');
foreach ($aLogosToCompile as $aLogo) {
$sLogo = $this->CompileLogo($oLocalBrandingNode, $sTempTargetDir, $sLocalBrandingId, $aLogo['sNodeName'], $aLogo['sTargetFile']);
if ($sLogo != null) {
$aDataBranding[$oLocalBrandingNode->getAttribute('id')][$aLogo['sType']] = $sLogo;
}
}
}
}
if ($sTempTargetDir == null) { if ($sTempTargetDir == null) {
$sWorkingPath = APPROOT.'env-'.utils::GetCurrentEnvironment().'/'; $sWorkingPath = APPROOT.'env-'.utils::GetCurrentEnvironment().'/';
} else { } else {
@@ -3680,8 +3725,7 @@ EOF;
file_put_contents($sWorkingPath.'/branding/logos.json', json_encode($aDataBranding)); file_put_contents($sWorkingPath.'/branding/logos.json', json_encode($aDataBranding));
// Cleanup the images directory (eventually made by CompileFiles) // Cleanup the images directory (eventually made by CompileFiles)
if (file_exists($sTempTargetDir.'/branding/images')) if (file_exists($sTempTargetDir.'/branding/images')) {
{
SetupUtils::rrmdir($sTempTargetDir.'/branding/images'); SetupUtils::rrmdir($sTempTargetDir.'/branding/images');
} }

View File

@@ -920,12 +920,12 @@ class iTopDesignFormat
$oNode->setAttribute('id', 'ibo-page-banner--background-color'); $oNode->setAttribute('id', 'ibo-page-banner--background-color');
} }
$oNodeList = $oXPath->query( '/itop_design/branding/themes/theme[@id="test-red"]/variables/variable[@id="backoffice-environment-banner-text-color"]'); $oNodeList = $oXPath->query('/itop_design/branding/themes/theme[@id="test-red"]/variables/variable[@id="backoffice-environment-banner-text-color"]');
foreach ($oNodeList as $oNode) { foreach ($oNodeList as $oNode) {
$oNode->setAttribute('id', 'ibo-page-banner--text-color'); $oNode->setAttribute('id', 'ibo-page-banner--text-color');
} }
$oNodeList = $oXPath->query( '/itop_design/branding/themes/theme[@id="test-red"]/variables/variable[@id="backoffice-environment-banner-text-content"]'); $oNodeList = $oXPath->query('/itop_design/branding/themes/theme[@id="test-red"]/variables/variable[@id="backoffice-environment-banner-text-content"]');
foreach ($oNodeList as $oNode) { foreach ($oNodeList as $oNode) {
$oNode->setAttribute('id', 'ibo-page-banner--text-content'); $oNode->setAttribute('id', 'ibo-page-banner--text-content');
} }
@@ -1067,7 +1067,6 @@ class iTopDesignFormat
*/ */
protected function From30To31($oFactory) protected function From30To31($oFactory)
{ {
} }
/** /**
* Downgrade the format from version 3.1 to 3.0 * Downgrade the format from version 3.1 to 3.0
@@ -1097,6 +1096,7 @@ class iTopDesignFormat
$this->RemoveNodeFromXPath("/itop_design/classes//class/fields/field/sort_type"); $this->RemoveNodeFromXPath("/itop_design/classes//class/fields/field/sort_type");
// - Remove rank in values // - Remove rank in values
$this->RemoveNodeFromXPath("/itop_design/classes//class/fields/field/values/value/rank"); $this->RemoveNodeFromXPath("/itop_design/classes//class/fields/field/values/value/rank");
} }
/** /**
@@ -1139,7 +1139,7 @@ class iTopDesignFormat
*/ */
protected function From33To32($oFactory) protected function From33To32($oFactory)
{ {
// Nothing for now... $this->RemoveNodeFromXPath('/itop_design/branding/local_brandings');
} }
/** /**

View File

@@ -93,15 +93,28 @@ class Branding
*/ */
protected static function GetLogoPath(string $sType, string $sAppPath, ?string $sModulePath = null): string protected static function GetLogoPath(string $sType, string $sAppPath, ?string $sModulePath = null): string
{ {
$sDefaultLogoPath = static::$aLogoPaths[$sType]['default'];
$sWorkingPath = APPROOT.'env-'.utils::GetCurrentEnvironment().'/'; $sWorkingPath = APPROOT.'env-'.utils::GetCurrentEnvironment().'/';
$aThemeParameters = json_decode(@file_get_contents($sWorkingPath.'branding/logos.json'), true); $aThemeParameters = json_decode(@file_get_contents($sWorkingPath.'branding/logos.json'), true);
if (isset($aThemeParameters[$sType])) { //environment type from config.php
$sCustomLogoPath = $aThemeParameters[$sType]; $sEnvType = MetaModel::GetConfig()->Get('local_branding');
if (utils::IsNullOrEmptyString($sEnvType)) {
$sEnvType = 'default';
}
if (isset($aThemeParameters[$sEnvType]) && isset($aThemeParameters[$sEnvType][$sType])) {
$sCustomLogoPath = $aThemeParameters[$sEnvType][$sType];
if (file_exists($sWorkingPath.$sCustomLogoPath)) { if (file_exists($sWorkingPath.$sCustomLogoPath)) {
return ($sModulePath ?? $sAppPath).$sCustomLogoPath; return ($sModulePath ?? $sAppPath).$sCustomLogoPath;
} }
} }
//if not found => take the default logo
$sEnvType = 'default';
if (isset($aThemeParameters[$sEnvType]) && isset($aThemeParameters[$sEnvType][$sType])) {
$sCustomLogoPath = $aThemeParameters[$sEnvType][$sType];
if (file_exists($sWorkingPath.$sCustomLogoPath)) {
return ($sModulePath ?? $sAppPath).$sCustomLogoPath;
}
}
$sDefaultLogoPath = static::$aLogoPaths[$sType]['default'];
return $sAppPath.$sDefaultLogoPath; return $sAppPath.$sDefaultLogoPath;
} }
@@ -201,7 +214,12 @@ class Branding
*/ */
public static function GetPortalFavIconAbsoluteUrl(): string public static function GetPortalFavIconAbsoluteUrl(): string
{ {
return static::GetLogoAbsoluteUrl(static::ENUM_LOGO_TYPE_PORTAL_FAVICON); $sIcon = static::GetLogoAbsoluteUrl(static::ENUM_LOGO_TYPE_PORTAL_FAVICON);
if (utils::IsNullOrEmptyString($sIcon)) {
return static::GetLogoAbsoluteUrl(static::ENUM_LOGO_TYPE_MAIN_FAVICON);
}
return $sIcon;
} }
/** /**
@@ -213,6 +231,11 @@ class Branding
*/ */
public static function GetLoginFavIconAbsoluteUrl(): string public static function GetLoginFavIconAbsoluteUrl(): string
{ {
return static::GetLogoAbsoluteUrl(static::ENUM_LOGO_TYPE_LOGIN_FAVICON); $sIcon = static::GetLogoAbsoluteUrl(static::ENUM_LOGO_TYPE_LOGIN_FAVICON);
if (utils::IsNullOrEmptyString($sIcon)) {
return static::GetLogoAbsoluteUrl(static::ENUM_LOGO_TYPE_MAIN_FAVICON);
}
return $sIcon;
} }
} }

View File

@@ -1,3 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.2"> <itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.2">
<branding>
<main_favicon _delta="define">
<fileref ref="logo_rvb"/>
</main_favicon>
<login_favicon _delta="define">
<fileref ref="logo_log"/>
</login_favicon>
<portal_favicon _delta="define">
<fileref ref="logo_log"/>
</portal_favicon>
<themes>
<theme id="fullmoon" _delta="define">
<variables>
<variable id="ibo-page-banner--background-color">$ibo-color-red-600</variable>
<variable id="ibo-page-banner--text-color">$ibo-color-red-100</variable>
<variable id="ibo-page-banner--text-content">"THIS IS A TEST INSTANCE"</variable>
</variables>
<imports>
<import id="ignored-because-lack-xsi-type">ignored-because-lack-xsi-type.scss</import>
<import id="ok-because-xsi-type-variables" xsi:type="variables">ok-because-xsi-type-variables.scss</import>
<import id="ok-because-xsi-type-utilities" xsi:type="utilities">ok-because-xsi-type-utilities.scss</import>
</imports>
<stylesheets>
<stylesheet id="fullmoon">../css/backoffice/main.scss</stylesheet>
<stylesheet id="environment-banner">../css/backoffice/themes/page-banner.scss</stylesheet>
</stylesheets>
<precompiled_stylesheet>itop-structure/precompiled-themes/test-red/main.css</precompiled_stylesheet>
</theme>
</themes>
</branding>
</itop_design> </itop_design>

View File

@@ -1,3 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.2"> <itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.2">
<branding>
<main_favicon _delta="define">
<fileref ref="logo_rvb"/>
</main_favicon>
<login_favicon _delta="define">
<fileref ref="logo_log"/>
</login_favicon>
<portal_favicon _delta="define">
<fileref ref="logo_log"/>
</portal_favicon>
<themes>
<theme id="fullmoon" _delta="define">
<variables>
<variable id="ibo-page-banner--background-color">$ibo-color-red-600</variable>
<variable id="ibo-page-banner--text-color">$ibo-color-red-100</variable>
<variable id="ibo-page-banner--text-content">"THIS IS A TEST INSTANCE"</variable>
</variables>
<imports>
<import id="ignored-because-lack-xsi-type">ignored-because-lack-xsi-type.scss</import>
<import id="ok-because-xsi-type-variables" xsi:type="variables">ok-because-xsi-type-variables.scss</import>
<import id="ok-because-xsi-type-utilities" xsi:type="utilities">ok-because-xsi-type-utilities.scss</import>
</imports>
<stylesheets>
<stylesheet id="fullmoon">../css/backoffice/main.scss</stylesheet>
<stylesheet id="environment-banner">../css/backoffice/themes/page-banner.scss</stylesheet>
</stylesheets>
<precompiled_stylesheet>itop-structure/precompiled-themes/test-red/main.css</precompiled_stylesheet>
</theme>
</themes>
<local_brandings>
<local_branding id="test">
<main_favicon _delta="define">
<fileref ref="logo_rvb_test"/>
</main_favicon>
<login_favicon _delta="define">
<fileref ref="logo_log_test"/>
</login_favicon>
<portal_favicon _delta="define">
<fileref ref="logo_log_test"/>
</portal_favicon>
<default_theme>
<value>fullmoon</value>
</default_theme>
<allowed_themes>
<allowed_theme id="fullmoon">
</allowed_themes>
</local_branding>
</local_brandings>
</branding>
</itop_design> </itop_design>