mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-12 23:14:18 +01:00
N°3363 - Add favicon in branding (#522)
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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 #}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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'],
|
||||
];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user