N°3363 - Add favicon in branding (#522)

This commit is contained in:
Anne-Catherine
2024-02-28 09:59:11 +01:00
committed by GitHub
parent baa05ba8d4
commit 1394bc221d
13 changed files with 161 additions and 35 deletions

View File

@@ -82,7 +82,7 @@ class LoginWebPage extends NiceWebPage
}
protected static $m_sLoginFailedMessage = '';
public function __construct($sTitle = null)
{
if ($sTitle === null) {
@@ -101,6 +101,15 @@ class LoginWebPage extends NiceWebPage
$this->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/font-awesome/css/all.min.css');
}
/**
* @inheritDoc
* @since 3.2.0
*/
protected function GetFaviconAbsoluteUrl()
{
return Branding::GetLoginFavIconAbsoluteUrl();
}
public static function SetLoginFailedMessage($sMessage)
{
self::$m_sLoginFailedMessage = $sMessage;

View File

@@ -52,6 +52,8 @@ class Basic extends AbstractConfiguration
$aPortalConf = $this->ParseGlobalProperties($aPortalConf);
// - Rectifying portal logo url
$aPortalConf = $this->AppendLogoUri($aPortalConf);
// - Rectifying portal favicon url
$aPortalConf = $this->AppendFavIconUri($aPortalConf);
}
catch (Exception $oException)
{
@@ -71,10 +73,11 @@ class Basic extends AbstractConfiguration
{
$aPortalConf = array(
'properties' => array(
'id' => $_ENV['PORTAL_ID'],
'name' => 'Page:DefaultTitle',
'logo' => Branding::GetPortalLogoAbsoluteUrl(),
'themes' => array(
'id' => $_ENV['PORTAL_ID'],
'name' => 'Page:DefaultTitle',
'logo' => Branding::GetPortalLogoAbsoluteUrl(),
'favicon' => Branding::GetPortalFavIconAbsoluteUrl(),
'themes' => array(
'bootstrap' => 'itop-portal-base/portal/public/css/bootstrap-theme-combodo.scss',
'portal' => 'itop-portal-base/portal/public/css/portal.scss',
'others' => array(),
@@ -116,11 +119,8 @@ class Basic extends AbstractConfiguration
case 'name':
case 'urlmaker_class':
case 'triggers_query':
$aPortalConf['properties'][$oPropertyNode->nodeName] = $oPropertyNode->GetText(
$aPortalConf['properties'][$oPropertyNode->nodeName]
);
break;
case 'logo':
case 'favicon':
$aPortalConf['properties'][$oPropertyNode->nodeName] = $oPropertyNode->GetText(
$aPortalConf['properties'][$oPropertyNode->nodeName]
);
@@ -263,8 +263,7 @@ class Basic extends AbstractConfiguration
private function AppendLogoUri(array $aPortalConf)
{
$sLogoUri = $aPortalConf['properties']['logo'];
if (!preg_match('/^http/', $sLogoUri))
{
if (!preg_match('/^http/', $sLogoUri)) {
// We prefix it with the server base url
$sLogoUri = utils::GetAbsoluteUrlAppRoot().'env-'.utils::GetCurrentEnvironment().'/'.$sLogoUri;
}
@@ -272,4 +271,23 @@ class Basic extends AbstractConfiguration
return $aPortalConf;
}
/**
* @param array $aPortalConf
*
* @return array
* @throws \Exception
* @since 3.2.0 N°3363
*/
private function AppendFaviconUri(array $aPortalConf)
{
$sFaviconUri = $aPortalConf['properties']['favicon'];
if (!preg_match('/^http/', $sFaviconUri)) {
// We prefix it with the server base url
$sFaviconUri = utils::GetAbsoluteUrlAppRoot().'env-'.utils::GetCurrentEnvironment().'/'.$sFaviconUri;
}
$aPortalConf['properties']['favicon'] = $sFaviconUri;
return $aPortalConf;
}
}

View File

@@ -23,7 +23,7 @@
{% block pPageExtraMetas %}
{% 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>
<link rel="shortcut icon" href="{{ app['combodo.absolute_url'] ~ 'images/favicon.ico'|add_itop_version }}" />
<link rel="shortcut icon" href="{{ app['combodo.portal.instance.conf'].properties.favicon|add_itop_version }}"/>
{% block pPageStylesheets %}
{# First bootstrap core, lib themes, then bootstrap theme, portal adjustements #}

View File

@@ -3652,12 +3652,15 @@ EOF;
$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],
];
$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) {
@@ -3677,7 +3680,7 @@ EOF;
{
SetupUtils::rrmdir($sTempTargetDir.'/branding/images');
}
// Compile themes
$this->CompileThemes($oBrandingNode, $sTempTargetDir);
}

View File

@@ -910,8 +910,8 @@ class iTopDesignFormat
$oNodeList = $oXPath->query('/itop_design/branding/themes/theme[@id="test-red"]/variables/variable[@id="backoffice-environment-banner-background-color"]');
foreach ($oNodeList as $oNode) {
$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"]');
foreach ($oNodeList as $oNode) {
$oNode->setAttribute('id', 'ibo-page-banner--text-color');
@@ -1108,7 +1108,10 @@ class iTopDesignFormat
*/
protected function From32To31($oFactory)
{
// Nothing for now...
// N°3363 - Add favicon in branding
$this->RemoveNodeFromXPath('/itop_design/branding/main_favicon');
$this->RemoveNodeFromXPath('/itop_design/branding/portal_favicon');
$this->RemoveNodeFromXPath('/itop_design/branding/login_favicon');
}
/**

View File

@@ -19,6 +19,7 @@
namespace Combodo\iTop\Application;
use MetaModel;
use utils;
/**
@@ -38,27 +39,52 @@ class Branding
public const ENUM_LOGO_TYPE_PORTAL_LOGO = 'portal_logo';
/** @var string Logo used in the login pages */
public const ENUM_LOGO_TYPE_LOGIN_LOGO = 'login_logo';
/**
* @var string Logo used in most pages (backoffice, ...)
* @since 3.2.0 N°3363
*/
public const ENUM_LOGO_TYPE_MAIN_FAVICON = 'main_favicon';
/**
* @var string Logo used in the end-users portals
* @since 3.2.0 N°3363
*/
public const ENUM_LOGO_TYPE_PORTAL_FAVICON = 'portal_favicon';
/**
* @var string Logo used in the login page
* @since 3.2.0 N°3363
*/
public const ENUM_LOGO_TYPE_LOGIN_FAVICON = 'login_favicon';
/** @var string Default logo */
public const DEFAULT_LOGO_TYPE = self::ENUM_LOGO_TYPE_MAIN_LOGO_FULL;
/** @var \string[][] Relative paths to the logos from the current environment folder */
public static $aLogoPaths = [
self::ENUM_LOGO_TYPE_MAIN_LOGO_FULL => [
self::ENUM_LOGO_TYPE_MAIN_LOGO_FULL => [
'default' => 'images/itop-logo.png',
],
self::ENUM_LOGO_TYPE_MAIN_LOGO_COMPACT => [
'default' => 'images/itop-logo-square.png',
],
self::ENUM_LOGO_TYPE_PORTAL_LOGO => [
self::ENUM_LOGO_TYPE_PORTAL_LOGO => [
'default' => 'images/logo-itop-dark-bg.svg',
],
self::ENUM_LOGO_TYPE_LOGIN_LOGO => [
self::ENUM_LOGO_TYPE_LOGIN_LOGO => [
'default' => 'images/itop-logo-external.png',
],
self::ENUM_LOGO_TYPE_MAIN_FAVICON => [
'default' => 'images/favicon.ico',
],
self::ENUM_LOGO_TYPE_PORTAL_FAVICON => [
'default' => 'images/favicon.ico',
],
self::ENUM_LOGO_TYPE_LOGIN_FAVICON => [
'default' => 'images/favicon.ico',
],
];
/**
* Return url or path of logo defined by $sType
*
* @param string $sType
* @param string $sAppPath
* @param ?string $sModulePath
@@ -73,7 +99,7 @@ class Branding
if (isset($aThemeParameters[$sType])) {
$sCustomLogoPath = $aThemeParameters[$sType];
if (file_exists($sWorkingPath.$sCustomLogoPath)) {
return ($sModulePath??$sAppPath).$sCustomLogoPath;
return ($sModulePath ?? $sAppPath).$sCustomLogoPath;
}
}
@@ -154,4 +180,39 @@ class Branding
return static::GetLogoAbsoluteUrl(static::ENUM_LOGO_TYPE_LOGIN_LOGO);
}
/**
* Return the absolute URL for thefavicon
*
* @return string
* @throws \Exception
* @since 3.2.0 N°3363
*/
public static function GetMainFavIconAbsoluteUrl(): string
{
return static::GetLogoAbsoluteUrl(static::ENUM_LOGO_TYPE_MAIN_FAVICON);
}
/**
* Return the absolute URL for thefavicon
*
* @return string
* @throws \Exception
* @since 3.2.0 N°3363
*/
public static function GetPortalFavIconAbsoluteUrl(): string
{
return static::GetLogoAbsoluteUrl(static::ENUM_LOGO_TYPE_PORTAL_FAVICON);
}
/**
* Return the absolute URL for thefavicon
*
* @return string
* @throws \Exception
* @since 3.2.0 N°3363
*/
public static function GetLoginFavIconAbsoluteUrl(): string
{
return static::GetLogoAbsoluteUrl(static::ENUM_LOGO_TYPE_LOGIN_FAVICON);
}
}

View File

@@ -41,7 +41,7 @@ class UnauthenticatedWebPage extends NiceWebPage
private $sContent;
private $sPanelTitle;
private $sPanelIcon;
// TODO 3.0 Find a clever way to allow theme customization for unauthenticated webpages
private $sCustomThemeUrl;
@@ -288,4 +288,13 @@ class UnauthenticatedWebPage extends NiceWebPage
$this->add_linked_stylesheet($this->sCustomThemeUrl);
}
}
/**
* @inheritDoc
* @since 3.2.0
*/
protected function GetFaviconAbsoluteUrl()
{
return Branding::GetLoginFavIconAbsoluteUrl();
}
}

View File

@@ -6,6 +6,7 @@
namespace Combodo\iTop\Application\WebPage;
use Combodo\iTop\Application\Branding;
use Combodo\iTop\Application\Helper\Session;
use Combodo\iTop\Application\Helper\WebResourcesHelper;
use Combodo\iTop\Application\TwigBase\Twig\TwigHelper;
@@ -1761,17 +1762,13 @@ EOD
}
/**
* Return the absolute URL for the favicon
*
* @return string
* @return string Absolute URL for the favicon
* @throws \Exception
* @since 3.0.0
*/
protected function GetFaviconAbsoluteUrl()
{
// TODO 3.0.0: Make it a property so it can be changed programmatically
// TODO 3.0.0: How to set both dark/light mode favicons
return utils::GetAbsoluteUrlAppRoot().'images/favicon.ico';
return Branding::GetMainFavIconAbsoluteUrl();
}
/**
@@ -1838,7 +1835,7 @@ EOD
/**
* @return bool
*
*
* @since 3.2.0
*/
public function GetAddJSDict(): bool
@@ -1850,7 +1847,7 @@ EOD
* @param bool $bAddJSDict
*
* @return $this
*
*
* @since 3.2.0
*/
public function SetAddJSDict(bool $bAddJSDict)

View File

@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.2">
</itop_design>

View File

@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.1">
</itop_design>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.1">
<branding/>
</itop_design>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<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>
</branding>
</itop_design>

View File

@@ -143,6 +143,8 @@ class iTopDesignFormatTest extends ItopTestCase
'3.0 to 1.7' => ['sXmlFileName' => '3.0_to_1.7'],
'3.0 to 3.1' => ['sXmlFileName' => '3.0_to_3.1'],
'3.1 to 3.0' => ['sXmlFileName' => '3.1_to_3.0'],
'3.1 to 3.2' => ['sXmlFileName' => '3.1_to_3.2'],
'3.2 to 3.1' => ['sXmlFileName' => '3.2_to_3.1'],
'Bug_4569' => ['sXmlFileName' => 'Bug_4569'],
];
}