mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
N°8031 - Make all portal bricks use custom templates for all templates (#696)
Service implementation
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 = '';
|
||||
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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'];
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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']));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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 %}
|
||||
|
||||
|
||||
@@ -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 %}
|
||||
|
||||
|
||||
@@ -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');
|
||||
});
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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 :
|
||||
|
||||
@@ -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 %}
|
||||
@@ -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 #}
|
||||
|
||||
@@ -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 %}
|
||||
|
||||
@@ -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 %}
|
||||
|
||||
|
||||
@@ -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 %}
|
||||
|
||||
@@ -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 %}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 %}
|
||||
@@ -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 %}
|
||||
@@ -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 #}
|
||||
|
||||
@@ -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 #}
|
||||
@@ -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 #}
|
||||
|
||||
|
||||
@@ -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" %}
|
||||
|
||||
@@ -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 %}
|
||||
@@ -22,4 +22,4 @@ if (PHP_VERSION_ID < 50600) {
|
||||
|
||||
require_once __DIR__ . '/composer/autoload_real.php';
|
||||
|
||||
return ComposerAutoloaderInitdf408f3f8ea034d298269cdf7647358b::getLoader();
|
||||
return ComposerAutoloaderInitd751713988987e9331980363e24189ce::getLoader();
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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" />-->
|
||||
|
||||
@@ -109,7 +109,11 @@ class InterfaceDiscovery
|
||||
|
||||
// guess all the autoload class maps from the extensions
|
||||
$aAutoloadClassMaps = glob(APPROOT.'env-'.utils::GetCurrentEnvironment().'/*/vendor/composer/autoload_classmap.php');
|
||||
if($aAutoloadClassMaps === false) {
|
||||
$aAutoloadClassMaps = [];
|
||||
}
|
||||
$aAutoloadClassMaps[] = APPROOT.'lib/composer/autoload_classmap.php';
|
||||
$aAutoloadClassMaps[] = APPROOT.'env-'.utils::GetCurrentEnvironment().'/itop-portal-base/portal/vendor/composer/autoload_classmap.php';
|
||||
|
||||
if ($this->GetCacheMode() === self::CACHE_DYNAMIC) {
|
||||
$this->oCacheService->Store('InterfaceDiscovery', 'autoload_classmaps', $aAutoloadClassMaps);
|
||||
|
||||
Reference in New Issue
Block a user