N°8031 - Make all portal bricks use custom templates for all templates (#696)

Service implementation
This commit is contained in:
Benjamin Dalsass
2025-01-13 08:04:49 +01:00
committed by GitHub
parent 93dba0644d
commit 9fadbb5eb1
52 changed files with 1681 additions and 501 deletions

View File

@@ -1,19 +1,13 @@
framework:
cache:
# Unique name of your app: used to compute stable namespaces for cache keys.
#prefix_seed: your_vendor_name/app_name
# Unique name of your app: used to compute stable namespaces for cache keys.
prefix_seed: combodo/itop
# The "app" cache stores to the filesystem by default.
# The data in this cache should persist between deploys.
# Other options include:
# filesystem
app: cache.adapter.filesystem
# Redis
#app: cache.adapter.redis
#default_redis_provider: redis://localhost
# Namespaced pools use the above "app" backend by default
pools:
# APCu (not recommended with heavy random-write workloads as memory fragmentation can cause perf issues)
#app: cache.adapter.apcu
# Namespaced pools use the above "app" backend by default
#pools:
#my.dedicated.cache: null
templates_cache_pool:
adapter: cache.app

View File

@@ -23,9 +23,13 @@ namespace Combodo\iTop\Portal\Brick;
require_once APPROOT.'/core/moduledesign.class.inc.php';
require_once APPROOT.'/setup/compiler.class.inc.php';
use Combodo\iTop\DesignElement;
use Combodo\iTop\Portal\Service\TemplatesProvider\TemplatesProviderInterface;
use Combodo\iTop\Portal\Service\TemplatesProvider\TemplateDefinitionDto;
use Combodo\iTop\Portal\Service\TemplatesProvider\TemplatesProviderService;
use Combodo\iTop\Portal\Service\TemplatesProvider\TemplatesRegister;
use DOMFormatException;
use ModuleDesign;
use Combodo\iTop\DesignElement;
/**
* Description of AbstractBrick
@@ -36,7 +40,7 @@ use Combodo\iTop\DesignElement;
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
* @since 2.3.0
*/
abstract class AbstractBrick
abstract class AbstractBrick implements TemplatesProviderInterface
{
/** @var string ENUM_DATA_LOADING_LAZY */
const ENUM_DATA_LOADING_LAZY = 'lazy';
@@ -53,7 +57,7 @@ abstract class AbstractBrick
const DEFAULT_VISIBLE = true;
/** @var float DEFAULT_RANK */
const DEFAULT_RANK = 1.0;
/** @var string|null DEFAULT_PAGE_TEMPLATE_PATH */
/** @var string|null DEFAULT_PAGE_TEMPLATE_PATH @deprecated since 3.2.1 */
const DEFAULT_PAGE_TEMPLATE_PATH = null;
/** @var string DEFAULT_TITLE */
const DEFAULT_TITLE = '';
@@ -65,10 +69,8 @@ abstract class AbstractBrick
const DEFAULT_ALLOWED_PROFILES_OQL = '';
/** @var string DEFAULT_DENIED_PROFILES_OQL */
const DEFAULT_DENIED_PROFILES_OQL = '';
/** @var array $DEFAULT_TEMPLATES_PATH */
protected static $DEFAULT_TEMPLATES_PATH = [
'page' => self::DEFAULT_PAGE_TEMPLATE_PATH,
];
/** @var string TEMPLATES_BASE_PATH */
const TEMPLATES_BASE_PATH = 'itop-portal-base/portal/templates/bricks/';
/** @var string $sId */
protected $sId;
@@ -80,7 +82,7 @@ abstract class AbstractBrick
protected $bVisible;
/** @var float $fRank */
protected $fRank;
/** @var string|null $sPageTemplatePath */
/** @var string|null $sPageTemplatePath @deprecated since 3.2.1 */
protected $sPageTemplatePath;
/** @var string $sTitle */
protected $sTitle;
@@ -97,6 +99,37 @@ abstract class AbstractBrick
/** @var string $sDeniedProfilesOql */
protected $sDeniedProfilesOql;
/** @var \Combodo\iTop\Portal\Service\TemplatesProvider\TemplatesProviderService Templating provider service for registering default templates paths */
private static TemplatesProviderService $oTemplatesProviderService;
/** @inheritdoc */
public static function RegisterTemplates(TemplatesRegister $oTemplatesRegister): void
{
$oTemplatesRegister->RegisterTemplates(self::class,
TemplateDefinitionDto::Create('page', static::TEMPLATES_BASE_PATH . 'layout.html.twig'),
);
}
/**
* @param \Combodo\iTop\Portal\Service\TemplatesProvider\TemplatesProviderService $oTemplateProviderService
*
* @return void
*/
public static function SetTemplatesProviderService(TemplatesProviderService $oTemplateProviderService): void
{
self::$oTemplatesProviderService = $oTemplateProviderService;
}
/**
* Return the templates provider service.
*
* @return \Combodo\iTop\Portal\Service\TemplatesProvider\TemplatesProviderService
*/
protected static function GetTemplatesProviderService(): TemplatesProviderService
{
return self::$oTemplatesProviderService;
}
/**
* Returns all enum values for the data loading modes in an array.
*
@@ -116,7 +149,9 @@ abstract class AbstractBrick
$this->bActive = static::DEFAULT_ACTIVE;
$this->bVisible = static::DEFAULT_VISIBLE;
$this->fRank = static::DEFAULT_RANK;
$this->sPageTemplatePath = static::$DEFAULT_TEMPLATES_PATH['page'];
// BEGIN cleaning 3.2.1 deprecated
$this->sPageTemplatePath = static::DEFAULT_PAGE_TEMPLATE_PATH;
// END cleaning 3.2.1 deprecated
$this->sTitle = static::DEFAULT_TITLE;
$this->sDescription = static::DEFAULT_DESCRIPTION;
$this->sDataLoading = static::DEFAULT_DATA_LOADING;
@@ -180,10 +215,12 @@ abstract class AbstractBrick
* Returns the brick page template path
*
* @return string
*
* @deprecated since 3.2.1 use GetTemplatePath('page') instead
*/
public function GetPageTemplatePath()
{
return $this->sPageTemplatePath;
return $this->GetTemplatePath('page');
}
/**
@@ -327,10 +364,13 @@ abstract class AbstractBrick
* @param string $sPageTemplatePath
*
* @return \Combodo\iTop\Portal\Brick\AbstractBrick
*
* @deprecated since 3.2.1 use SetTemplatePath('page') instead
*/
public function SetPageTemplatePath($sPageTemplatePath)
{
$this->sPageTemplatePath = $sPageTemplatePath;
$this->SetTemplatePath( 'page', $sPageTemplatePath);
return $this;
}
@@ -576,20 +616,6 @@ abstract class AbstractBrick
return ($this->sDescription !== null && $this->sDescription !== '');
}
/**
* @param $sTemplateId
* @param $sTemplatePath
*
* @return void
* @since 3.2.1
*/
public static function SetDefaultTemplatePath($sTemplateId, $sTemplatePath)
{
if(array_key_exists($sTemplateId, static::$DEFAULT_TEMPLATES_PATH)) {
static::$DEFAULT_TEMPLATES_PATH[$sTemplateId] = $sTemplatePath;
}
}
/**
* Load the brick's data from the xml passed as a ModuleDesignElement.
* This is used to set all the brick attributes at once.
@@ -634,7 +660,7 @@ abstract class AbstractBrick
{
/** @var \Combodo\iTop\DesignElement $oTemplateNode */
$oTemplateNode = $oTemplateNodeList->item(0);
$this->SetPageTemplatePath($oTemplateNode->GetText(static::DEFAULT_PAGE_TEMPLATE_PATH));
$this->SetTemplatePath('page', $oTemplateNode->GetText(static::DEFAULT_PAGE_TEMPLATE_PATH));
}
break;
case 'title':
@@ -678,32 +704,48 @@ abstract class AbstractBrick
}
/**
* Load brick configuration that is not part of the brick definition but is part of the portal global properties.
* Override the brick default template path.
* Template is managed by the TemplatesProviderService.
*
* @param $aPortalProperties
*
* @return void
* @since 3.2.1
*
* @param string $sTemplateId
* @param string $sTileTemplatePath
*
* @return \Combodo\iTop\Portal\Brick\PortalBrick
*/
public static function LoadClassDefinitionFromPortalProperties($aPortalProperties)
public function SetTemplatePath(string $sTemplateId, string $sTileTemplatePath): AbstractBrick
{
// Check if they are any brick templates
if(!array_key_exists('bricks', $aPortalProperties['templates']) || !is_array($aPortalProperties['templates']['bricks'])) {
return;
}
// Get the bricks templates
$aBricksTemplates = $aPortalProperties['templates']['bricks'];
$sClassFQCN = static::class;
// Get the current brick templates
$aCurrentBricksTemplates = array_key_exists($sClassFQCN, $aBricksTemplates) ? $aBricksTemplates[$sClassFQCN] : [];
foreach($aCurrentBricksTemplates as $sTemplateKey => $sTemplate) {
// Clean the template id
$sTemplateId = str_ireplace($sClassFQCN.':', '', $sTemplateKey);
// Call the set method for the template
static::SetDefaultTemplatePath($sTemplateId, $sTemplate);
}
static::GetTemplatesProviderService()->OverrideInstanceTemplatePath($this, $sTemplateId, $sTileTemplatePath);
return $this;
}
/**
* Returns the brick template path.
* Template is managed by the TemplatesProviderService.
*
* @since 3.2.1
*
* @param string $sTemplateId template identifier
*
* @return string template path
*/
public function GetTemplatePath(string $sTemplateId): string
{
return static::GetTemplatesProviderService()->GetProviderInstanceTemplatePath($this, $sTemplateId);
}
/**
* Returns true if this brick template path is overridden.
*
* @since 3.2.1
*
* @param string $sTemplateId template identifier
*
* @return string|null
*/
public function HasInstanceOverriddenTemplate(string $sTemplateId): ?string
{
return static::GetTemplatesProviderService()->HasInstanceOverriddenTemplate($this, $sTemplateId);
}
}

View File

@@ -21,6 +21,8 @@
namespace Combodo\iTop\Portal\Brick;
use Combodo\iTop\DesignElement;
use Combodo\iTop\Portal\Service\TemplatesProvider\TemplateDefinitionDto;
use Combodo\iTop\Portal\Service\TemplatesProvider\TemplatesRegister;
use Dict;
use DOMFormatException;
@@ -38,11 +40,10 @@ class AggregatePageBrick extends PortalBrick
// Overloaded constants
const DEFAULT_DECORATION_CLASS_HOME = 'fas fa-tachometer-alt';
const DEFAULT_DECORATION_CLASS_NAVIGATION_MENU = 'fas fa-tachometer-alt fa-2x';
/** @var string @deprecated since 3.2.1 */
const DEFAULT_PAGE_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/aggregate-page/layout.html.twig';
protected static $DEFAULT_TEMPLATES_PATH = [
'page' => self::DEFAULT_PAGE_TEMPLATE_PATH,
'tile' => self::DEFAULT_TILE_TEMPLATE_PATH,
];
// Overloaded variables
public static $sRouteName = 'p_aggregatepage_brick';
@@ -51,6 +52,15 @@ class AggregatePageBrick extends PortalBrick
*/
private $aAggregatePageBricks = array();
/** @inheritdoc */
public static function RegisterTemplates(TemplatesRegister $oTemplatesRegister): void
{
parent::RegisterTemplates($oTemplatesRegister);
$oTemplatesRegister->RegisterTemplates(self::class,
TemplateDefinitionDto::Create('page', static::TEMPLATES_BASE_PATH . 'aggregate-page/layout.html.twig')
);
}
/**
* AggregatePageBrick constructor.
*/

View File

@@ -19,9 +19,9 @@
namespace Combodo\iTop\Portal\Brick;
use Combodo\iTop\Portal\Service\TemplatesProvider\TemplatesProviderService;
use DOMFormatException;
use Exception;
use Symfony\Component\DependencyInjection\ContainerInterface;
use UserRights;
use ModuleDesign;
use Combodo\iTop\Portal\Helper\ApplicationHelper;
@@ -48,21 +48,20 @@ class BrickCollection
private $aHomeOrdering;
/** @var array $aNavigationMenuOrdering */
private $aNavigationMenuOrdering;
/** @var \array $aCombodoPortalInstanceConf
* @since 3.2.1
*/
private $aCombodoPortalInstanceConf;
/**
* BrickCollection constructor.
*
* @param \ModuleDesign $oModuleDesign
* @param $aCombodoPortalInstanceConf
* @param \Combodo\iTop\Portal\Service\TemplatesProvider\TemplatesProviderService $oTemplatesProviderService
*
* @throws \Exception
* @since 3.2.1 Added $aCombodoPortalInstanceConf parameter
*
* @since 3.2.1 Added $oTemplatesProviderService parameter
* Important: The service is not directly used, but the injection ensure that the service is initialized.
* Bricks may need to use the service to get the templates.
*/
public function __construct(ModuleDesign $oModuleDesign, array $aCombodoPortalInstanceConf)
public function __construct(ModuleDesign $oModuleDesign, TemplatesProviderService $oTemplatesProviderService)
{
$this->oModuleDesign = $oModuleDesign;
$this->aAllowedBricks = null;
@@ -70,7 +69,6 @@ class BrickCollection
$this->iDisplayedInNavigationMenu = 0;
$this->aHomeOrdering = array();
$this->aNavigationMenuOrdering = array();
$this->aCombodoPortalInstanceConf = $aCombodoPortalInstanceConf;
$this->Load();
}
@@ -202,10 +200,6 @@ class BrickCollection
{
if (class_exists($sBrickClass))
{
// Load the portal properties that are common to all bricks of this type
$sBrickClass::LoadClassDefinitionFromPortalProperties($this->aCombodoPortalInstanceConf['properties']);
/** @var \Combodo\iTop\Portal\Brick\PortalBrick $oBrick */
$oBrick = new $sBrickClass();

View File

@@ -20,8 +20,10 @@
namespace Combodo\iTop\Portal\Brick;
use DOMFormatException;
use Combodo\iTop\DesignElement;
use Combodo\iTop\Portal\Service\TemplatesProvider\TemplateDefinitionDto;
use Combodo\iTop\Portal\Service\TemplatesProvider\TemplatesRegister;
use DOMFormatException;
/**
* Description of BrowseBrick
@@ -32,13 +34,23 @@ use Combodo\iTop\DesignElement;
*/
class BrowseBrick extends PortalBrick
{
/** @var string DEFAULT_PAGE_TEMPLATE_PATH */
/**
* @var string DEFAULT_PAGE_TEMPLATE_PATH
* @deprecated 3.2.1
*/
const DEFAULT_MODE_LIST_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/browse/mode_list.html.twig';
/** @var string DEFAULT_MODE_MOSAIC_TEMPLATE_PATH */
/**
* @var string DEFAULT_MODE_MOSAIC_TEMPLATE_PATH
* @deprecated 3.2.1
*/
const DEFAULT_MODE_MOSAIC_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/browse/mode_mosaic.html.twig';
/** @var string DEFAULT_MODE_TREE_TEMPLATE_PATH */
/**
* @var string DEFAULT_MODE_TREE_TEMPLATE_PATH
* @deprecated 3.2.1
*/
const DEFAULT_MODE_TREE_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/browse/mode_tree.html.twig';
/** @var string ENUM_BROWSE_MODE_LIST */
const ENUM_BROWSE_MODE_LIST = 'list';
/** @var string ENUM_BROWSE_MODE_TREE */
@@ -84,13 +96,6 @@ class BrowseBrick extends PortalBrick
const DEFAULT_ACTION_OPENING_TARGET = self::ENUM_OPENING_TARGET_MODAL;
/** @var int DEFAULT_LIST_LENGTH */
const DEFAULT_LIST_LENGTH = 20;
protected static $DEFAULT_TEMPLATES_PATH = [
'page' => self::DEFAULT_PAGE_TEMPLATE_PATH,
'tile' => self::DEFAULT_TILE_TEMPLATE_PATH,
'mode-list'=> self::DEFAULT_MODE_LIST_TEMPLATE_PATH,
'mode-mosaic'=> self::DEFAULT_MODE_MOSAIC_TEMPLATE_PATH,
'mode-tree'=> self::DEFAULT_MODE_TREE_TEMPLATE_PATH,
];
// Overloaded variables
public static $sRouteName = 'p_browse_brick';
@@ -111,6 +116,18 @@ class BrowseBrick extends PortalBrick
/** @var int $iDefaultListLength */
protected $iDefaultListLength;
/** @inheritdoc */
public static function RegisterTemplates(TemplatesRegister $oTemplatesRegister): void
{
parent::RegisterTemplates($oTemplatesRegister);
$oTemplatesRegister->RegisterTemplates(self::class,
TemplateDefinitionDto::Create('page', static::TEMPLATES_BASE_PATH . 'browse/layout.html.twig'),
TemplateDefinitionDto::Create('page_list', static::TEMPLATES_BASE_PATH . 'browse/mode_list.html.twig'),
TemplateDefinitionDto::Create('page_tree', static::TEMPLATES_BASE_PATH . 'browse/mode_tree.html.twig'),
TemplateDefinitionDto::Create('page_mosaic', static::TEMPLATES_BASE_PATH . 'browse/mode_mosaic.html.twig'),
);
}
/**
* BrowseBrick constructor.
*/
@@ -369,13 +386,8 @@ class BrowseBrick extends PortalBrick
$oTemplateNode = $oModeNode->GetOptionalElement('template');
if (($oTemplateNode !== null) && ($oTemplateNode->GetText() !== null))
{
$sTemplatePath = $oTemplateNode->GetText();
$this->SetTemplatePath('page_'.$sModeId, $oTemplateNode->GetText());
}
else
{
$sTemplatePath = static::$DEFAULT_TEMPLATES_PATH['mode-'.$sModeId];
}
$aModeData['template'] = $sTemplatePath;
$this->AddAvailableBrowseMode($sModeId, $aModeData);
}

View File

@@ -20,8 +20,8 @@
namespace Combodo\iTop\Portal\Brick;
use DOMFormatException;
use Combodo\iTop\DesignElement;
use DOMFormatException;
/**
* Description of CreateBrick
@@ -35,11 +35,6 @@ class CreateBrick extends PortalBrick
// Overloaded constants
const DEFAULT_DECORATION_CLASS_HOME = 'fas fa-plus';
const DEFAULT_DECORATION_CLASS_NAVIGATION_MENU = 'fas fa-plus fa-2x';
const DEFAULT_PAGE_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/create/modal.html.twig';
protected static $DEFAULT_TEMPLATES_PATH = [
'page' => self::DEFAULT_PAGE_TEMPLATE_PATH,
'tile' => self::DEFAULT_TILE_TEMPLATE_PATH,
];
/** @var string DEFAULT_CLASS */
const DEFAULT_CLASS = '';

View File

@@ -20,8 +20,10 @@
namespace Combodo\iTop\Portal\Brick;
use DOMFormatException;
use Combodo\iTop\DesignElement;
use Combodo\iTop\Portal\Service\TemplatesProvider\TemplateDefinitionDto;
use Combodo\iTop\Portal\Service\TemplatesProvider\TemplatesRegister;
use DOMFormatException;
/**
* Description of FilterBrick
@@ -34,13 +36,12 @@ class FilterBrick extends PortalBrick
{
// Overloaded constants
const DEFAULT_VISIBLE_NAVIGATION_MENU = false;
const DEFAULT_TILE_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/filter/tile.html.twig';
/**
* @deprecated 3.2.1
*/
const DEFAULT_TILE_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/filter/tile.html.twig';
const DEFAULT_DECORATION_CLASS_HOME = 'fas fa-search';
const DEFAULT_DECORATION_CLASS_NAVIGATION_MENU = 'fas fa-search fa-2x';
protected static $DEFAULT_TEMPLATES_PATH = [
'page' => self::DEFAULT_PAGE_TEMPLATE_PATH,
'tile' => self::DEFAULT_TILE_TEMPLATE_PATH,
];
/** @var string DEFAULT_TARGET_BRICK_CLASS */
const DEFAULT_TARGET_BRICK_CLASS = 'Combodo\\iTop\\Portal\\Brick\\BrowseBrick';
/** @var string DEFAULT_SEARCH_PLACEHOLDER_VALUE */
@@ -63,6 +64,15 @@ class FilterBrick extends PortalBrick
/** @var string $sSearchSubmitClass */
protected $sSearchSubmitClass;
/** @inheritdoc */
public static function RegisterTemplates(TemplatesRegister $oTemplatesRegister): void
{
parent::RegisterTemplates($oTemplatesRegister);
$oTemplatesRegister->RegisterTemplates(self::class,
TemplateDefinitionDto::Create('tile', static::TEMPLATES_BASE_PATH . 'filter/tile.html.twig')
);
}
/**
* FilterBrick constructor.
*/

View File

@@ -20,11 +20,14 @@
namespace Combodo\iTop\Portal\Brick;
use Exception;
use DOMFormatException;
use DBSearch;
use MetaModel;
use Combodo\iTop\DesignElement;
use Combodo\iTop\Portal\Service\TemplatesProvider\TemplateDefinitionDto;
use Combodo\iTop\Portal\Service\TemplatesProvider\TemplatesRegister;
use DBSearch;
use DOMFormatException;
use Exception;
use MetaModel;
use ModuleDesign;
class ManageBrick extends PortalBrick
{
@@ -51,26 +54,28 @@ class ManageBrick extends PortalBrick
/** @var string ENUM_DISPLAY_MODE_BAR */
const ENUM_DISPLAY_MODE_BAR = 'bar-chart';
/** @var string ENUM_PAGE_TEMPLATE_PATH_TABLE */
/** @var string ENUM_PAGE_TEMPLATE_PATH_TABLE
* @deprecated since 3.2.1
* */
const ENUM_PAGE_TEMPLATE_PATH_TABLE = 'itop-portal-base/portal/templates/bricks/manage/layout-table.html.twig';
/** @var string ENUM_PAGE_TEMPLATE_PATH_CHART */
/** @var string ENUM_PAGE_TEMPLATE_PATH_CHART
* @deprecated since 3.2.1
* */
const ENUM_PAGE_TEMPLATE_PATH_CHART = 'itop-portal-base/portal/templates/bricks/manage/layout-chart.html.twig';
// Overloaded constants
/** Overloaded constants */
const DEFAULT_DECORATION_CLASS_HOME = 'fas fa-pen-square';
const DEFAULT_DECORATION_CLASS_NAVIGATION_MENU = 'fas fa-pen-square fa-2x';
/**
* @deprecated 3.2.1
*/
const DEFAULT_PAGE_TEMPLATE_PATH = self::ENUM_PAGE_TEMPLATE_PATH_TABLE;
const DEFAULT_DATA_LOADING = self::ENUM_DATA_LOADING_LAZY;
/**
* @deprecated 3.2.1
*/
const DEFAULT_TILE_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/manage/tile-default.html.twig';
const DEFAULT_TILE_CONTROLLER_ACTION = 'Combodo\\iTop\\Portal\\Controller\\ManageBrickController::TileAction';
const DEFAULT_LAYOUT_CHART_TEMPLATE_PATH = self::ENUM_PAGE_TEMPLATE_PATH_CHART;
const DEFAULT_LAYOUT_TABLE_TEMPLATE_PATH = self::ENUM_PAGE_TEMPLATE_PATH_TABLE;
const DEFAULT_LAYOUT_BADGE_TEMPLATE_PATH = self::ENUM_PAGE_TEMPLATE_PATH_TABLE;
const DEFAULT_TILE_CHART_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/manage/tile-chart.html.twig';
const DEFAULT_TILE_TOP_LIST_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/manage/tile-top-list.html.twig';
const DEFAULT_TILE_BADGE_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/manage/tile-badge.html.twig';
const DEFAULT_TILE_DEFAULT_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/manage/tile-default.html.twig';
const DEFAULT_POPUP_EXPORT_EXCEL_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/manage/popup-export-excel.html.twig';
/** @var string DEFAULT_OQL */
const DEFAULT_OQL = '';
@@ -91,40 +96,94 @@ class ManageBrick extends PortalBrick
/** @var bool DEFAULT_GROUP_SHOW_OTHERS */
const DEFAULT_GROUP_SHOW_OTHERS = true;
protected static $DEFAULT_TEMPLATES_PATH = [
'page' => self::DEFAULT_PAGE_TEMPLATE_PATH,
'tile' => self::DEFAULT_TILE_TEMPLATE_PATH,
'layout-chart' => self::DEFAULT_LAYOUT_CHART_TEMPLATE_PATH,
'layout-table' => self::DEFAULT_LAYOUT_TABLE_TEMPLATE_PATH,
'layout-badge' => self::DEFAULT_LAYOUT_BADGE_TEMPLATE_PATH,
'tile-chart' => self::DEFAULT_TILE_CHART_TEMPLATE_PATH,
'tile-top-list' => self::DEFAULT_TILE_TOP_LIST_TEMPLATE_PATH,
'tile-badge' => self::DEFAULT_TILE_BADGE_TEMPLATE_PATH,
'tile-default' => self::DEFAULT_TILE_DEFAULT_TEMPLATE_PATH,
'popup-export-excel' => self::DEFAULT_POPUP_EXPORT_EXCEL_TEMPLATE_PATH,
];
/** @var array $aDisplayModes */
static $aDisplayModes = array(
public static array $aDisplayModes = array(
self::ENUM_DISPLAY_MODE_LIST,
self::ENUM_DISPLAY_MODE_PIE,
self::ENUM_DISPLAY_MODE_BAR,
);
/** @var array $aTileModes */
public static $aTileModes = array(
public static array $aTileModes = array(
self::ENUM_TILE_MODE_TEXT,
self::ENUM_TILE_MODE_BADGE,
self::ENUM_TILE_MODE_PIE,
self::ENUM_TILE_MODE_BAR,
self::ENUM_TILE_MODE_TOP,
);
/** Initialized in its getter as we need DEFAULT_TEMPLATE static values to be accessible */
/** @var array $aDefaultPresentationData */
private static $aDefaultPresentationData = [];
/** Specific data for the current brick, including brick definition overloads */
/** @var array $aPresentationData */
public $aPresentationData = [];
/** @var array $aPresentationData
* @deprecated since 3.2.1
*/
public static $aPresentationData = array(
self::ENUM_TILE_MODE_BADGE => array(
'decorationCssClass' => 'fas fa-id-card fa-2x',
'tileTemplate' => 'itop-portal-base/portal/templates/bricks/manage/tile-badge.html.twig',
'layoutTemplate' => self::ENUM_PAGE_TEMPLATE_PATH_TABLE,
'layoutDisplayMode' => self::ENUM_DISPLAY_MODE_LIST,
'need_details' => true,
),
self::ENUM_TILE_MODE_TOP => array(
'decorationCssClass' => 'fas fa-signal fa-rotate-270 fa-2x',
'tileTemplate' => 'itop-portal-base/portal/templates/bricks/manage/tile-top-list.html.twig',
'layoutTemplate' => self::ENUM_PAGE_TEMPLATE_PATH_TABLE,
'layoutDisplayMode' => self::ENUM_DISPLAY_MODE_LIST,
'need_details' => true,
),
self::ENUM_TILE_MODE_PIE => array(
'decorationCssClass' => 'fas fa-chart-pie fa-2x',
'tileTemplate' => 'itop-portal-base/portal/templates/bricks/manage/tile-chart.html.twig',
'layoutTemplate' => self::ENUM_PAGE_TEMPLATE_PATH_CHART,
'layoutDisplayMode' => self::ENUM_DISPLAY_MODE_PIE,
'need_details' => false,
),
self::ENUM_TILE_MODE_BAR => array(
'decorationCssClass' => 'fas fa-chart-bar fa-2x',
'tileTemplate' => 'itop-portal-base/portal/templates/bricks/manage/tile-chart.html.twig',
'layoutTemplate' => self::ENUM_PAGE_TEMPLATE_PATH_CHART,
'layoutDisplayMode' => self::ENUM_DISPLAY_MODE_BAR,
'need_details' => false,
),
self::ENUM_TILE_MODE_TEXT => array(
'decorationCssClass' => 'fas fa-pen-square fa-2x',
'tileTemplate' => self::DEFAULT_TILE_TEMPLATE_PATH,
'layoutTemplate' => self::ENUM_PAGE_TEMPLATE_PATH_TABLE,
'layoutDisplayMode' => self::ENUM_DISPLAY_MODE_LIST,
'need_details' => true,
),
);
/** @var array $aDefaultTileData */
private static array $aDefaultTileData = [
self::ENUM_TILE_MODE_BADGE => [
'decorationCssClass' => 'fas fa-id-card fa-2x',
],
self::ENUM_TILE_MODE_TOP => [
'decorationCssClass' => 'fas fa-list-ol fa-2x',
],
self::ENUM_TILE_MODE_PIE => [
'decorationCssClass' => 'fas fa-chart-pie fa-2x',
],
self::ENUM_TILE_MODE_TEXT => [
'decorationCssClass' => 'fas fa-pen-square fa-2x',
],
self::ENUM_TILE_MODE_BAR => [
'decorationCssClass' => 'fas fa-chart-bar fa-2x',
],
];
/** @var array $aDefaultLayoutData */
private static array $aDefaultLayoutData = [
self::ENUM_DISPLAY_MODE_LIST => [
'need_details' => true,
],
self::ENUM_DISPLAY_MODE_PIE => [
'need_details' => false,
],
self::ENUM_DISPLAY_MODE_BAR => [
'need_details' => false,
],
];
// Overloaded variables
public static $sRouteName = 'p_manage_brick';
@@ -153,51 +212,22 @@ class ManageBrick extends PortalBrick
protected $bGroupShowOthers;
/** @var int $iDefaultListLength */
protected $iDefaultListLength;
/** @var string $sPopupExportExcelTemplatePath */
protected $sPopupExportExcelTemplatePath;
/**
* Returns true if the $sDisplayMode need objects details for rendering.
*
* @param string $sDisplayMode
*
* @return bool
*/
static public function AreDetailsNeededForDisplayMode($sDisplayMode)
/** @inheritdoc */
public static function RegisterTemplates(TemplatesRegister $oTemplatesRegister): void
{
$bNeedDetails = false;
foreach (static::GetDefaultPresentationData() as $aData)
{
if ($aData['layoutDisplayMode'] === $sDisplayMode)
{
$bNeedDetails = $aData['need_details'];
break;
}
}
return $bNeedDetails;
}
/**
* Returns the page template path for the $sDisplayMode
*
* @param string $sDisplayMode
*
* @return string
*/
static public function GetPageTemplateFromDisplayMode($sDisplayMode)
{
$sTemplate = static::$DEFAULT_TEMPLATES_PATH['page'];
foreach (static::GetDefaultPresentationData() as $aData)
{
if ($aData['layoutDisplayMode'] === $sDisplayMode)
{
$sTemplate = $aData['layoutTemplate'];
break;
}
}
return $sTemplate;
parent::RegisterTemplates($oTemplatesRegister);
$oTemplatesRegister->RegisterTemplates(self::class,
TemplateDefinitionDto::Create('tile', static::TEMPLATES_BASE_PATH . 'manage/tile-default.html.twig'),
TemplateDefinitionDto::Create('tile_badge', static::TEMPLATES_BASE_PATH. 'manage/tile-badge.html.twig'),
TemplateDefinitionDto::Create('tile_chart', static::TEMPLATES_BASE_PATH . 'manage/tile-chart.html.twig'),
TemplateDefinitionDto::Create('tile_top_list', static::TEMPLATES_BASE_PATH . 'manage/tile-top-list.html.twig'),
TemplateDefinitionDto::Create('page', static::TEMPLATES_BASE_PATH . 'manage/layout.html.twig'),
TemplateDefinitionDto::Create('page_table', static::TEMPLATES_BASE_PATH . 'manage/layout-table.html.twig'),
TemplateDefinitionDto::Create('page_chart', static::TEMPLATES_BASE_PATH . 'manage/layout-chart.html.twig'),
TemplateDefinitionDto::Create('mode_chart_bar', static::TEMPLATES_BASE_PATH . 'manage/mode-bar-chart.html.twig', true, self::ENUM_DISPLAY_MODE_BAR),
TemplateDefinitionDto::Create('mode_chart_pie', static::TEMPLATES_BASE_PATH . 'manage/mode-pie-chart.html.twig', true,self::ENUM_DISPLAY_MODE_PIE),
);
}
/**
@@ -219,12 +249,106 @@ class ManageBrick extends PortalBrick
$this->iGroupLimit = static::DEFAULT_GROUP_LIMIT;
$this->bGroupShowOthers = static::DEFAULT_GROUP_SHOW_OTHERS;
$this->iDefaultListLength = static::DEFAULT_LIST_LENGTH;
$this->sPopupExportExcelTemplatePath = static::$DEFAULT_TEMPLATES_PATH['popup-export-excel'];
// This is hardcoded for now, we might allow area grouping on another attribute in the future
$this->AddGrouping('areas', array('attribute' => 'finalclass'));
}
/**
* Returns true if the $sDisplayMode need objects details for rendering.
*
* @deprecated since 3.2.1
*
* @param string $sDisplayMode
*
* @return bool
*/
static public function AreDetailsNeededForDisplayMode($sDisplayMode)
{
$bNeedDetails = false;
foreach (static::$aPresentationData as $aData)
{
if ($aData['layoutDisplayMode'] === $sDisplayMode)
{
$bNeedDetails = $aData['need_details'];
break;
}
}
return $bNeedDetails;
}
/**
* Returns if the $sLayoutMode need objects details for rendering.
*
* @since 3.2.1
*
* @param string $sLayoutMode
*
* @return bool
*/
public function IsDetailsNeeded(string $sLayoutMode): bool
{
return static::$aDefaultLayoutData[$sLayoutMode]['need_details'];
}
/**
* Returns the page template path for the $sDisplayMode
*
* @deprecated since 3.2.1
*
* @param string $sDisplayMode
* @return string
*/
static public function GetPageTemplateFromDisplayMode($sDisplayMode)
{
$sTemplate = static::DEFAULT_PAGE_TEMPLATE_PATH;
foreach (static::$aPresentationData as $aData)
{
if ($aData['layoutDisplayMode'] === $sDisplayMode)
{
$sTemplate = $aData['layoutTemplate'];
break;
}
}
return $sTemplate;
}
/**
* Returns the page template path for the $sDisplayMode
*
* @since 3.2.1
*
* @param string $sDisplayMode
*
* @return string
*/
public function GetPageTemplate(string $sDisplayMode): string
{
return match ($sDisplayMode) {
self::ENUM_DISPLAY_MODE_BAR, self::ENUM_DISPLAY_MODE_PIE => $this->GetTemplatePath('page_chart'),
default => $this->GetTemplatePath('page_table'),
};
}
/**
* Returns the page template path for the $sDisplayMode
* @since 3.2.1
*
* @return string
*/
public function GetTileTemplate(): string
{
return match ($this->GetTileMode()) {
self::ENUM_TILE_MODE_BADGE => $this->GetTemplatePath('tile_badge'),
self::ENUM_TILE_MODE_PIE, self::ENUM_TILE_MODE_BAR => $this->GetTemplatePath('tile_chart'),
self::ENUM_TILE_MODE_TOP => $this->GetTemplatePath('tile_top_list'),
default => $this->GetTemplatePath('tile'),
};
}
/**
* Returns the brick oql
*
@@ -319,10 +443,24 @@ class ManageBrick extends PortalBrick
return $this->sTileMode;
}
/**
* @deprecated since 3.2.1
*/
public function GetDecorationCssClass()
{
return static::GetDefaultPresentationData()[$this->sTileMode]['decorationCssClass'];
return static::$aPresentationData[$this->sTileMode]['decorationCssClass'];
}
/**
* @since 3.2.1
*
* @return mixed|string
*/
public function GetDecoration()
{
return static::$aDefaultTileData[$this->sTileMode]['decorationCssClass'];
}
/**
* Sets the tile mode (display)
*
@@ -337,65 +475,21 @@ class ManageBrick extends PortalBrick
return $this;
}
public static function GetDefaultPresentationData()
{
/** If the table isn't initialized yet, do it now */
if (count(static::$aDefaultPresentationData) === 0) {
static::$aDefaultPresentationData = array(
self::ENUM_TILE_MODE_BADGE => array(
'decorationCssClass' => 'fas fa-id-card fa-2x',
'tileTemplate' => static::$DEFAULT_TEMPLATES_PATH['tile-badge'],
'layoutTemplate' => static::$DEFAULT_TEMPLATES_PATH['layout-table'],
'layoutDisplayMode' => self::ENUM_DISPLAY_MODE_LIST,
'need_details' => true,
),
self::ENUM_TILE_MODE_TOP => array(
'decorationCssClass' => 'fas fa-signal fa-rotate-270 fa-2x',
'tileTemplate' => static::$DEFAULT_TEMPLATES_PATH['tile-top-list'],
'layoutTemplate' => static::$DEFAULT_TEMPLATES_PATH['layout-table'],
'layoutDisplayMode' => self::ENUM_DISPLAY_MODE_LIST,
'need_details' => true,
),
self::ENUM_TILE_MODE_PIE => array(
'decorationCssClass' => 'fas fa-chart-pie fa-2x',
'tileTemplate' => static::$DEFAULT_TEMPLATES_PATH['tile-chart'],
'layoutTemplate' => static::$DEFAULT_TEMPLATES_PATH['layout-chart'],
'layoutDisplayMode' => self::ENUM_DISPLAY_MODE_PIE,
'need_details' => false,
),
self::ENUM_TILE_MODE_BAR => array(
'decorationCssClass' => 'fas fa-chart-bar fa-2x',
'tileTemplate' => static::$DEFAULT_TEMPLATES_PATH['tile-chart'],
'layoutTemplate' => static::$DEFAULT_TEMPLATES_PATH['layout-chart'],
'layoutDisplayMode' => self::ENUM_DISPLAY_MODE_BAR,
'need_details' => false,
),
self::ENUM_TILE_MODE_TEXT => array(
'decorationCssClass' => 'fas fa-pen-square fa-2x',
'tileTemplate' => static::$DEFAULT_TEMPLATES_PATH['tile-default'],
'layoutTemplate' => static::$DEFAULT_TEMPLATES_PATH['layout-table'],
'layoutDisplayMode' => self::ENUM_DISPLAY_MODE_LIST,
'need_details' => true,
),
);
}
return static::$aDefaultPresentationData;
}
/**
* @deprecated since 3.2.1
*
* @param string $sTileMode
*
* @return string[] parameters for specified type, default parameters if type is invalid
*/
public function GetPresentationDataForTileMode($sTileMode)
{
if (isset(static::GetDefaultPresentationData()[$sTileMode]))
if (isset(static::$aPresentationData[$sTileMode]))
{
return static::GetDefaultPresentationData()[$sTileMode];
return static::$aPresentationData[$sTileMode];
}
return static::GetDefaultPresentationData()[static::DEFAULT_TILE_MODE];
return static::$aPresentationData[static::DEFAULT_TILE_MODE];
}
/**
@@ -505,16 +599,7 @@ class ManageBrick extends PortalBrick
$this->iDefaultListLength = $iDefaultListLength;
return $this;
}
public function GetPopupExportExcelTemplatePath() {
return $this->sPopupExportExcelTemplatePath;
}
public function SetPopupExportExcelTemplatePath($sPopupExportExcelTemplatePath) {
$this->sPopupExportExcelTemplatePath = $sPopupExportExcelTemplatePath;
return $this;
}
/**
* Adds a grouping.
*
@@ -829,10 +914,11 @@ class ManageBrick extends PortalBrick
case 'tile';
$this->SetTileMode($oDisplayNode->GetText(static::DEFAULT_TILE_MODE));
$aTileParametersForType = $this->GetPresentationDataForTileMode($this->sTileMode);
$this->SetTileTemplatePath($aTileParametersForType['tileTemplate']);
$this->SetPageTemplatePath($aTileParametersForType['layoutTemplate']);
if($this->sDecorationClassHome === static::DEFAULT_DECORATION_CLASS_HOME){
$this->sDecorationClassHome = static::$aDefaultTileData[$this->GetTileMode()]['decorationCssClass'];
$this->SetDecorationClassNavigationMenu(static::$aDefaultTileData[$this->GetTileMode()]['decorationCssClass']);
$this->SetDecorationClassHome(static::$aDefaultTileData[$this->GetTileMode()]['decorationCssClass']);
}
break;
}
}
@@ -966,6 +1052,19 @@ class ManageBrick extends PortalBrick
}
}
break;
case 'templates':
$aTemplatesIds = static::GetTemplatesProviderService()->GetRegister()->GetProviderTemplatesIds(self::class);
/** @var TemplateDefinitionDto $oTemplateDefinition */
foreach ($aTemplatesIds as $sTemplateId) {
$oTemplateNodeList = $oBrickSubNode->GetNodes('template[@id='.ModuleDesign::XPathQuote($sTemplateId).']');
if ($oTemplateNodeList->length > 0) {
/** @var \Combodo\iTop\DesignElement $oTemplateNode */
$oTemplateNode = $oTemplateNodeList->item(0);
$this->SetTemplatePath($sTemplateId, $oTemplateNode->GetText(static::DEFAULT_TILE_TEMPLATE_PATH));
}
}
break;
}
}
@@ -1013,10 +1112,10 @@ class ManageBrick extends PortalBrick
// Checking the navigation icon
$sDecorationClassNavigationMenu = $this->GetDecorationClassNavigationMenu();
if (empty($sDecorationClassNavigationMenu) && isset(static::GetDefaultPresentationData()[$this->sTileMode]))
if (empty($sDecorationClassNavigationMenu) && isset(static::$aDefaultTileData[$this->sTileMode]))
{
/** @var string $sDecorationClassNavigationMenu */
$sDecorationClassNavigationMenu = static::GetDefaultPresentationData()[$this->sTileMode]['decorationCssClass'];
$sDecorationClassNavigationMenu = static::$aDefaultTileData[$this->sTileMode]['decorationCssClass'];
if (!empty($sDecorationClassNavigationMenu))
{
$this->SetDecorationClassNavigationMenu($sDecorationClassNavigationMenu);

View File

@@ -1,62 +0,0 @@
<?php
namespace Combodo\iTop\Portal\Brick;
/**
* Description of ObjectBrick
*
* @package Combodo\iTop\Portal\Brick
* @since 3.2.1
* @author Stephen Abello <stephen.abello@combodo.com>
*/
abstract class ObjectBrick extends AbstractBrick
{
/** @var string DEFAULT_PAGE_TEMPLATE_PATH */
const DEFAULT_PAGE_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/object/layout.html.twig';
/** @var string DEFAULT_MODAL_TEMPLATE_PATH */
const DEFAULT_MODAL_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/object/modal.html.twig';
/** @var string DEFAULT_MODE_LOADER_TEMPLATE_PATH */
const DEFAULT_MODE_LOADER_TEMPLATE_PATH = 'itop-portal-base/portal/templates/modal/mode_loader.html.twig';
protected static $DEFAULT_TEMPLATES_PATH = [
'page' => self::DEFAULT_PAGE_TEMPLATE_PATH,
'modal' => self::DEFAULT_MODAL_TEMPLATE_PATH,
'mode_loader' => self::DEFAULT_MODE_LOADER_TEMPLATE_PATH,
];
/**
* @param $aCombodoPortalInstanceConf
*
* @return void
*/
public static function InitializeSelf($aCombodoPortalInstanceConf): void
{
if(array_key_exists('properties', $aCombodoPortalInstanceConf))
{
static::LoadClassDefinitionFromPortalProperties($aCombodoPortalInstanceConf['properties']);
}
}
/**
* @return string
*/
public static function GetPageDefaultTemplatePath(): string
{
return static::$DEFAULT_TEMPLATES_PATH['page'];
}
/**
* @return string
*/
public static function GetModalDefaultTemplatePath(): string
{
return static::$DEFAULT_TEMPLATES_PATH['modal'];
}
/**
* @return string
*/
public static function GetModeLoaderDefaultTemplatePath(): string
{
return static::$DEFAULT_TEMPLATES_PATH['mode_loader'];
}
}

View File

@@ -20,9 +20,11 @@
namespace Combodo\iTop\Portal\Brick;
use Combodo\iTop\DesignElement;
use Combodo\iTop\Portal\Service\TemplatesProvider\TemplateDefinitionDto;
use Combodo\iTop\Portal\Service\TemplatesProvider\TemplatesRegister;
use DOMFormatException;
use ModuleDesign;
use Combodo\iTop\DesignElement;
/**
* Description of PortalBrick
@@ -63,11 +65,6 @@ abstract class PortalBrick extends AbstractBrick
/** @var string DEFAULT_OPENING_TARGET */
const DEFAULT_OPENING_TARGET = self::ENUM_OPENING_TARGET_MODAL;
protected static $DEFAULT_TEMPLATES_PATH = [
'page' => self::DEFAULT_PAGE_TEMPLATE_PATH,
'tile' => self::DEFAULT_TILE_TEMPLATE_PATH,
];
/** @var string|null $sRouteName */
static $sRouteName = null;
/** @var array $aOpeningTargets */
@@ -75,6 +72,8 @@ abstract class PortalBrick extends AbstractBrick
/** @var int $iWidth */
protected $iWidth;
/** @var bool width in pixel flag */
public bool $bIsWidthPixel = false;
/** @var int $iHeight */
protected $iHeight;
/** @var bool $bModal */
@@ -87,7 +86,7 @@ abstract class PortalBrick extends AbstractBrick
protected $sDecorationClassHome;
/** @var string $sDecorationClassNavigationMenu */
protected $sDecorationClassNavigationMenu;
/** @var string $sTileTemplatePath */
/** @var string $sTileTemplatePath @deprecated since 3.2.1 */
protected $sTileTemplatePath;
/** @var string|null $sTileControllerAction */
protected $sTileControllerAction;
@@ -104,6 +103,17 @@ abstract class PortalBrick extends AbstractBrick
/** @var string $sTitleNavigationMenu */
protected $sTitleNavigationMenu;
/** @inheritdoc */
public static function RegisterTemplates(TemplatesRegister $oTemplatesRegister): void
{
parent::RegisterTemplates($oTemplatesRegister);
$oTemplatesRegister->RegisterTemplates(self::class,
TemplateDefinitionDto::Create('tile', static::TEMPLATES_BASE_PATH . 'tile.html.twig'),
);
}
/**
* @return string|null
*/
@@ -126,7 +136,9 @@ abstract class PortalBrick extends AbstractBrick
$this->bVisibleNavigationMenu = static::DEFAULT_VISIBLE_NAVIGATION_MENU;
$this->sDecorationClassHome = static::DEFAULT_DECORATION_CLASS_HOME;
$this->sDecorationClassNavigationMenu = static::DEFAULT_DECORATION_CLASS_NAVIGATION_MENU;
$this->sTileTemplatePath = static::$DEFAULT_TEMPLATES_PATH['tile'];
// BEGIN cleaning 3.2.1 deprecated
$this->sTileTemplatePath = static::DEFAULT_TILE_TEMPLATE_PATH;
// END cleaning 3.2.1 deprecated
$this->sTileControllerAction = static::DEFAULT_TILE_CONTROLLER_ACTION;
$this->sOpeningTarget = static::DEFAULT_OPENING_TARGET;
}
@@ -255,10 +267,12 @@ abstract class PortalBrick extends AbstractBrick
* Returns the brick tile template path
*
* @return string
*
* @deprecated since 3.2.1 use GetTemplatePath('tile') instead
*/
public function GetTileTemplatePath()
{
return $this->sTileTemplatePath;
return $this->GetTemplatePath('tile');
}
/**
@@ -431,10 +445,13 @@ abstract class PortalBrick extends AbstractBrick
* @param string $sTileTemplatePath
*
* @return \Combodo\iTop\Portal\Brick\PortalBrick
*
* @deprecated since 3.2.1 use SetTemplatePath('tile') instead
*/
public function SetTileTemplatePath($sTileTemplatePath)
{
$this->sTileTemplatePath = $sTileTemplatePath;
$this->SetTemplatePath('tile', $sTileTemplatePath);
return $this;
}
@@ -488,7 +505,9 @@ abstract class PortalBrick extends AbstractBrick
switch ($oBrickSubNode->nodeName)
{
case 'width':
$this->SetWidth((int)$oBrickSubNode->GetText(static::DEFAULT_WIDTH));
$sWidth = $oBrickSubNode->GetText(static::DEFAULT_WIDTH);
$this->bIsWidthPixel = str_contains($sWidth, 'px');
$this->SetWidth((int)$sWidth);
break;
case 'height':
@@ -531,7 +550,7 @@ abstract class PortalBrick extends AbstractBrick
{
/** @var \Combodo\iTop\DesignElement $oTemplateNode */
$oTemplateNode = $oTemplateNodeList->item(0);
$this->SetTileTemplatePath($oTemplateNode->GetText(static::DEFAULT_TILE_TEMPLATE_PATH));
$this->SetTemplatePath('tile', $oTemplateNode->GetText(static::DEFAULT_TILE_TEMPLATE_PATH));
}
break;

View File

@@ -20,6 +20,8 @@
namespace Combodo\iTop\Portal\Brick;
use Combodo\iTop\DesignElement;
use Combodo\iTop\Portal\Service\TemplatesProvider\TemplateDefinitionDto;
use Combodo\iTop\Portal\Service\TemplatesProvider\TemplatesRegister;
use DOMFormatException;
/**
@@ -32,17 +34,10 @@ use DOMFormatException;
class UserProfileBrick extends PortalBrick
{
// Overloaded constants
const DEFAULT_PAGE_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/user-profile/layout.html.twig';
const DEFAULT_TILE_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/user-profile/tile.html.twig';
const DEFAULT_VISIBLE_NAVIGATION_MENU = false;
const DEFAULT_VISIBLE_HOME = false;
const DEFAUT_TITLE = 'Brick:Portal:UserProfile:Title';
const DEFAULT_DECORATION_CLASS_HOME = 'glyphicon glyphicon-user';
const DEFAULT_DECORATION_CLASS_NAVIGATION_MENU = 'glyphicon glyphicon-user';
protected static $DEFAULT_TEMPLATES_PATH = [
'page' => self::DEFAULT_PAGE_TEMPLATE_PATH,
'tile' => self::DEFAULT_TILE_TEMPLATE_PATH,
];
/** @var bool DEFAULT_SHOW_PICTURE_FORM */
const DEFAULT_SHOW_PICTURE_FORM = true;
/** @var bool DEFAULT_SHOW_PREFERENCES_FORM */
@@ -62,6 +57,15 @@ class UserProfileBrick extends PortalBrick
/** @var bool $bShowPasswordForm */
protected $bShowPasswordForm;
/** @inheritdoc */
public static function RegisterTemplates(TemplatesRegister $oTemplatesRegister): void
{
parent::RegisterTemplates($oTemplatesRegister);
$oTemplatesRegister->RegisterTemplates(self::class,
TemplateDefinitionDto::Create('page', static::TEMPLATES_BASE_PATH . 'user-profile/layout.html.twig'),
);
}
/**
* UserProfileBrick constructor.
*/

View File

@@ -20,7 +20,11 @@
namespace Combodo\iTop\Portal\Controller;
use \Symfony\Bundle\FrameworkBundle\Controller\AbstractController as SymfonyAbstractController;
use Combodo\iTop\Portal\Service\TemplatesProvider\TemplatesProviderInterface;
use Combodo\iTop\Portal\Service\TemplatesProvider\TemplateDefinitionDto;
use Combodo\iTop\Portal\Service\TemplatesProvider\TemplatesProviderService;
use Combodo\iTop\Portal\Service\TemplatesProvider\TemplatesRegister;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController as SymfonyAbstractController;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Contracts\Service\Attribute\Required;
@@ -31,8 +35,19 @@ use Symfony\Contracts\Service\Attribute\Required;
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
* @since 2.3.0
*/
abstract class AbstractController extends SymfonyAbstractController
abstract class AbstractController extends SymfonyAbstractController implements TemplatesProviderInterface
{
const TEMPLATES_BASE_PATH = 'itop-portal-base/portal/templates/';
/** @inheritdoc */
public static function RegisterTemplates(TemplatesRegister $oTemplatesRegister): void
{
$oTemplatesRegister->RegisterTemplates(self::class,
TemplateDefinitionDto::Create('page', static::TEMPLATES_BASE_PATH . 'layout.html.twig'),
TemplateDefinitionDto::Create('modal', static::TEMPLATES_BASE_PATH . 'modal/layout.html.twig'),
);
}
/**
* @var \Symfony\Component\Routing\RouterInterface symfony router
*
@@ -46,6 +61,25 @@ abstract class AbstractController extends SymfonyAbstractController
$this->oRouter = $oRouter;
}
/** @var TemplatesProviderService templates provider service */
private TemplatesProviderService $oTemplatesService;
#[Required]
public function SetTemplatesService(TemplatesProviderService $oTemplatesService): void
{
$this->oTemplatesService = $oTemplatesService;
}
/**
* Return the templates provider service.
*
* @return \Combodo\iTop\Portal\Service\TemplatesProvider\TemplatesProviderService
*/
protected function GetTemplatesProviderService(): TemplatesProviderService
{
return $this->oTemplatesService;
}
/**
* Unlike {@see \Symfony\Bundle\FrameworkBundle\Controller\ControllerTrait::redirectToRoute()}, this method directly calls the route controller without creating a redirection client side
*
@@ -104,4 +138,33 @@ abstract class AbstractController extends SymfonyAbstractController
return $aRouteDefaults['_controller'];
}
/**
* Returns the controller template path
*
* @since 3.2.1
*
* @param string $sTemplateId
*
* @return string
*/
public function GetTemplatePath(string $sTemplateId): string
{
return static::GetTemplatesProviderService()->GetProviderInstanceTemplatePath($this, $sTemplateId);
}
/**
* Sets the brick template path
*
* @since 3.2.1
* @param string $sTemplateId
* @param string $sTileTemplatePath
*
* @return \Combodo\iTop\Portal\Controller\AbstractController
*/
public function SetTemplatePath(string $sTemplateId, string $sTileTemplatePath): AbstractController
{
static::GetTemplatesProviderService()->OverrideInstanceTemplatePath($this, $sTemplateId, $sTileTemplatePath);
return $this;
}
}

View File

@@ -75,7 +75,7 @@ class AggregatePageBrickController extends BrickController
$aTilesRendering = $this->GetBricksTileRendering($oRequest, $aAggregatePageBricks);
$sLayoutTemplate = $oBrick->GetPageTemplatePath();
$sLayoutTemplate = $oBrick->GetTemplatePath('page');
$aData = array(
'oBrick' => $oBrick,
'aggregatepage_bricks' => $aAggregatePageBricks,

View File

@@ -495,13 +495,13 @@ class BrowseBrickController extends BrickController
// - Create a template for that browse mode,
// - Add the mode to those available in the brick configuration,
// - Create a router and add a route for the new browse mode
if ($oBrick->GetPageTemplatePath() !== null)
if ($oBrick->HasInstanceOverriddenTemplate('page'))
{
$sTemplatePath = $oBrick->GetPageTemplatePath();
$sTemplatePath = $oBrick->GetTemplatePath('page');
}
else
{
$sTemplatePath = $aBrowseModes[$sBrowseMode]['template'];
$sTemplatePath = $oBrick->GetTemplatePath('page_' .$sBrowseMode);
}
$oResponse = $this->render($sTemplatePath, $aData);
}

View File

@@ -23,7 +23,6 @@ namespace Combodo\iTop\Portal\Controller;
use Combodo\iTop\Portal\Brick\BrickCollection;
use Combodo\iTop\Portal\Helper\ContextManipulatorHelper;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
/**
* Class CreateBrickController

View File

@@ -21,6 +21,8 @@
namespace Combodo\iTop\Portal\Controller;
use Combodo\iTop\Portal\Brick\BrickCollection;
use Combodo\iTop\Portal\Service\TemplatesProvider\TemplateDefinitionDto;
use Combodo\iTop\Portal\Service\TemplatesProvider\TemplatesRegister;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
@@ -33,6 +35,15 @@ use Symfony\Component\HttpFoundation\Response;
*/
class DefaultController extends AbstractController
{
/** @inheritdoc */
public static function RegisterTemplates(TemplatesRegister $oTemplatesRegister): void
{
parent::RegisterTemplates($oTemplatesRegister);
$oTemplatesRegister->RegisterTemplates(self::class,
TemplateDefinitionDto::Create('home', static::TEMPLATES_BASE_PATH . 'home/layout.html.twig'),
);
}
/**
* @param \Symfony\Component\HttpFoundation\Request $oRequest
* @param \Combodo\iTop\Portal\Brick\BrickCollection $oBricksCollection
@@ -72,7 +83,7 @@ class DefaultController extends AbstractController
}
// Home page template
$sTemplatePath = $this->getParameter('combodo.portal.instance.conf')['properties']['templates']['home'];
$sTemplatePath = $this->GetTemplatePath('home');
return $this->render($sTemplatePath, $aData);
}

View File

@@ -40,6 +40,8 @@ use Combodo\iTop\Portal\Helper\RequestManipulatorHelper;
use Combodo\iTop\Portal\Helper\ScopeValidatorHelper;
use Combodo\iTop\Portal\Helper\SecurityHelper;
use Combodo\iTop\Portal\Routing\UrlGenerator;
use Combodo\iTop\Portal\Service\TemplatesProvider\TemplateDefinitionDto;
use Combodo\iTop\Portal\Service\TemplatesProvider\TemplatesRegister;
use DBObject;
use DBObjectSet;
use DBSearch;
@@ -70,10 +72,20 @@ use utils;
*/
class ManageBrickController extends BrickController
{
/** @var string EXCEL_EXPORT_TEMPLATE_PATH
/**
* @var string EXCEL_EXPORT_TEMPLATE_PATH
* @deprecated since 3.2.1
*/
const EXCEL_EXPORT_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/manage/popup-export-excel.html.twig';
/** @inheritdoc */
public static function RegisterTemplates(TemplatesRegister $oTemplatesRegister): void
{
parent::RegisterTemplates($oTemplatesRegister);
$oTemplatesRegister->RegisterTemplates(self::class,
TemplateDefinitionDto::Create('modal_export_excel', static::TEMPLATES_BASE_PATH . 'bricks/manage/popup-export-excel.html.twig'),
);
}
/**
* @param \Combodo\iTop\Portal\Brick\BrickCollection $oBrickCollection
@@ -123,7 +135,7 @@ class ManageBrickController extends BrickController
$sDisplayMode = $oBrick->GetDefaultDisplayMode();
}
$aData = $this->GetData($oRequest, $sBrickId, $sGroupingTab, $oBrick::AreDetailsNeededForDisplayMode($sDisplayMode));
$aData = $this->GetData($oRequest, $sBrickId, $sGroupingTab, $oBrick->IsDetailsNeeded($sDisplayMode));
$aExportFields = $oBrick->GetExportFields();
$aData = $aData + array(
@@ -137,7 +149,7 @@ class ManageBrickController extends BrickController
}
else
{
$sLayoutTemplate = $oBrick::GetPageTemplateFromDisplayMode($sDisplayMode);
$sLayoutTemplate = $oBrick->GetPageTemplate($sDisplayMode);
$oResponse = $this->render($sLayoutTemplate, $aData);
}
@@ -169,7 +181,7 @@ class ManageBrickController extends BrickController
$aData = array();
}
return $this->render($oBrick->GetTileTemplatePath(), $aData);
return $this->render($oBrick->GetTileTemplate(), $aData);
}
/**
@@ -283,7 +295,7 @@ class ManageBrickController extends BrickController
'sWikiUrl' => 'https://www.itophub.io/wiki/page?id='.utils::GetItopVersionWikiSyntax().'%3Auser%3Alists#excel_export',
);
return $this->render($oBrick->GetPopupExportExcelTemplatePath(), $aData);
return $this->render($this->GetTemplatePath('modal_export_excel'), $aData);
}
/**

View File

@@ -29,7 +29,6 @@ use BinaryExpression;
use Combodo\iTop\Form\Field\DateTimeField;
use Combodo\iTop\Portal\Brick\BrickCollection;
use Combodo\iTop\Portal\Brick\CreateBrick;
use Combodo\iTop\Portal\Brick\ObjectBrick;
use Combodo\iTop\Portal\Helper\ApplicationHelper;
use Combodo\iTop\Portal\Helper\ContextManipulatorHelper;
use Combodo\iTop\Portal\Helper\NavigationRuleHelper;
@@ -38,6 +37,8 @@ use Combodo\iTop\Portal\Helper\RequestManipulatorHelper;
use Combodo\iTop\Portal\Helper\ScopeValidatorHelper;
use Combodo\iTop\Portal\Helper\SecurityHelper;
use Combodo\iTop\Portal\Routing\UrlGenerator;
use Combodo\iTop\Portal\Service\TemplatesProvider\TemplateDefinitionDto;
use Combodo\iTop\Portal\Service\TemplatesProvider\TemplatesRegister;
use Combodo\iTop\Renderer\Bootstrap\FieldRenderer\BsLinkedSetFieldRenderer;
use DBObject;
use DBObjectSearch;
@@ -75,6 +76,18 @@ class ObjectController extends BrickController
const DEFAULT_PAGE_NUMBER = 1;
const DEFAULT_LIST_LENGTH = 10;
/** @inheritdoc */
public static function RegisterTemplates(TemplatesRegister $oTemplatesRegister): void
{
parent::RegisterTemplates($oTemplatesRegister);
$oTemplatesRegister->RegisterTemplates(self::class,
TemplateDefinitionDto::Create('page', static::TEMPLATES_BASE_PATH. 'bricks/object/layout.html.twig'),
TemplateDefinitionDto::Create('modal', static::TEMPLATES_BASE_PATH. 'bricks/object/modal.html.twig'),
TemplateDefinitionDto::Create('mode_create', static::TEMPLATES_BASE_PATH.'bricks/object/mode_create.html.twig', true, 'create'),
TemplateDefinitionDto::Create('mode_loader', static::TEMPLATES_BASE_PATH.'modal/mode_loader.html.twig', true, 'loader'),
);
}
/**
* @param \Combodo\iTop\Portal\Helper\SecurityHelper $oSecurityHelper
* @param \Combodo\iTop\Portal\Helper\ScopeValidatorHelper $oScopeValidatorHelper
@@ -101,7 +114,7 @@ class ObjectController extends BrickController
protected array $aCombodoPortalInstanceConf = []
)
{
ObjectBrick::InitializeSelf($this->aCombodoPortalInstanceConf);
}
/**
@@ -237,7 +250,7 @@ class ObjectController extends BrickController
if ($oRequest->isXmlHttpRequest()) {
// We have to check whether the 'operation' parameter is defined or not in order to know if the form is required via ajax (to be displayed as a modal dialog) or if it's a lifecycle call from a existing form.
if (empty($sOperation)) {
$oResponse = $this->render(ObjectBrick::GetModalDefaultTemplatePath(), $aData);
$oResponse = $this->render($this->GetTemplatePath('modal'), $aData);
} else {
$oResponse = new JsonResponse($aData);
}
@@ -251,7 +264,7 @@ class ObjectController extends BrickController
}
}
$aData['sPageTitle'] = $aData['form']['title'];
$oResponse = $this->render(ObjectBrick::GetPageDefaultTemplatePath(), $aData);
$oResponse = $this->render($this->GetTemplatePath('page'), $aData);
}
return $oResponse;
@@ -312,7 +325,7 @@ class ObjectController extends BrickController
// We have to check whether the 'operation' parameter is defined or not in order to know if the form is required via ajax (to be displayed as a modal dialog) or if it's a lifecycle call from a existing form.
if (empty($sOperation))
{
$oResponse = $this->render(ObjectBrick::GetModalDefaultTemplatePath(), $aData);
$oResponse = $this->render($this->GetTemplatePath('modal'), $aData);
}
else
{
@@ -332,7 +345,7 @@ class ObjectController extends BrickController
}
}
$aData['sPageTitle'] = $aData['form']['title'];
$oResponse = $this->render(ObjectBrick::GetPageDefaultTemplatePath(), $aData);
$oResponse = $this->render($this->GetTemplatePath('page'), $aData);
}
return $oResponse;
@@ -539,11 +552,11 @@ class ObjectController extends BrickController
// We have to check whether the 'operation' parameter is defined or not in order to know if the form is required via ajax (to be displayed as a modal dialog) or if it's a lifecycle call from a existing form.
if (empty($sOperation))
{
$oResponse = $this->render(ObjectBrick::GetModalDefaultTemplatePath(), $aData);
$oResponse = $this->render($this->GetTemplatePath('modal'), $aData);
}
elseif ($sOperation === 'redirect')
{
$oResponse = $this->render(ObjectBrick::GetModeLoaderDefaultTemplatePath(), $aData);
$oResponse = $this->render($this->GetTemplatePath('mode_loader'), $aData);
}
else
{
@@ -552,7 +565,7 @@ class ObjectController extends BrickController
}
else
{
$oResponse = $this->render(ObjectBrick::GetPageDefaultTemplatePath(), $aData);
$oResponse = $this->render($this->GetTemplatePath('page'), $aData);
}
return $oResponse;
@@ -1016,12 +1029,12 @@ class ObjectController extends BrickController
if ($oRequest->isXmlHttpRequest())
{
$oResponse = $this->render(ObjectBrick::GetModalDefaultTemplatePath(), $aData);
$oResponse = $this->render($this->GetTemplatePath('modal'), $aData);
}
else
{
//throw new HttpException(Response::HTTP_NOT_FOUND, Dict::S('UI:ObjectDoesNotExist'));
$oResponse = $this->render(ObjectBrick::GetPageDefaultTemplatePath(), $aData);
$oResponse = $this->render($this->GetTemplatePath('page'), $aData);
}
}
else
@@ -1602,7 +1615,7 @@ class ObjectController extends BrickController
// We have to check whether the 'operation' parameter is defined or not in order to know if the form is required via ajax (to be displayed as a modal dialog) or if it's a lifecycle call from a existing form.
if (empty($sOperation))
{
$oResponse = $this->render(ObjectBrick::GetModalDefaultTemplatePath(), $aData);
$oResponse = $this->render($this->GetTemplatePath('modal'), $aData);
}
else
{
@@ -1622,7 +1635,7 @@ class ObjectController extends BrickController
}
}
$aData['sPageTitle'] = $aData['form']['title'];
$oResponse = $this->render(ObjectBrick::GetPageDefaultTemplatePath(), $aData);
$oResponse = $this->render($this->GetTemplatePath('page'), $aData);
}
return $oResponse;
@@ -1656,7 +1669,7 @@ class ObjectController extends BrickController
if (!empty($sBrickId))
{
$oBrick = $this->oBrickCollection->GetBrickById($sBrickId);
$sTemplatePath = $oBrick->GetPageTemplatePath();
$sTemplatePath = $oBrick->GetTemplatePath('page');
$aData['sBrickId'] = $sBrickId;
$aData['oBrick'] = $oBrick;

View File

@@ -166,7 +166,7 @@ class UserProfileBrickController extends BrickController
$this->ManageUserProfileBrickExtensibility($sTab, $aData);
$oResponse = $this->render($oBrick->GetPageTemplatePath(), $aData);
$oResponse = $this->render($oBrick->GetTemplatePath('page'), $aData);
}
return $oResponse;

View File

@@ -0,0 +1,127 @@
<?php
namespace Combodo\iTop\Portal\DataCollector;
use Combodo\iTop\Portal\Service\TemplatesProvider\TemplatesProviderService;
use Symfony\Bundle\FrameworkBundle\DataCollector\AbstractDataCollector;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Throwable;
/**
* Template information collector for Symfony profiler.
*
* @package Combodo\iTop\Portal\DataCollector
* @since 3.2.1
*/
class PortalCollector extends AbstractDataCollector
{
/**
* Constructor.
*
*
* @param \Combodo\iTop\Portal\Service\TemplatesProvider\TemplatesProviderService $oTemplatesProviderService
*/
public function __construct(private readonly TemplatesProviderService $oTemplatesProviderService)
{
}
/** @inheritdoc */
public function collect(Request $request, Response $response, Throwable $exception = null): void
{
$oRegister = $this->oTemplatesProviderService->GetRegister();
$aTemplatesDefinitions = $oRegister->GetTemplatesDefinitions();
$this->data = [
'templates_definitions' => $aTemplatesDefinitions,
'instances_overridden_templates' => $this->oTemplatesProviderService->GetInstancesOverriddenTemplatesPaths(),
'templates_count' => $this->ComputeOverridesCount($aTemplatesDefinitions),
'ui_version' => $oRegister->GetUIVersion(),
];
}
/**
* @return string|null
*/
public static function getTemplate(): ?string
{
return 'itop-portal-base/portal/templates/data_collector/portal.html.twig';
}
/**
* @return array
* @noinspection PhpUnused
*/
public function GetTemplatesDefinitions(): array
{
return $this->data['templates_definitions'];
}
/**
* @return array
* @noinspection PhpUnused
*/
public function GetInstancesOverriddenTemplates(): array
{
return $this->data['instances_overridden_templates'];
}
/**
* @return array
* @noinspection PhpUnused
*/
public function GetTemplatesCount(): array
{
return $this->data['templates_count'];
}
/**
* @return string
* @noinspection PhpUnused
*/
public function GetUIVersion(): string
{
return $this->data['ui_version'];
}
private function ComputeOverridesCount($aTemplatesDefinitions): array
{
$iCount = 0;
$iOverridesCount = 0;
$aExtensions = [];
foreach($aTemplatesDefinitions as $templates){
foreach ($templates as $template) {
$aMatches = [];
preg_match('#([\w-]+)/#', $template->GetPath(), $aMatches);
if(!in_array($aMatches[1], $aExtensions)){
$aExtensions[] = $aMatches[1];
}
$iCount++;
if ($template->IsOverridden()) {
$iOverridesCount++;
}
}
}
return [
'count' => $iCount,
'providers_count' => count($aTemplatesDefinitions),
'overrides_count' => $iOverridesCount,
'extensions_count' => count($aExtensions),
'bricks_count' => count($this->oTemplatesProviderService->GetInstancesOverriddenTemplatesPaths()),
];
}
/**
* @return string
* @noinspection PhpUnused
*/
public function GetInstanceDescriptionName(): string
{
return 'portal';
}
}

View File

@@ -21,9 +21,10 @@ namespace Combodo\iTop\Portal\DependencyInjection\SilexCompatBootstrap\PortalXml
use Combodo\iTop\Application\Branding;
use Combodo\iTop\DesignElement;
use Combodo\iTop\Portal\Helper\UIExtensionsHelper;
use Combodo\iTop\Portal\Service\TemplatesProvider\TemplatesProviderInterface;
use DOMFormatException;
use Exception;
use ReflectionClass;
use Symfony\Component\DependencyInjection\Container;
use utils;
@@ -74,6 +75,7 @@ class Basic extends AbstractConfiguration
$aPortalConf = array(
'properties' => array(
'id' => $_ENV['PORTAL_ID'],
'ui_version' => '2017',
'name' => 'Page:DefaultTitle',
'logo' => Branding::GetPortalLogoAbsoluteUrl(),
'favicon' => Branding::GetPortalFavIconAbsoluteUrl(),
@@ -85,7 +87,6 @@ class Basic extends AbstractConfiguration
'templates' => array(
'layout' => 'itop-portal-base/portal/templates/layout.html.twig',
'home' => 'itop-portal-base/portal/templates/home/layout.html.twig',
'bricks' => array(),
),
'urlmaker_class' => null,
'triggers_query' => null,
@@ -117,6 +118,7 @@ class Basic extends AbstractConfiguration
{
switch ($oPropertyNode->nodeName)
{
case 'ui_version':
case 'name':
case 'urlmaker_class':
case 'triggers_query':
@@ -186,19 +188,22 @@ class Basic extends AbstractConfiguration
$aPortalConf['properties']['templates'][$sNodeId] = $oSubNode->GetText(null);
break;
default:
// Try to accept the value as a global brick template, brick id format is "FQCN:page"
[$sBrickFQCN, $sPage] = explode(':', $sNodeId);
if (utils::IsNotNullOrEmptyString($sBrickFQCN) && utils::IsNotNullOrEmptyString($sPage))
{
$aPortalConf['properties']['templates']['bricks'][$sBrickFQCN][$sPage] = $oSubNode->GetText(null);
break;
$aMatches = [];
// allowed format is: <class implementing TemplatesProviderInterface>:<template_id>
if(preg_match('#([\w\\\d_]+):(\w+)#', $sNodeId, $aMatches)){
try{
$oClass = new ReflectionClass($aMatches[1]);
if($oClass->implementsInterface(TemplatesProviderInterface::class)){
$aPortalConf['properties']['templates'][$aMatches[1]][$aMatches[2]] = $oSubNode->GetText(null);
break;
}
}
catch(Exception){}
}
throw new DOMFormatException(
'Value "'.$sNodeId.'" is not handled for template[@id]',
'Template ID "'.$sNodeId.'" is not handled in module design templates property',
null, null, $oSubNode
);
break;
}
break;
}

View File

@@ -0,0 +1,145 @@
<?php
/**
* Copyright (C) 2013-2024 Combodo SAS
*
* This file is part of iTop.
*
* iTop is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* iTop is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
*/
namespace Combodo\iTop\Portal\Service\TemplatesProvider;
/**
* Template definition DTO.
*
* Describes a template.
*
* @package Combodo\iTop\Portal\Service\TemplatesProvider
* @since 3.2.1
*/
class TemplateDefinitionDto
{
/**
* Create a new template definition instance.
*
* @param string $sTemplateId template identifier
* @param string $sPath template path
* @param bool $isOverridable flag set when the template is overridable
* @param string|null $sAlias template alias
*
* @return \Combodo\iTop\Portal\Service\TemplatesProvider\TemplateDefinitionDto
*/
public static function Create(string $sTemplateId, string $sPath, bool $isOverridable = true, ?string $sAlias = null): TemplateDefinitionDto
{
return new TemplateDefinitionDto($sTemplateId, $sPath, $isOverridable, $sAlias);
}
/** @var bool $bIsOverridden flag set when overriding a template */
private bool $bIsOverridden = false;
/** @var string|null $sInitialValue Initial template value */
private ?string $sInitialValue;
/**
* Constructor.
*
* @param string $sId template identifier
* @param string|null $sPath template path
* @param bool|null $bIsOverridable flag set when the template is overridable
* @param string|null $sAlias template alias
*/
private function __construct(
private readonly string $sId,
private ?string $sPath = null,
private readonly ?bool $bIsOverridable = false,
private readonly ?string $sAlias = null,
)
{
// save overridable values
$this->sInitialValue = $sPath;
}
/**
* Return the template identifier.
*
* @return string
*/
public function GetId(): string
{
return $this->sId !== null ? $this->sId : '';
}
/**
* Return the template path.
*
* @param bool $bInitialValue Return the initial value instead of the overridden one.
*
* @return string
*/
public function GetPath(bool $bInitialValue = false): string
{
if($bInitialValue){
return $this->sInitialValue !== null ? $this->sInitialValue : '';
}
return $this->sPath !== null ? $this->sPath : '';
}
/**
* Return the overridable state.
*
* @return bool
*/
public function IsOverridable(): bool
{
return $this->bIsOverridable !== null ? $this->bIsOverridable : false;
}
/**
* Return the template alias.
*
* @return string
*/
public function GetAlias(): string
{
return $this->sAlias !== null ? $this->sAlias : '';
}
/**
* Override a template.
*
* @param string $sPath template path
*
* @return $this
*/
public function OverrideTemplatePath(string $sPath): TemplateDefinitionDto
{
if ($this->IsOverridable() && $sPath !== $this->sPath) {
$this->sPath = $sPath;
$this->bIsOverridden = true;
}
return $this;
}
/**
* Return the overridden flag.
*
* @noinspection PhpUnused
*/
public function IsOverridden(): bool
{
return $this->bIsOverridden;
}
}

View File

@@ -0,0 +1,39 @@
<?php
/**
* Copyright (C) 2013-2024 Combodo SAS
*
* This file is part of iTop.
*
* iTop is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* iTop is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
*/
namespace Combodo\iTop\Portal\Service\TemplatesProvider;
/**
* Template provider interface.
*
* This interface is used to register templates in the templates provider service.
*
* @package Combodo\iTop\Portal\Service\TemplatesProvider
* @since 3.2.1
*/
interface TemplatesProviderInterface
{
/**
* @param \Combodo\iTop\Portal\Service\TemplatesProvider\TemplatesRegister $oTemplatesRegister
*
* @return void
*/
public static function RegisterTemplates(TemplatesRegister $oTemplatesRegister): void;
}

View File

@@ -0,0 +1,323 @@
<?php
/**
* Copyright (C) 2013-2024 Combodo SAS
*
* This file is part of iTop.
*
* iTop is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* iTop is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
*/
namespace Combodo\iTop\Portal\Service\TemplatesProvider;
use Combodo\iTop\Portal\Brick\AbstractBrick;
use Combodo\iTop\Portal\Controller\AbstractController;
use Combodo\iTop\Portal\Controller\DefaultController;
use Combodo\iTop\Service\InterfaceDiscovery\InterfaceDiscovery;
use Exception;
use ReflectionClass;
use Symfony\Contracts\Cache\CacheInterface;
use Symfony\Contracts\Cache\ItemInterface;
/**
* Service responsible for managing portal templates.
*
* The templates provider interface allows any provider to register templates for the portal.
* The templates registered may be overridden by the portal configuration and for a specific instance (brick instance).
*
* Templates are defined in module_design properties section, under the templates key.
* The layouts for home and default layout still allow to be defined in the portal configuration.
* Otherwise, the templates for providers are defined as follows:
* <template id="{class implementing TemplatesProviderInterface}:{template_id}">{path to template}</template>
*
* Templates are store in register object.
* This register is cached.
*
* @package Combodo\iTop\Portal\Service\TemplatesProvider
* @since 3.2.1
*/
class TemplatesProviderService
{
/** @var \Combodo\iTop\Portal\Service\TemplatesProvider\TemplatesRegister templates register */
protected TemplatesRegister $oTemplateRegister;
/** @var array instances overridden templates paths */
protected array $aInstancesOverriddenTemplatesPaths = [];
/**
* TemplatesService constructor.
*
* @param array $aCombodoPortalInstanceConf configuration for the current portal instance
* @param \Symfony\Contracts\Cache\CacheInterface $templatesCachePool cache pool for templates
*
* @throws \Psr\Cache\InvalidArgumentException
*/
public function __construct(array $aCombodoPortalInstanceConf, CacheInterface $templatesCachePool)
{
// template register cache
$this->oTemplateRegister = $templatesCachePool->get('portal_templates_register', function (ItemInterface $item) use ($aCombodoPortalInstanceConf): TemplatesRegister {
// initialize register
return $this->InitializeTemplatesRegister($aCombodoPortalInstanceConf);
});
// brick should be able to give the templates with GetTileTemplate, GetPageTemplate (so it needs to know the service)
// a more elegant way would be to use a controller to achieve this
AbstractBrick::SetTemplatesProviderService($this);
}
/**
* Initialize templates register.
* Store the UI version defined in portal instance configuration.
* Iterate throw TemplatesProviderInterface implementations to register templates.
* Override templates with portal instance configuration.
*
* @throws \ReflectionException
*/
private function InitializeTemplatesRegister(array $aCombodoPortalInstanceConf): TemplatesRegister
{
// UI version
$sUIVersion = 'unset';
if (isset($aCombodoPortalInstanceConf['properties']['ui_version'])) {
$sUIVersion = $aCombodoPortalInstanceConf['properties']['ui_version'];
}
// create template register
$oTemplateRegister = new TemplatesRegister($sUIVersion);
// search for templates providers
// only non-abstract classes are discovered.
// classes implementing the interface needs to call the parent to ensure abstracted class levels templates are registered.
$oTemplatesProviders = InterfaceDiscovery::GetInstance()->FindItopClasses(TemplatesProviderInterface::class);
// register default templates...
foreach ($oTemplatesProviders as $oTemplateProvider) {
$oTemplateProvider::RegisterTemplates($oTemplateRegister);
}
// overrides the templates declared in portal configuration...
foreach ($aCombodoPortalInstanceConf['properties']['templates'] as $sKey => $oValue) {
switch ($sKey) {
case 'layout': // legacy configuration
$oTemplateDefinition = $oTemplateRegister->GetTemplateDefinition(AbstractController::class, 'page');
$oTemplateDefinition->OverrideTemplatePath($oValue);
break;
case 'home': // legacy configuration
$oTemplateDefinition = $oTemplateRegister->GetTemplateDefinition(DefaultController::class, 'home');
$oTemplateDefinition->OverrideTemplatePath($oValue);
break;
default:
if (is_array($oValue)) {
foreach ($oValue as $sTemplateId => $sTemplatePath) {
$oTemplateDefinition = $oTemplateRegister->GetTemplateDefinition($sKey, $sTemplateId);
$oTemplateDefinition?->OverrideTemplatePath($sTemplatePath);
}
}
break;
}
}
return $oTemplateRegister;
}
/**
* Override an object instance template path.
*
* @param object $oObject object instance
* @param string $sTemplateId the template id
* @param string $sTemplatePath the template path
*
* @return $this
*/
public function OverrideInstanceTemplatePath(object $oObject, string $sTemplateId, string $sTemplatePath): TemplatesProviderService
{
// get object UUID
$sObjectId = spl_object_id($oObject);
// initialize overridden object templates and information
if (array_key_exists($sObjectId, $this->aInstancesOverriddenTemplatesPaths) === false) {
$this->aInstancesOverriddenTemplatesPaths[$sObjectId] = [];
$this->aInstancesOverriddenTemplatesPaths[$sObjectId]['templates'] = [];
// friendly id
$sId = $sObjectId;
if ($oObject instanceof AbstractBrick) {
$sId = $oObject->GetId();
}
// store object information
$this->aInstancesOverriddenTemplatesPaths[$sObjectId]['info'] = [
'class' => get_class($oObject),
'id' => $sId,
];
}
// store template path
$this->aInstancesOverriddenTemplatesPaths[$sObjectId]['templates'][$sTemplateId] = $sTemplatePath;
return $this;
}
/**
* Get a template path.
*
* @param string $sProviderClass the templates provider class
* @param string $sTemplateId the template id
* @param bool $bIsInitial
*
* @return string|null
* @throws \ReflectionException
*/
public function GetTemplatePath(string $sProviderClass, string $sTemplateId, bool $bIsInitial = false): ?string
{
if ($this->oTemplateRegister->IsProviderExists($sProviderClass)) {
// I
// SERVICE DECLARATION
// the provider class is known by service
// the class register its templates with service
// search for the template definition
$oTemplateDefinition = $this->oTemplateRegister->GetTemplateDefinition($sProviderClass, $sTemplateId);
// return the template path
return $oTemplateDefinition?->GetPath($bIsInitial);
} else {
// II
// LEGACY DECLARATION
// the provider class is unknown by service
// the class register its templates with legacy constants
return $this->GetLegacyTemplatePath($sProviderClass, $sTemplateId);
}
}
/**
* @param string $sProviderClass
* @param string $sTemplateId
*
* @return string|null
* @throws \ReflectionException
*/
private function GetLegacyTemplatePath(string $sProviderClass, string $sTemplateId): ?string
{
// reflexion for class
$oReflexion = new ReflectionClass($sProviderClass);
// class defined constants
$aClassDefinedConstants = array_diff($oReflexion->getConstants(), $oReflexion->getParentClass()->getConstants());
// return the constant if exists
return match ($sTemplateId) {
'page' => array_key_exists('DEFAULT_PAGE_TEMPLATE_PATH', $aClassDefinedConstants) ? $oReflexion->getConstant('DEFAULT_PAGE_TEMPLATE_PATH') : null,
'tile' => array_key_exists('DEFAULT_TILE_TEMPLATE_PATH', $aClassDefinedConstants) ? $oReflexion->getConstant('DEFAULT_TILE_TEMPLATE_PATH') : null,
default => null,
};
}
/**
* Get a provider instance template path.
*
* @param object $oObject
* @param string $sTemplateId
*
* @return string|null
*
*/
public function GetProviderInstanceTemplatePath(object $oObject, string $sTemplateId): ?string
{
// object UUID
$sObjectId = spl_object_id($oObject);
// get the provider instance class name
$sCurrentClass = get_class($oObject);
// get template definition if it exists
$oTemplateDefinition = $this->oTemplateRegister->GetTemplateDefinition($sCurrentClass, $sTemplateId);
$sId = $oTemplateDefinition != null ? $oTemplateDefinition->GetId() : $sTemplateId;
// if instance override exists, return it
if (array_key_exists($sObjectId, $this->aInstancesOverriddenTemplatesPaths)
&& array_key_exists($sId, $this->aInstancesOverriddenTemplatesPaths[$sObjectId]['templates'])) {
return $this->aInstancesOverriddenTemplatesPaths[$sObjectId]['templates'][$sId];
}
// now, we search in class hierarchy for a template
do {
$oParent = null;
try {
// get template path for current class
$sTemplate = $this->GetTemplatePath($sCurrentClass, $sTemplateId);
if ($sTemplate !== null) {
return $sTemplate;
}
// no template defined at this level, try parent class
$oReflexion = new ReflectionClass($sCurrentClass);
$oParent = $oReflexion->getParentClass();
if ($oParent) {
$sCurrentClass = $oReflexion->getParentClass()->getName();
}
}
catch (Exception) {
}
} while ($oParent); // continue while parent class exists
return null; // no template found
}
/**
* Return the register.
*
* @return \Combodo\iTop\Portal\Service\TemplatesProvider\TemplatesRegister
*/
public function GetRegister(): TemplatesRegister
{
return $this->oTemplateRegister;
}
/**
* Return instances overridden templates paths.
*
* @return array
*/
public function GetInstancesOverriddenTemplatesPaths(): array
{
return $this->aInstancesOverriddenTemplatesPaths;
}
/**
* Returns true if brick template path is overridden.
*
* @param object $oObject object instance
* @param string $sTemplateId template identifier
*
* @return bool
*/
public function HasInstanceOverriddenTemplate(object $oObject, string $sTemplateId): bool
{
// object UUID
$sObjectId = spl_object_id($oObject);
return (array_key_exists($sObjectId, $this->aInstancesOverriddenTemplatesPaths)
&& array_key_exists($sTemplateId, $this->aInstancesOverriddenTemplatesPaths[$sObjectId]['templates']));
}
}

View File

@@ -0,0 +1,133 @@
<?php
/**
* Copyright (C) 2013-2024 Combodo SAS
*
* This file is part of iTop.
*
* iTop is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* iTop is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
*/
namespace Combodo\iTop\Portal\Service\TemplatesProvider;
/**
* Template register.
*
*
* @package Combodo\iTop\Portal\Service\TemplatesProvider
* @since 3.2.1
*/
class TemplatesRegister
{
/** @var array Templates definitions (possibly altered by portal configuration) */
private array $aTemplatesDefinitions = [];
public function __construct(private string $sTemplateUIVersion = 'unset')
{
}
/**
* @return string
*/
public function GetUIVersion(): string
{
return $this->sTemplateUIVersion;
}
public function IsProviderExists(string $sProviderId): bool
{
return array_key_exists($sProviderId, $this->aTemplatesDefinitions);
}
public function IsTemplateExists(string $sProviderId, string $sTemplateId): bool
{
return array_key_exists($sProviderId, $this->aTemplatesDefinitions) && array_key_exists($sTemplateId, $this->aTemplatesDefinitions[$sProviderId]);
}
/**
* Register templates.
*
* @param string $sProviderId the templates provider id
* @param \Combodo\iTop\Portal\Service\TemplatesProvider\TemplateDefinitionDto ...$aTemplatesDefinitions
*
* @return \Combodo\iTop\Portal\Service\TemplatesProvider\TemplatesRegister
*/
public function RegisterTemplates(string $sProviderId, TemplateDefinitionDto...$aTemplatesDefinitions): TemplatesRegister
{
// prevent child classes to erase parent templates
if (array_key_exists($sProviderId, $this->aTemplatesDefinitions)) {
return $this;
}
// register templates...
$this->aTemplatesDefinitions[$sProviderId] = [];
foreach ($aTemplatesDefinitions as $oTemplateDefinition) {
$this->aTemplatesDefinitions[$sProviderId][$oTemplateDefinition->GetId()] = $oTemplateDefinition;
}
return $this;
}
/**
* Get a template definition.
*
* @param string $sProviderId the templates provider id
* @param string $sTemplateId the template id
*
* @return TemplateDefinitionDto|null
*/
public function GetTemplateDefinition(string $sProviderId, string $sTemplateId): ?TemplateDefinitionDto
{
// retrieve template path
if (array_key_exists($sProviderId, $this->aTemplatesDefinitions)) {
// search in template definitions
if (array_key_exists($sTemplateId, $this->aTemplatesDefinitions[$sProviderId])) {
return $this->aTemplatesDefinitions[$sProviderId][$sTemplateId];
}
// search in aliases
foreach ($this->aTemplatesDefinitions[$sProviderId] as $item) {
/** @var \Combodo\iTop\Portal\Service\TemplatesProvider\TemplateDefinitionDto $item */
if ($item->GetAlias() === $sTemplateId) {
return $item;
}
}
}
return null;
}
/**
* @param string $sProviderId
*
* @return array
*/
public function GetProviderTemplatesIds(string $sProviderId): array
{
return array_map(fn($oTemplateDefinition) => $oTemplateDefinition->GetId(), $this->aTemplatesDefinitions[$sProviderId] ?? ['tile', 'page']);
}
/**
* Return templates definitions.
*
* @return array
*/
public function GetTemplatesDefinitions(): array
{
return $this->aTemplatesDefinitions;
}
}

View File

@@ -0,0 +1,81 @@
<?php
/**
* Copyright (C) 2013-2023 Combodo SARL
*
* This file is part of iTop.
*
* iTop is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* iTop is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
*/
namespace Combodo\iTop\Portal\Twig;
use Combodo\iTop\Portal\Service\TemplatesProvider\TemplatesProviderService;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;
/**
* New Twig function useful for extending or including template handled by templates provider service.
*
* @package Combodo\iTop\Portal\Twig
* @since 3.2.1
*/
class TemplatesTwigExtension extends AbstractExtension
{
const DEFAULT_PROVIDER_CLASS = 'Combodo\\iTop\\Portal\\Controller\\AbstractController';
public function __construct(private readonly TemplatesProviderService $oTemplatesService)
{
}
/** @inheritdoc */
public function getFunctions(): array
{
return [
new TwigFunction('template', [$this, 'GetTemplate'], ['id' => null, 'provider' => null, 'provider_instance' => null]),
new TwigFunction('template_initial', [$this, 'GetInitialTemplate'], ['id' => null, 'provider' => null]),
];
}
/**
* Retrieve the path of the desired template (maybe overridden by configuration or by instance).
*
* @param string $sId template identifier
* @param string $sProviderClass provider class FQN
* @param object|null $oProviderInstance the provider instance
*
* @return string the template path
* @throws \ReflectionException
*/
public function GetTemplate(string $sId, string $sProviderClass = self::DEFAULT_PROVIDER_CLASS, object $oProviderInstance = null): string
{
if ($oProviderInstance === null) {
return $this->oTemplatesService->GetTemplatePath($sProviderClass, $sId);
} else {
return $this->oTemplatesService->GetProviderInstanceTemplatePath($oProviderInstance, $sId);
}
}
/**
* Retrieve the initial path of the desired template (hardcoded).
*
* @param string $sId template identifier
* @param string $sProviderClass provider class FQN
*
* @return string the template path
* @throws \ReflectionException
*/
public function GetInitialTemplate(string $sId, string $sProviderClass = self::DEFAULT_PROVIDER_CLASS): string
{
return $this->oTemplatesService->GetTemplatePath($sProviderClass, $sId, true);
}
}

View File

@@ -1,5 +1,4 @@
{# itop-portal-base/portal/templates/bricks/aggregate-page/layout.html.twig #}
{% extends 'itop-portal-base/portal/templates/bricks/layout.html.twig' %}
{% extends template('page', 'Combodo\\iTop\\Portal\\Brick\\AbstractBrick') %}
{% block pPageBodyClass %}{{ parent() }} page_aggregate_page_brick home{% endblock %}

View File

@@ -1,6 +1,4 @@
{# itop-portal-base/portal/templates/bricks/browse/layout.html.twig #}
{# Browse brick base layout #}
{% extends 'itop-portal-base/portal/templates/bricks/layout.html.twig' %}
{% extends template('page', 'Combodo\\iTop\\Portal\\Brick\\AbstractBrick') %}
{% block pPageBodyClass %}{{ parent() }} page_browse_brick page_browse_brick_as_{{ sBrowseMode }}{% endblock %}

View File

@@ -1,6 +1,4 @@
{# itop-portal-base/portal/templates/bricks/browse/mode_list.html.twig #}
{# Browse brick list mode layout #}
{% extends 'itop-portal-base/portal/templates/bricks/browse/layout.html.twig' %}
{% extends template('page', 'Combodo\\iTop\\Portal\\Brick\\BrowseBrick', oBrick) %}
{% block bBrowseMainContent%}
<table id="brick-content-table" class="object-list table table-striped table-bordered responsive" cellspacing="0" width="100%">
@@ -11,8 +9,8 @@
{% block pPageLiveScripts %}
{{ parent() }}
<script type="text/javascript">
<script type="text/javascript">
var sBrowseMode = '{{ sBrowseMode }}';
var sDataLoading = '{{ sDataLoading }}';
var oLevelsProperties = {{ aLevelsProperties|raw }};
@@ -22,8 +20,8 @@
var iSearchThrottle = 600;
var oKeyTimeout;
var aKeyTimeoutFilteredKeys = [9, 16, 17, 18, 19, 27, 33, 34, 35, 36, 37, 38, 39, 40]; // Tab, Shift, Ctrl, Alt, Pause, Esc, Page Up/Down, Home, End, Left/Up/Right/Down arrows
// Show a loader inside the table
// Show a loader inside the table
var showTableLoader = function(oElem)
{
oElem.children('tbody').html('<tr><td class="datatables_overlay" colspan="100">' + $('#page_overlay').html() + '</td></tr>');
@@ -32,8 +30,8 @@
var getColumnsDefinition = function()
{
var aColumnsDefinition = [];
for(sKey in oLevelsProperties)
for (sKey in oLevelsProperties)
{
// Level main column
aColumnsDefinition.push({
@@ -189,8 +187,8 @@
},
},
});
// Level's fields columns
// Level's fields columns
if(oLevelsProperties[sKey].fields !== undefined)
{
for(var i in oLevelsProperties[sKey].fields)
@@ -231,15 +229,15 @@
}
}
}
return aColumnsDefinition;
return aColumnsDefinition;
};
$(document).ready(function()
$(document).ready(function ()
{
showTableLoader($('#brick-content-table'));
// Note : Those options should be externalized in an library so we can use them on any DataTables for the portal.
// Note : Those options should be externalized in an library so we can use them on any DataTables for the portal.
// We would just have to override / complete the necessary elements
oTable = $('#brick-content-table').DataTable({
"language": {
@@ -331,8 +329,8 @@
// Note : The '.off()' call is to unbind event from DataTables that where triggered before we could intercept anything
$('#brick-content-table_filter input').off().on('keyup', function(event){
var me = this;
// We trigger the search only if those keys where not pressed
// We trigger the search only if those keys where not pressed
if(aKeyTimeoutFilteredKeys.indexOf(event.which) < 0)
{
clearTimeout(oKeyTimeout);
@@ -348,8 +346,8 @@
showTableLoader($(this));
}
});
// Auto collapse item actions popup
// Auto collapse item actions popup
$('body').on('click', function(){
$('table .item-action-wrapper.collapse.in').collapse('hide');
});

View File

@@ -1,6 +1,4 @@
{# itop-portal-base/portal/templates/bricks/browse/mode_mosaic.html.twig #}
{# Browse brick mosaic mode layout #}
{% extends 'itop-portal-base/portal/templates/bricks/browse/layout.html.twig' %}
{% extends template('page', 'Combodo\\iTop\\Portal\\Brick\\BrowseBrick', oBrick) %}
{% block bBrowseMainContent %}
<div id="brick_content_mosaic">

View File

@@ -1,6 +1,4 @@
{# itop-portal-base/portal/templates/bricks/browse/mode_tree.html.twig #}
{# Browse brick tree mode layout #}
{% extends 'itop-portal-base/portal/templates/bricks/browse/layout.html.twig' %}
{% extends template('page', 'Combodo\\iTop\\Portal\\Brick\\BrowseBrick', oBrick) %}
{#
Documentation :

View File

@@ -1,44 +0,0 @@
{# itop-portal-base/portal/templates/bricks/create/layout.html.twig #}
{# Create brick base layout #}
{% extends 'itop-portal-base/portal/templates/modal/layout.html.twig' %}
{% block pModalTitle %}
{{ sPageTitle|dict_s }}
{% endblock %}
{% block pModalBody %}
<p>{{ 'Brick:Portal:Create:ChooseType'|dict_s }}</p>
<ul id="{{ sLeafClassesListId }}">
{% for aLeafClass in aLeafClasses %}
<li><a href="#" data-target-class="{{ aLeafClass.id }}">{{ aLeafClass.name }}</a></li>
{% endfor %}
</ul>
<script type="text/javascript">
$(document).ready(function(){
$('#{{ sLeafClassesListId }} a').off('click').on('click', function(oEvent){
oEvent.preventDefault();
// Preparing target class url
var sUrl = '{{ app['url_generator'].generate('p_object_create', {sObjectClass : '-sObjectClass-'})|raw }}';
sUrl = sUrl.replace(/-sObjectClass-/, $(this).attr('data-target-class') );
sUrl = CombodoGlobalToolbox.AddParameterToUrl(sUrl, 'ar_token', '{{ ar_token }}');
// Creating a new modal
CombodoModal.OpenModal({
base_modal: {
usage: 'replace',
selector: $(this).closest('.modal'),
},
content: {
endpoint: sUrl,
},
});
});
});
</script>
{% endblock %}
{% block pModalFooter %}
<button type="button" class="btn btn-default" data-dismiss="modal">{{ 'Portal:Button:Cancel'|dict_s }}</button>
{% endblock %}

View File

@@ -1,6 +1,4 @@
{# itop-portal-base/portal/templates/bricks/layout.html.twig #}
{# Brick base layout #}
{% extends app['combodo.portal.instance.conf'].properties.templates.layout %}
{% extends template('page') %}
{% block pPageTitle %}
{# Overloading the default template's title to show the brick's title #}

View File

@@ -1,6 +1,4 @@
{# itop-portal-base/portal/templates/bricks/manage/layout-chart.html.twig #}
{# Manage brick base layout #}
{% extends 'itop-portal-base/portal/templates/bricks/manage/layout.html.twig' %}
{% extends template('page', 'Combodo\\iTop\\Portal\\Brick\\ManageBrick', oBrick) %}
{% block pPageBodyClass %}{{ parent() }} page_manage_brick{% endblock %}
@@ -8,7 +6,7 @@
{% block pMainContentHolder %}
<div class="panel panel-default">
<div class="panel-body">
{% include 'itop-portal-base/portal/templates/bricks/manage/mode-' ~ sDisplayMode ~ '.html.twig' with {'oBrick': oBrick, 'aColumns': aColumns, 'aNames': aNames, 'aUrls': aUrls, 'aDisplayValues': aDisplayValues} %}
{% include template(sDisplayMode, 'Combodo\\iTop\\Portal\\Brick\\ManageBrick', oBrick) with {'oBrick': oBrick, 'aColumns': aColumns, 'aNames': aNames, 'aUrls': aUrls, 'aDisplayValues': aDisplayValues} %}
</div>
</div>
{% endblock %}

View File

@@ -1,6 +1,4 @@
{# itop-portal-base/portal/templates/bricks/manage/layout-table.html.twig #}
{# Manage brick base layout #}
{% extends 'itop-portal-base/portal/templates/bricks/manage/layout.html.twig' %}
{% extends template('page', 'Combodo\\iTop\\Portal\\Brick\\ManageBrick', oBrick) %}
{% block pPageBodyClass %}{{ parent() }} page_manage_brick{% endblock %}

View File

@@ -1,5 +1,4 @@
{# itop-portal-base/portal/templates/bricks/manage/layout.html.twig #}
{% extends 'itop-portal-base/portal/templates/bricks/layout.html.twig' %}
{% extends template('page', 'Combodo\\iTop\\Portal\\Brick\\AbstractBrick') %}
{% block pMainHeaderTitle %}{{ oBrick.GetTitle()|dict_s }} {% if iCount >= 0 %} ({{ iCount }}){% endif %} {% endblock %}
@@ -9,7 +8,7 @@
{% for sDisplay in oBrick.GetAvailablesDisplayModes %}
<a href="{{ app.url_generator.generate('p_manage_brick_display_as', {'sBrickId': sBrickId, 'sDisplayMode': sDisplay}) }}{% if app['combodo.portal.instance.routes'][oBrick.GetRouteName]['hash'] is defined %}#{{ app['combodo.portal.instance.routes'][oBrick.GetRouteName]['hash'] }}{% endif %}"
id="btn_tab_for_{{ sDisplay }}"
class="btn btn-default {% if sDisplay == oBrick.GetPresentationDataForTileMode(sDisplayMode).layoutDisplayMode %}active{% endif %}">
class="btn btn-default {% if sDisplay == sDisplayMode %}active{% endif %}">
{{ ('Brick:Portal:Manage:DisplayMode:' ~ sDisplay)|dict_s }}
</a>
{% endfor %}

View File

@@ -10,9 +10,9 @@
id="brick-{{ oBrick.GetId }}"
data-brick-id="{{ oBrick.GetId }}">
<div>
<div class="tile_title"><span class="icon fas fa-{{ oBrick.GetDecorationCssClass }}"></span> {{ oBrick.GetTitle()|dict_s }}
<div class="tile_title"><span class="icon {{ oBrick.GetDecorationClassHome }}"></span> {{ oBrick.GetTitle()|dict_s }}
({{ iCount }})</span> </div>
{% include 'itop-portal-base/portal/templates/bricks/manage/mode-' ~ oBrick.GetTileMode ~ '.html.twig' with {'oBrick': oBrick, 'aColumns': aColumns, 'aNames': aNames, 'aUrls': aUrls, 'aDisplayValues': aDisplayValues} %}
{% include template(oBrick.GetTileMode, 'Combodo\\iTop\\Portal\\Brick\\ManageBrick', oBrick) with {'oBrick': oBrick, 'aColumns': aColumns, 'aNames': aNames, 'aUrls': aUrls, 'aDisplayValues': aDisplayValues} %}
</div>
</a>
{% endblock %}

View File

@@ -11,7 +11,7 @@
data-brick-id="{{ oBrick.GetId }}">
<div style="background-color:#fff;padding:0.25em;">
<div class="tile_title">
<span class="icon fas fa-signal fa-rotate-270"></span> {{ oBrick.GetTitle()|dict_s }}
<span class="icon {{ oBrick.GetDecorationClassHome }}"></span> {{ oBrick.GetTitle()|dict_s }}
({{ iCount }})</span> </div>
<table class="table table-sm">
<thead>

View File

@@ -1,6 +1,4 @@
{# itop-portal-base/portal/templates/bricks/object/layout.html.twig #}
{# Object brick base layout #}
{% extends 'itop-portal-base/portal/templates/bricks/layout.html.twig' %}
{% extends template('page') %}
{% block pPageBodyClass %}{{ parent() }} page_object_brick page_object_brick_as_{{ sMode }}{% endblock %}
@@ -27,7 +25,7 @@
{% block pMainContentHolder%}
<div class="panel panel-default">
<div class="panel-body">
{% include 'itop-portal-base/portal/templates/bricks/object/mode_' ~ sMode ~ '.html.twig' %}
{% include template(sMode, 'Combodo\\iTop\\Portal\\Controller\\ObjectController') %}
</div>
</div>
{% endblock %}

View File

@@ -1,6 +1,4 @@
{# itop-portal-base/portal/templates/bricks/object/modal.html.twig #}
{# Object brick base layout #}
{% extends 'itop-portal-base/portal/templates/modal/layout.html.twig' %}
{% extends template('modal') %}
{% block pModalTitle %}
{% if form.title_clipboard_text is defined %}
@@ -19,5 +17,5 @@
{% endblock %}
{% block pModalBody %}
{% include 'itop-portal-base/portal/templates/bricks/object/mode_' ~ sMode ~ '.html.twig' with {tIsModal: true} %}
{% include template(sMode, 'Combodo\\iTop\\Portal\\Controller\\ObjectController') with {tIsModal: true} %}
{% endblock %}

View File

@@ -1,5 +1,3 @@
{# itop-portal-base/portal/templates/bricks/object/mode_apply_stimulus.html.twig #}
{# Object brick apply stimulus layout #}
{% extends 'itop-portal-base/portal/templates/bricks/object/mode_create.html.twig' %}
{% extends template('mode_create', 'Combodo\\iTop\\Portal\\Controller\\ObjectController') %}
{# This layout is exactly the same as the mode_create.html.twig, we duplicated it in case we need to have some subtle differences #}

View File

@@ -1,5 +1,3 @@
{# itop-portal-base/portal/templates/bricks/object/mode_create.html.twig #}
{# Object brick edit layout #}
{% extends 'itop-portal-base/portal/templates/bricks/object/mode_create.html.twig' %}
{% extends template('mode_create', 'Combodo\\iTop\\Portal\\Controller\\ObjectController') %}
{# This layout is exactly the same as the mode_create.html.twig, we duplicated it in case we need to have some subtle differences #}

View File

@@ -1,6 +1,4 @@
{# itop-portal-base/portal/templates/bricks/object/mode_view.html.twig #}
{# Object brick view layout #}
{% extends 'itop-portal-base/portal/templates/bricks/object/mode_create.html.twig' %}
{% extends template('mode_create', 'Combodo\\iTop\\Portal\\Controller\\ObjectController') %}
{# This layout is exactly the same as the mode_create.html.twig, we duplicated it in case we need to have some subtle differences #}

View File

@@ -1,6 +1,4 @@
{# itop-portal-base/portal/templates/bricks/user-profile/layout.html.twig #}
{# User profile brick base layout #}
{% extends 'itop-portal-base/portal/templates/bricks/layout.html.twig' %}
{% extends template('page', 'Combodo\\iTop\\Portal\\Brick\\AbstractBrick') %}
{% if sTab == "" %}
{% set sTab = "user-info" %}

View File

@@ -0,0 +1,170 @@
{% extends '@WebProfiler/Profiler/layout.html.twig' %}
{% block toolbar %}
{# toolbar text & icon #}
{% set icon %}
<span class="icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" fill="currentColor"><path d="M192 64l0 64c0 17.7 14.3 32 32 32l64 0c17.7 0 32-14.3 32-32l0-64c0-17.7-14.3-32-32-32l-64 0c-17.7 0-32 14.3-32 32zM82.7 207c-15.3 8.8-20.5 28.4-11.7 43.7l32 55.4c8.8 15.3 28.4 20.5 43.7 11.7l55.4-32c15.3-8.8 20.5-28.4 11.7-43.7l-32-55.4c-8.8-15.3-28.4-20.5-43.7-11.7L82.7 207zM288 192c-17.7 0-32 14.3-32 32l0 64c0 17.7 14.3 32 32 32l64 0c17.7 0 32-14.3 32-32l0-64c0-17.7-14.3-32-32-32l-64 0zm64 160c-17.7 0-32 14.3-32 32l0 64c0 17.7 14.3 32 32 32l64 0c17.7 0 32-14.3 32-32l0-64c0-17.7-14.3-32-32-32l-64 0zM160 384l0 64c0 17.7 14.3 32 32 32l64 0c17.7 0 32-14.3 32-32l0-64c0-17.7-14.3-32-32-32l-64 0c-17.7 0-32 14.3-32 32zM32 352c-17.7 0-32 14.3-32 32l0 64c0 17.7 14.3 32 32 32l64 0c17.7 0 32-14.3 32-32l0-64c0-17.7-14.3-32-32-32l-64 0z"/></svg>
</span>
<span class="sf-toolbar-label">Portal{% if collector.GetTemplatesCount.overrides_count > 0 %} <span style=" color: var(--sf-toolbar-yellow-600);"> Overrides</span>{% endif %}</span>
{% endset %}
{# toolbar panel #}
{% set text %}
<div class="sf-toolbar-info-piece">
<b>Templates registered</b><span class="sf-toolbar-status">{{ collector.GetTemplatesCount.count }}</span>
</div>
{% if collector.GetTemplatesCount.overrides_count %}
<div class="sf-toolbar-info-piece">
<b>Templates overridden</b><span class="sf-toolbar-status">{{ collector.GetTemplatesCount.overrides_count }}</span>
</div>
{% endif %}
{% endset %}
{{ include('@WebProfiler/Profiler/toolbar_item.html.twig', { 'link': true }) }}
{% endblock %}
{% block head %}
{{ parent() }}
<style>
.overridden_value {
color: var(--color-link);
}
.old_value {
color: grey;
text-decoration: line-through;
}
</style>
{% endblock %}
{% block menu %}
{# menu #}
<span class="label label-status-none">
<span class="icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" fill="currentColor"><path d="M192 64l0 64c0 17.7 14.3 32 32 32l64 0c17.7 0 32-14.3 32-32l0-64c0-17.7-14.3-32-32-32l-64 0c-17.7 0-32 14.3-32 32zM82.7 207c-15.3 8.8-20.5 28.4-11.7 43.7l32 55.4c8.8 15.3 28.4 20.5 43.7 11.7l55.4-32c15.3-8.8 20.5-28.4 11.7-43.7l-32-55.4c-8.8-15.3-28.4-20.5-43.7-11.7L82.7 207zM288 192c-17.7 0-32 14.3-32 32l0 64c0 17.7 14.3 32 32 32l64 0c17.7 0 32-14.3 32-32l0-64c0-17.7-14.3-32-32-32l-64 0zm64 160c-17.7 0-32 14.3-32 32l0 64c0 17.7 14.3 32 32 32l64 0c17.7 0 32-14.3 32-32l0-64c0-17.7-14.3-32-32-32l-64 0zM160 384l0 64c0 17.7 14.3 32 32 32l64 0c17.7 0 32-14.3 32-32l0-64c0-17.7-14.3-32-32-32l-64 0c-17.7 0-32 14.3-32 32zM32 352c-17.7 0-32 14.3-32 32l0 64c0 17.7 14.3 32 32 32l64 0c17.7 0 32-14.3 32-32l0-64c0-17.7-14.3-32-32-32l-64 0z"/></svg>
</span>
<strong>Portal</strong>
<span class="count">
{{ collector.GetTemplatesCount.count }}
</span>
</span>
{% endblock %}
{% block panel %}
{# title #}
<h2>Templates</h2>
{# metrics #}
<div class="metrics">
{# ui version #}
<div class="metric">
<span class="value">{{ collector.GetUIVersion }}</span>
<span class="label">UI Version</span>
</div>
<div class="metric-divider"></div>
{# templates #}
<div class="metric-group">
<div class="metric">
<span class="value">{{ collector.GetTemplatesCount.count }}</span>
<span class="label">Templates</span>
</div>
<div class="metric">
<span class="value">{{ collector.GetTemplatesCount.overrides_count }}</span>
<span class="label">Overridden</span>
</div>
</div>
{# additional info #}
<div class="metric-divider"></div>
<div class="metric-group">
<div class="metric">
<span class="value">{{ collector.GetTemplatesCount.extensions_count }}</span>
<span class="label">Extensions</span>
</div>
<div class="metric">
<span class="value">{{ collector.GetTemplatesCount.providers_count }}</span>
<span class="label">Providers</span>
</div>
</div>
</div>
{# Instances overloads #}
<h2>Bricks declared templates list</h2>
{# help #}
<p class="help">
Bricks overridden templates are templates defined in brick declarations.
</p>
{% if collector.GetInstancesOverriddenTemplates|length == 0 %}
No instance overridden template.
{% else %}
<table>
<thead>
<tr>
<th>Brick</th>
<th>Class</th>
<th>ID</th>
<th>Template</th>
</tr>
</thead>
{% for instance,item in collector.GetInstancesOverriddenTemplates %}
{% for id,template in item.templates %}
<tr>
<td>{{ item.info.id }}</td>
<td>{{ item.info.class }}</td>
<td>{{ id }}</td>
<td>{{ template }}</td>
</tr>
{% endfor %}
{% endfor %}
</table>
{% endif %}
{# templates list #}
<h2>Templates list</h2>
{# help #}
<p class="help">
Templates doesn't necessary covers all existing templates, only the ones that are registered in the portal.
</p>
<table>
<thead>
<tr>
<th>Provider</th>
<th>ID</th>
<th>Template</th>
<th>Alias</th>
<th>Override</th>
</tr>
</thead>
{% for provider,item in collector.GetTemplatesDefinitions %}
{% for id,template in item %}
<tr {% if template.IsOverridden %}class="overridden_value"{% endif %}>
<td>{{ provider }}</td>
<td>{{ template.Id }}</td>
<td>{{ template.path }}{% if template.IsOverridden %}
<div class="old_value">{{ template.GetPath(true) }}</div>{% endif %}</td>
<td>{{ template.Alias }}</td>
<td>{% if template.IsOverridable %}
{% if template.IsOverridden %}
Yes
{% else %}
No
{% endif %}
{% else %}
Not allowed
{% endif %}
</td>
</tr>
{% endfor %}
{% endfor %}
</table>
{% endblock %}

View File

@@ -22,4 +22,4 @@ if (PHP_VERSION_ID < 50600) {
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInitdf408f3f8ea034d298269cdf7647358b::getLoader();
return ComposerAutoloaderInitd751713988987e9331980363e24189ce::getLoader();

View File

@@ -14,7 +14,6 @@ return array(
'Combodo\\iTop\\Portal\\Brick\\CreateBrick' => $baseDir . '/src/Brick/CreateBrick.php',
'Combodo\\iTop\\Portal\\Brick\\FilterBrick' => $baseDir . '/src/Brick/FilterBrick.php',
'Combodo\\iTop\\Portal\\Brick\\ManageBrick' => $baseDir . '/src/Brick/ManageBrick.php',
'Combodo\\iTop\\Portal\\Brick\\ObjectBrick' => $baseDir . '/src/Brick/ObjectBrick.php',
'Combodo\\iTop\\Portal\\Brick\\PortalBrick' => $baseDir . '/src/Brick/PortalBrick.php',
'Combodo\\iTop\\Portal\\Brick\\PropertyNotFoundException' => $baseDir . '/src/Brick/PropertyNotFoundException.php',
'Combodo\\iTop\\Portal\\Brick\\UserProfileBrick' => $baseDir . '/src/Brick/UserProfileBrick.php',
@@ -28,6 +27,7 @@ return array(
'Combodo\\iTop\\Portal\\Controller\\ObjectController' => $baseDir . '/src/Controller/ObjectController.php',
'Combodo\\iTop\\Portal\\Controller\\SessionMessageController' => $baseDir . '/src/Controller/SessionMessageController.php',
'Combodo\\iTop\\Portal\\Controller\\UserProfileBrickController' => $baseDir . '/src/Controller/UserProfileBrickController.php',
'Combodo\\iTop\\Portal\\DataCollector\\PortalCollector' => $baseDir . '/src/DataCollector/PortalCollector.php',
'Combodo\\iTop\\Portal\\DependencyInjection\\SilexCompatBootstrap\\PortalXmlConfiguration\\AbstractConfiguration' => $baseDir . '/src/DependencyInjection/SilexCompatBootstrap/PortalXmlConfiguration/AbstractConfiguration.php',
'Combodo\\iTop\\Portal\\DependencyInjection\\SilexCompatBootstrap\\PortalXmlConfiguration\\Basic' => $baseDir . '/src/DependencyInjection/SilexCompatBootstrap/PortalXmlConfiguration/Basic.php',
'Combodo\\iTop\\Portal\\DependencyInjection\\SilexCompatBootstrap\\PortalXmlConfiguration\\Forms' => $baseDir . '/src/DependencyInjection/SilexCompatBootstrap/PortalXmlConfiguration/Forms.php',
@@ -60,6 +60,10 @@ return array(
'Combodo\\iTop\\Portal\\Kernel' => $baseDir . '/src/Kernel.php',
'Combodo\\iTop\\Portal\\Routing\\ItopExtensionsExtraRoutes' => $baseDir . '/src/Routing/ItopExtensionsExtraRoutes.php',
'Combodo\\iTop\\Portal\\Routing\\UrlGenerator' => $baseDir . '/src/Routing/UrlGenerator.php',
'Combodo\\iTop\\Portal\\Service\\TemplatesProvider\\TemplateDefinitionDto' => $baseDir . '/src/Service/TemplatesProvider/TemplateDefinitionDto.php',
'Combodo\\iTop\\Portal\\Service\\TemplatesProvider\\TemplatesProviderInterface' => $baseDir . '/src/Service/TemplatesProvider/TemplatesProviderInterface.php',
'Combodo\\iTop\\Portal\\Service\\TemplatesProvider\\TemplatesProviderService' => $baseDir . '/src/Service/TemplatesProvider/TemplatesProviderService.php',
'Combodo\\iTop\\Portal\\Service\\TemplatesProvider\\TemplatesRegister' => $baseDir . '/src/Service/TemplatesProvider/TemplatesRegister.php',
'Combodo\\iTop\\Portal\\Twig\\AppExtension' => $baseDir . '/src/Twig/AppExtension.php',
'Combodo\\iTop\\Portal\\Twig\\AppGlobal' => $baseDir . '/src/Twig/AppGlobal.php',
'Combodo\\iTop\\Portal\\Twig\\AppVariable' => $baseDir . '/src/Twig/AppVariable.php',
@@ -67,6 +71,7 @@ return array(
'Combodo\\iTop\\Portal\\Twig\\CurrentUserAccessor' => $baseDir . '/src/Twig/CurrentUserAccessor.php',
'Combodo\\iTop\\Portal\\Twig\\PortalBlockExtension' => $baseDir . '/src/Twig/PortalBlockExtension.php',
'Combodo\\iTop\\Portal\\Twig\\PortalTwigContext' => $baseDir . '/src/Twig/PortalTwigContext.php',
'Combodo\\iTop\\Portal\\Twig\\TemplatesTwigExtension' => $baseDir . '/src/Twig/TemplatesTwigExtension.php',
'Combodo\\iTop\\Portal\\UrlMaker\\AbstractPortalUrlMaker' => $baseDir . '/src/UrlMaker/AbstractPortalUrlMaker.php',
'Combodo\\iTop\\Portal\\VariableAccessor\\AbstractStringVariableAccessor' => $baseDir . '/src/VariableAccessor/AbstractStringVariableAccessor.php',
'Combodo\\iTop\\Portal\\VariableAccessor\\AbstractVariableAccessor' => $baseDir . '/src/VariableAccessor/AbstractVariableAccessor.php',

View File

@@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
class ComposerAutoloaderInitdf408f3f8ea034d298269cdf7647358b
class ComposerAutoloaderInitd751713988987e9331980363e24189ce
{
private static $loader;
@@ -22,14 +22,13 @@ class ComposerAutoloaderInitdf408f3f8ea034d298269cdf7647358b
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInitdf408f3f8ea034d298269cdf7647358b', 'loadClassLoader'), true, true);
spl_autoload_register(array('ComposerAutoloaderInitd751713988987e9331980363e24189ce', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInitdf408f3f8ea034d298269cdf7647358b', 'loadClassLoader'));
spl_autoload_unregister(array('ComposerAutoloaderInitd751713988987e9331980363e24189ce', 'loadClassLoader'));
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInitdf408f3f8ea034d298269cdf7647358b::getInitializer($loader));
call_user_func(\Composer\Autoload\ComposerStaticInitd751713988987e9331980363e24189ce::getInitializer($loader));
$loader->setClassMapAuthoritative(true);
$loader->register(true);
return $loader;

View File

@@ -4,7 +4,7 @@
namespace Composer\Autoload;
class ComposerStaticInitdf408f3f8ea034d298269cdf7647358b
class ComposerStaticInitd751713988987e9331980363e24189ce
{
public static $prefixLengthsPsr4 = array (
'C' =>
@@ -34,7 +34,6 @@ class ComposerStaticInitdf408f3f8ea034d298269cdf7647358b
'Combodo\\iTop\\Portal\\Brick\\CreateBrick' => __DIR__ . '/../..' . '/src/Brick/CreateBrick.php',
'Combodo\\iTop\\Portal\\Brick\\FilterBrick' => __DIR__ . '/../..' . '/src/Brick/FilterBrick.php',
'Combodo\\iTop\\Portal\\Brick\\ManageBrick' => __DIR__ . '/../..' . '/src/Brick/ManageBrick.php',
'Combodo\\iTop\\Portal\\Brick\\ObjectBrick' => __DIR__ . '/../..' . '/src/Brick/ObjectBrick.php',
'Combodo\\iTop\\Portal\\Brick\\PortalBrick' => __DIR__ . '/../..' . '/src/Brick/PortalBrick.php',
'Combodo\\iTop\\Portal\\Brick\\PropertyNotFoundException' => __DIR__ . '/../..' . '/src/Brick/PropertyNotFoundException.php',
'Combodo\\iTop\\Portal\\Brick\\UserProfileBrick' => __DIR__ . '/../..' . '/src/Brick/UserProfileBrick.php',
@@ -48,6 +47,7 @@ class ComposerStaticInitdf408f3f8ea034d298269cdf7647358b
'Combodo\\iTop\\Portal\\Controller\\ObjectController' => __DIR__ . '/../..' . '/src/Controller/ObjectController.php',
'Combodo\\iTop\\Portal\\Controller\\SessionMessageController' => __DIR__ . '/../..' . '/src/Controller/SessionMessageController.php',
'Combodo\\iTop\\Portal\\Controller\\UserProfileBrickController' => __DIR__ . '/../..' . '/src/Controller/UserProfileBrickController.php',
'Combodo\\iTop\\Portal\\DataCollector\\PortalCollector' => __DIR__ . '/../..' . '/src/DataCollector/PortalCollector.php',
'Combodo\\iTop\\Portal\\DependencyInjection\\SilexCompatBootstrap\\PortalXmlConfiguration\\AbstractConfiguration' => __DIR__ . '/../..' . '/src/DependencyInjection/SilexCompatBootstrap/PortalXmlConfiguration/AbstractConfiguration.php',
'Combodo\\iTop\\Portal\\DependencyInjection\\SilexCompatBootstrap\\PortalXmlConfiguration\\Basic' => __DIR__ . '/../..' . '/src/DependencyInjection/SilexCompatBootstrap/PortalXmlConfiguration/Basic.php',
'Combodo\\iTop\\Portal\\DependencyInjection\\SilexCompatBootstrap\\PortalXmlConfiguration\\Forms' => __DIR__ . '/../..' . '/src/DependencyInjection/SilexCompatBootstrap/PortalXmlConfiguration/Forms.php',
@@ -80,6 +80,10 @@ class ComposerStaticInitdf408f3f8ea034d298269cdf7647358b
'Combodo\\iTop\\Portal\\Kernel' => __DIR__ . '/../..' . '/src/Kernel.php',
'Combodo\\iTop\\Portal\\Routing\\ItopExtensionsExtraRoutes' => __DIR__ . '/../..' . '/src/Routing/ItopExtensionsExtraRoutes.php',
'Combodo\\iTop\\Portal\\Routing\\UrlGenerator' => __DIR__ . '/../..' . '/src/Routing/UrlGenerator.php',
'Combodo\\iTop\\Portal\\Service\\TemplatesProvider\\TemplateDefinitionDto' => __DIR__ . '/../..' . '/src/Service/TemplatesProvider/TemplateDefinitionDto.php',
'Combodo\\iTop\\Portal\\Service\\TemplatesProvider\\TemplatesProviderInterface' => __DIR__ . '/../..' . '/src/Service/TemplatesProvider/TemplatesProviderInterface.php',
'Combodo\\iTop\\Portal\\Service\\TemplatesProvider\\TemplatesProviderService' => __DIR__ . '/../..' . '/src/Service/TemplatesProvider/TemplatesProviderService.php',
'Combodo\\iTop\\Portal\\Service\\TemplatesProvider\\TemplatesRegister' => __DIR__ . '/../..' . '/src/Service/TemplatesProvider/TemplatesRegister.php',
'Combodo\\iTop\\Portal\\Twig\\AppExtension' => __DIR__ . '/../..' . '/src/Twig/AppExtension.php',
'Combodo\\iTop\\Portal\\Twig\\AppGlobal' => __DIR__ . '/../..' . '/src/Twig/AppGlobal.php',
'Combodo\\iTop\\Portal\\Twig\\AppVariable' => __DIR__ . '/../..' . '/src/Twig/AppVariable.php',
@@ -87,6 +91,7 @@ class ComposerStaticInitdf408f3f8ea034d298269cdf7647358b
'Combodo\\iTop\\Portal\\Twig\\CurrentUserAccessor' => __DIR__ . '/../..' . '/src/Twig/CurrentUserAccessor.php',
'Combodo\\iTop\\Portal\\Twig\\PortalBlockExtension' => __DIR__ . '/../..' . '/src/Twig/PortalBlockExtension.php',
'Combodo\\iTop\\Portal\\Twig\\PortalTwigContext' => __DIR__ . '/../..' . '/src/Twig/PortalTwigContext.php',
'Combodo\\iTop\\Portal\\Twig\\TemplatesTwigExtension' => __DIR__ . '/../..' . '/src/Twig/TemplatesTwigExtension.php',
'Combodo\\iTop\\Portal\\UrlMaker\\AbstractPortalUrlMaker' => __DIR__ . '/../..' . '/src/UrlMaker/AbstractPortalUrlMaker.php',
'Combodo\\iTop\\Portal\\VariableAccessor\\AbstractStringVariableAccessor' => __DIR__ . '/../..' . '/src/VariableAccessor/AbstractStringVariableAccessor.php',
'Combodo\\iTop\\Portal\\VariableAccessor\\AbstractVariableAccessor' => __DIR__ . '/../..' . '/src/VariableAccessor/AbstractVariableAccessor.php',
@@ -98,9 +103,9 @@ class ComposerStaticInitdf408f3f8ea034d298269cdf7647358b
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInitdf408f3f8ea034d298269cdf7647358b::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInitdf408f3f8ea034d298269cdf7647358b::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInitdf408f3f8ea034d298269cdf7647358b::$classMap;
$loader->prefixLengthsPsr4 = ComposerStaticInitd751713988987e9331980363e24189ce::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInitd751713988987e9331980363e24189ce::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInitd751713988987e9331980363e24189ce::$classMap;
}, null, ClassLoader::class);
}

View File

@@ -3,7 +3,7 @@
'name' => '__root__',
'pretty_version' => 'dev-develop',
'version' => 'dev-develop',
'reference' => 'c9beba0ceadf11c644a8eb1b254efff9b17d804c',
'reference' => '4f6d514694b9813b9a5ebda4c38f29b4847ff9c3',
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
@@ -13,7 +13,7 @@
'__root__' => array(
'pretty_version' => 'dev-develop',
'version' => 'dev-develop',
'reference' => 'c9beba0ceadf11c644a8eb1b254efff9b17d804c',
'reference' => '4f6d514694b9813b9a5ebda4c38f29b4847ff9c3',
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),

View File

@@ -16,6 +16,7 @@
<module_design id="itop-portal" xsi:type="portal" _delta="define">
<properties>
<name>portal:itop-portal</name>
<ui_version>2017</ui_version>
<!-- Can be either a fileref or a relative path to the file (To be tested). Takes over env-xxx/branding/portal-logo.png -->
<!-- Priority order is <logo> from xml > env-xxx/branding/portal-logo.png > /images/logo-itop-dark-bg.svg -->
<!--<fileref ref="brt_6a2be154b2a62659d3332c513bdad715" />-->