mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
N°8781 - Improve twig base controller render error report
This commit is contained in:
@@ -506,6 +506,7 @@ Dict::Add('EN US', 'English', 'English', array(
|
|||||||
'UI:Error:MaintenanceMode' => 'Application is currently in maintenance',
|
'UI:Error:MaintenanceMode' => 'Application is currently in maintenance',
|
||||||
'UI:Error:MaintenanceTitle' => 'Maintenance',
|
'UI:Error:MaintenanceTitle' => 'Maintenance',
|
||||||
'UI:Error:InvalidToken' => 'Error: the requested operation has already been performed (CSRF token not found)',
|
'UI:Error:InvalidToken' => 'Error: the requested operation has already been performed (CSRF token not found)',
|
||||||
|
'UI:Error:TwigController' => 'Internal error in form controller',
|
||||||
|
|
||||||
'UI:Error:SMTP:UnknownVendor' => 'OAuth SMTP provider %1$s does not exist (email_transport_smtp.oauth.provider)',
|
'UI:Error:SMTP:UnknownVendor' => 'OAuth SMTP provider %1$s does not exist (email_transport_smtp.oauth.provider)',
|
||||||
|
|
||||||
|
|||||||
@@ -500,6 +500,7 @@ Nous espérons que vous aimerez cette version autant que nous avons eu du plaisi
|
|||||||
'UI:Error:MaintenanceMode' => 'L\'application est en maintenance',
|
'UI:Error:MaintenanceMode' => 'L\'application est en maintenance',
|
||||||
'UI:Error:MaintenanceTitle' => 'Maintenance',
|
'UI:Error:MaintenanceTitle' => 'Maintenance',
|
||||||
'UI:Error:InvalidToken' => 'Erreur: l\'opération a déjà été effectuée (CSRF token not found)',
|
'UI:Error:InvalidToken' => 'Erreur: l\'opération a déjà été effectuée (CSRF token not found)',
|
||||||
|
'UI:Error:TwigController' => 'Erreur interne dans le contrôleur de formulaire',
|
||||||
'UI:Error:SMTP:UnknownVendor' => 'Le provider SMTP OAuth 2.0 %1$s n\'existe pas',
|
'UI:Error:SMTP:UnknownVendor' => 'Le provider SMTP OAuth 2.0 %1$s n\'existe pas',
|
||||||
'UI:GroupBy:Count' => 'Nombre',
|
'UI:GroupBy:Count' => 'Nombre',
|
||||||
'UI:GroupBy:Count+' => 'Nombre d\'éléments',
|
'UI:GroupBy:Count+' => 'Nombre d\'éléments',
|
||||||
|
|||||||
@@ -144,8 +144,10 @@ return array(
|
|||||||
'Combodo\\iTop\\Application\\Search\\CriterionParser' => $baseDir . '/sources/Application/Search/criterionparser.class.inc.php',
|
'Combodo\\iTop\\Application\\Search\\CriterionParser' => $baseDir . '/sources/Application/Search/criterionparser.class.inc.php',
|
||||||
'Combodo\\iTop\\Application\\Search\\SearchForm' => $baseDir . '/sources/Application/Search/searchform.class.inc.php',
|
'Combodo\\iTop\\Application\\Search\\SearchForm' => $baseDir . '/sources/Application/Search/searchform.class.inc.php',
|
||||||
'Combodo\\iTop\\Application\\Status\\Status' => $baseDir . '/sources/Application/Status/Status.php',
|
'Combodo\\iTop\\Application\\Status\\Status' => $baseDir . '/sources/Application/Status/Status.php',
|
||||||
|
'Combodo\\iTop\\Application\\TwigBase\\Controller\\AbstractProfilerExtension' => $baseDir . '/sources/Application/TwigBase/Controller/AbstractProfilerExtension.php',
|
||||||
'Combodo\\iTop\\Application\\TwigBase\\Controller\\Controller' => $baseDir . '/sources/Application/TwigBase/Controller/Controller.php',
|
'Combodo\\iTop\\Application\\TwigBase\\Controller\\Controller' => $baseDir . '/sources/Application/TwigBase/Controller/Controller.php',
|
||||||
'Combodo\\iTop\\Application\\TwigBase\\Controller\\PageNotFoundException' => $baseDir . '/application/exceptions/PageNotFoundException.php',
|
'Combodo\\iTop\\Application\\TwigBase\\Controller\\PageNotFoundException' => $baseDir . '/application/exceptions/PageNotFoundException.php',
|
||||||
|
'Combodo\\iTop\\Application\\TwigBase\\Controller\\iProfilerExtension' => $baseDir . '/sources/Application/TwigBase/Controller/iProfilerExtension.php',
|
||||||
'Combodo\\iTop\\Application\\TwigBase\\Twig\\Extension' => $baseDir . '/sources/Application/TwigBase/Twig/Extension.php',
|
'Combodo\\iTop\\Application\\TwigBase\\Twig\\Extension' => $baseDir . '/sources/Application/TwigBase/Twig/Extension.php',
|
||||||
'Combodo\\iTop\\Application\\TwigBase\\Twig\\TwigHelper' => $baseDir . '/sources/Application/TwigBase/Twig/TwigHelper.php',
|
'Combodo\\iTop\\Application\\TwigBase\\Twig\\TwigHelper' => $baseDir . '/sources/Application/TwigBase/Twig/TwigHelper.php',
|
||||||
'Combodo\\iTop\\Application\\TwigBase\\UI\\UIBlockExtension' => $baseDir . '/sources/Application/TwigBase/UI/UIBlockExtension.php',
|
'Combodo\\iTop\\Application\\TwigBase\\UI\\UIBlockExtension' => $baseDir . '/sources/Application/TwigBase/UI/UIBlockExtension.php',
|
||||||
@@ -2412,13 +2414,6 @@ return array(
|
|||||||
'Symfony\\Component\\Form\\SubmitButton' => $vendorDir . '/symfony/form/SubmitButton.php',
|
'Symfony\\Component\\Form\\SubmitButton' => $vendorDir . '/symfony/form/SubmitButton.php',
|
||||||
'Symfony\\Component\\Form\\SubmitButtonBuilder' => $vendorDir . '/symfony/form/SubmitButtonBuilder.php',
|
'Symfony\\Component\\Form\\SubmitButtonBuilder' => $vendorDir . '/symfony/form/SubmitButtonBuilder.php',
|
||||||
'Symfony\\Component\\Form\\SubmitButtonTypeInterface' => $vendorDir . '/symfony/form/SubmitButtonTypeInterface.php',
|
'Symfony\\Component\\Form\\SubmitButtonTypeInterface' => $vendorDir . '/symfony/form/SubmitButtonTypeInterface.php',
|
||||||
'Symfony\\Component\\Form\\Test\\FormBuilderInterface' => $vendorDir . '/symfony/form/Test/FormBuilderInterface.php',
|
|
||||||
'Symfony\\Component\\Form\\Test\\FormIntegrationTestCase' => $vendorDir . '/symfony/form/Test/FormIntegrationTestCase.php',
|
|
||||||
'Symfony\\Component\\Form\\Test\\FormInterface' => $vendorDir . '/symfony/form/Test/FormInterface.php',
|
|
||||||
'Symfony\\Component\\Form\\Test\\FormPerformanceTestCase' => $vendorDir . '/symfony/form/Test/FormPerformanceTestCase.php',
|
|
||||||
'Symfony\\Component\\Form\\Test\\Traits\\RunTestTrait' => $vendorDir . '/symfony/form/Test/Traits/RunTestTrait.php',
|
|
||||||
'Symfony\\Component\\Form\\Test\\Traits\\ValidatorExtensionTrait' => $vendorDir . '/symfony/form/Test/Traits/ValidatorExtensionTrait.php',
|
|
||||||
'Symfony\\Component\\Form\\Test\\TypeTestCase' => $vendorDir . '/symfony/form/Test/TypeTestCase.php',
|
|
||||||
'Symfony\\Component\\Form\\Util\\FormUtil' => $vendorDir . '/symfony/form/Util/FormUtil.php',
|
'Symfony\\Component\\Form\\Util\\FormUtil' => $vendorDir . '/symfony/form/Util/FormUtil.php',
|
||||||
'Symfony\\Component\\Form\\Util\\InheritDataAwareIterator' => $vendorDir . '/symfony/form/Util/InheritDataAwareIterator.php',
|
'Symfony\\Component\\Form\\Util\\InheritDataAwareIterator' => $vendorDir . '/symfony/form/Util/InheritDataAwareIterator.php',
|
||||||
'Symfony\\Component\\Form\\Util\\OptionsResolverWrapper' => $vendorDir . '/symfony/form/Util/OptionsResolverWrapper.php',
|
'Symfony\\Component\\Form\\Util\\OptionsResolverWrapper' => $vendorDir . '/symfony/form/Util/OptionsResolverWrapper.php',
|
||||||
@@ -3031,7 +3026,6 @@ return array(
|
|||||||
'Symfony\\Component\\Security\\Core\\Signature\\Exception\\InvalidSignatureException' => $vendorDir . '/symfony/security-core/Signature/Exception/InvalidSignatureException.php',
|
'Symfony\\Component\\Security\\Core\\Signature\\Exception\\InvalidSignatureException' => $vendorDir . '/symfony/security-core/Signature/Exception/InvalidSignatureException.php',
|
||||||
'Symfony\\Component\\Security\\Core\\Signature\\ExpiredSignatureStorage' => $vendorDir . '/symfony/security-core/Signature/ExpiredSignatureStorage.php',
|
'Symfony\\Component\\Security\\Core\\Signature\\ExpiredSignatureStorage' => $vendorDir . '/symfony/security-core/Signature/ExpiredSignatureStorage.php',
|
||||||
'Symfony\\Component\\Security\\Core\\Signature\\SignatureHasher' => $vendorDir . '/symfony/security-core/Signature/SignatureHasher.php',
|
'Symfony\\Component\\Security\\Core\\Signature\\SignatureHasher' => $vendorDir . '/symfony/security-core/Signature/SignatureHasher.php',
|
||||||
'Symfony\\Component\\Security\\Core\\Test\\AccessDecisionStrategyTestCase' => $vendorDir . '/symfony/security-core/Test/AccessDecisionStrategyTestCase.php',
|
|
||||||
'Symfony\\Component\\Security\\Core\\User\\AttributesBasedUserProviderInterface' => $vendorDir . '/symfony/security-core/User/AttributesBasedUserProviderInterface.php',
|
'Symfony\\Component\\Security\\Core\\User\\AttributesBasedUserProviderInterface' => $vendorDir . '/symfony/security-core/User/AttributesBasedUserProviderInterface.php',
|
||||||
'Symfony\\Component\\Security\\Core\\User\\ChainUserChecker' => $vendorDir . '/symfony/security-core/User/ChainUserChecker.php',
|
'Symfony\\Component\\Security\\Core\\User\\ChainUserChecker' => $vendorDir . '/symfony/security-core/User/ChainUserChecker.php',
|
||||||
'Symfony\\Component\\Security\\Core\\User\\ChainUserProvider' => $vendorDir . '/symfony/security-core/User/ChainUserProvider.php',
|
'Symfony\\Component\\Security\\Core\\User\\ChainUserProvider' => $vendorDir . '/symfony/security-core/User/ChainUserProvider.php',
|
||||||
|
|||||||
@@ -525,8 +525,10 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
|||||||
'Combodo\\iTop\\Application\\Search\\CriterionParser' => __DIR__ . '/../..' . '/sources/Application/Search/criterionparser.class.inc.php',
|
'Combodo\\iTop\\Application\\Search\\CriterionParser' => __DIR__ . '/../..' . '/sources/Application/Search/criterionparser.class.inc.php',
|
||||||
'Combodo\\iTop\\Application\\Search\\SearchForm' => __DIR__ . '/../..' . '/sources/Application/Search/searchform.class.inc.php',
|
'Combodo\\iTop\\Application\\Search\\SearchForm' => __DIR__ . '/../..' . '/sources/Application/Search/searchform.class.inc.php',
|
||||||
'Combodo\\iTop\\Application\\Status\\Status' => __DIR__ . '/../..' . '/sources/Application/Status/Status.php',
|
'Combodo\\iTop\\Application\\Status\\Status' => __DIR__ . '/../..' . '/sources/Application/Status/Status.php',
|
||||||
|
'Combodo\\iTop\\Application\\TwigBase\\Controller\\AbstractProfilerExtension' => __DIR__ . '/../..' . '/sources/Application/TwigBase/Controller/AbstractProfilerExtension.php',
|
||||||
'Combodo\\iTop\\Application\\TwigBase\\Controller\\Controller' => __DIR__ . '/../..' . '/sources/Application/TwigBase/Controller/Controller.php',
|
'Combodo\\iTop\\Application\\TwigBase\\Controller\\Controller' => __DIR__ . '/../..' . '/sources/Application/TwigBase/Controller/Controller.php',
|
||||||
'Combodo\\iTop\\Application\\TwigBase\\Controller\\PageNotFoundException' => __DIR__ . '/../..' . '/application/exceptions/PageNotFoundException.php',
|
'Combodo\\iTop\\Application\\TwigBase\\Controller\\PageNotFoundException' => __DIR__ . '/../..' . '/application/exceptions/PageNotFoundException.php',
|
||||||
|
'Combodo\\iTop\\Application\\TwigBase\\Controller\\iProfilerExtension' => __DIR__ . '/../..' . '/sources/Application/TwigBase/Controller/iProfilerExtension.php',
|
||||||
'Combodo\\iTop\\Application\\TwigBase\\Twig\\Extension' => __DIR__ . '/../..' . '/sources/Application/TwigBase/Twig/Extension.php',
|
'Combodo\\iTop\\Application\\TwigBase\\Twig\\Extension' => __DIR__ . '/../..' . '/sources/Application/TwigBase/Twig/Extension.php',
|
||||||
'Combodo\\iTop\\Application\\TwigBase\\Twig\\TwigHelper' => __DIR__ . '/../..' . '/sources/Application/TwigBase/Twig/TwigHelper.php',
|
'Combodo\\iTop\\Application\\TwigBase\\Twig\\TwigHelper' => __DIR__ . '/../..' . '/sources/Application/TwigBase/Twig/TwigHelper.php',
|
||||||
'Combodo\\iTop\\Application\\TwigBase\\UI\\UIBlockExtension' => __DIR__ . '/../..' . '/sources/Application/TwigBase/UI/UIBlockExtension.php',
|
'Combodo\\iTop\\Application\\TwigBase\\UI\\UIBlockExtension' => __DIR__ . '/../..' . '/sources/Application/TwigBase/UI/UIBlockExtension.php',
|
||||||
@@ -2793,13 +2795,6 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
|||||||
'Symfony\\Component\\Form\\SubmitButton' => __DIR__ . '/..' . '/symfony/form/SubmitButton.php',
|
'Symfony\\Component\\Form\\SubmitButton' => __DIR__ . '/..' . '/symfony/form/SubmitButton.php',
|
||||||
'Symfony\\Component\\Form\\SubmitButtonBuilder' => __DIR__ . '/..' . '/symfony/form/SubmitButtonBuilder.php',
|
'Symfony\\Component\\Form\\SubmitButtonBuilder' => __DIR__ . '/..' . '/symfony/form/SubmitButtonBuilder.php',
|
||||||
'Symfony\\Component\\Form\\SubmitButtonTypeInterface' => __DIR__ . '/..' . '/symfony/form/SubmitButtonTypeInterface.php',
|
'Symfony\\Component\\Form\\SubmitButtonTypeInterface' => __DIR__ . '/..' . '/symfony/form/SubmitButtonTypeInterface.php',
|
||||||
'Symfony\\Component\\Form\\Test\\FormBuilderInterface' => __DIR__ . '/..' . '/symfony/form/Test/FormBuilderInterface.php',
|
|
||||||
'Symfony\\Component\\Form\\Test\\FormIntegrationTestCase' => __DIR__ . '/..' . '/symfony/form/Test/FormIntegrationTestCase.php',
|
|
||||||
'Symfony\\Component\\Form\\Test\\FormInterface' => __DIR__ . '/..' . '/symfony/form/Test/FormInterface.php',
|
|
||||||
'Symfony\\Component\\Form\\Test\\FormPerformanceTestCase' => __DIR__ . '/..' . '/symfony/form/Test/FormPerformanceTestCase.php',
|
|
||||||
'Symfony\\Component\\Form\\Test\\Traits\\RunTestTrait' => __DIR__ . '/..' . '/symfony/form/Test/Traits/RunTestTrait.php',
|
|
||||||
'Symfony\\Component\\Form\\Test\\Traits\\ValidatorExtensionTrait' => __DIR__ . '/..' . '/symfony/form/Test/Traits/ValidatorExtensionTrait.php',
|
|
||||||
'Symfony\\Component\\Form\\Test\\TypeTestCase' => __DIR__ . '/..' . '/symfony/form/Test/TypeTestCase.php',
|
|
||||||
'Symfony\\Component\\Form\\Util\\FormUtil' => __DIR__ . '/..' . '/symfony/form/Util/FormUtil.php',
|
'Symfony\\Component\\Form\\Util\\FormUtil' => __DIR__ . '/..' . '/symfony/form/Util/FormUtil.php',
|
||||||
'Symfony\\Component\\Form\\Util\\InheritDataAwareIterator' => __DIR__ . '/..' . '/symfony/form/Util/InheritDataAwareIterator.php',
|
'Symfony\\Component\\Form\\Util\\InheritDataAwareIterator' => __DIR__ . '/..' . '/symfony/form/Util/InheritDataAwareIterator.php',
|
||||||
'Symfony\\Component\\Form\\Util\\OptionsResolverWrapper' => __DIR__ . '/..' . '/symfony/form/Util/OptionsResolverWrapper.php',
|
'Symfony\\Component\\Form\\Util\\OptionsResolverWrapper' => __DIR__ . '/..' . '/symfony/form/Util/OptionsResolverWrapper.php',
|
||||||
@@ -3412,7 +3407,6 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
|||||||
'Symfony\\Component\\Security\\Core\\Signature\\Exception\\InvalidSignatureException' => __DIR__ . '/..' . '/symfony/security-core/Signature/Exception/InvalidSignatureException.php',
|
'Symfony\\Component\\Security\\Core\\Signature\\Exception\\InvalidSignatureException' => __DIR__ . '/..' . '/symfony/security-core/Signature/Exception/InvalidSignatureException.php',
|
||||||
'Symfony\\Component\\Security\\Core\\Signature\\ExpiredSignatureStorage' => __DIR__ . '/..' . '/symfony/security-core/Signature/ExpiredSignatureStorage.php',
|
'Symfony\\Component\\Security\\Core\\Signature\\ExpiredSignatureStorage' => __DIR__ . '/..' . '/symfony/security-core/Signature/ExpiredSignatureStorage.php',
|
||||||
'Symfony\\Component\\Security\\Core\\Signature\\SignatureHasher' => __DIR__ . '/..' . '/symfony/security-core/Signature/SignatureHasher.php',
|
'Symfony\\Component\\Security\\Core\\Signature\\SignatureHasher' => __DIR__ . '/..' . '/symfony/security-core/Signature/SignatureHasher.php',
|
||||||
'Symfony\\Component\\Security\\Core\\Test\\AccessDecisionStrategyTestCase' => __DIR__ . '/..' . '/symfony/security-core/Test/AccessDecisionStrategyTestCase.php',
|
|
||||||
'Symfony\\Component\\Security\\Core\\User\\AttributesBasedUserProviderInterface' => __DIR__ . '/..' . '/symfony/security-core/User/AttributesBasedUserProviderInterface.php',
|
'Symfony\\Component\\Security\\Core\\User\\AttributesBasedUserProviderInterface' => __DIR__ . '/..' . '/symfony/security-core/User/AttributesBasedUserProviderInterface.php',
|
||||||
'Symfony\\Component\\Security\\Core\\User\\ChainUserChecker' => __DIR__ . '/..' . '/symfony/security-core/User/ChainUserChecker.php',
|
'Symfony\\Component\\Security\\Core\\User\\ChainUserChecker' => __DIR__ . '/..' . '/symfony/security-core/User/ChainUserChecker.php',
|
||||||
'Symfony\\Component\\Security\\Core\\User\\ChainUserProvider' => __DIR__ . '/..' . '/symfony/security-core/User/ChainUserProvider.php',
|
'Symfony\\Component\\Security\\Core\\User\\ChainUserProvider' => __DIR__ . '/..' . '/symfony/security-core/User/ChainUserProvider.php',
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* @copyright Copyright (C) 2010-2025 Combodo SARL
|
||||||
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Combodo\iTop\Application\TwigBase\Controller;
|
||||||
|
|
||||||
|
|
||||||
|
abstract class AbstractProfilerExtension implements iProfilerExtension
|
||||||
|
{
|
||||||
|
public function Init()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract function GetTemplatesPath(): null|string|array;
|
||||||
|
|
||||||
|
public abstract function IsEnabled(): bool;
|
||||||
|
|
||||||
|
public abstract function GetDebugTemplate(): string;
|
||||||
|
|
||||||
|
public abstract function GetDebugParams(array $aParams): array;
|
||||||
|
|
||||||
|
public function GetLinkedScripts(): ?array
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetLinkedStylesheets(): ?array
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetSaas(): null|array
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,6 +26,7 @@ use Combodo\iTop\Application\WebPage\ErrorPage;
|
|||||||
use Combodo\iTop\Application\WebPage\iTopWebPage;
|
use Combodo\iTop\Application\WebPage\iTopWebPage;
|
||||||
use Combodo\iTop\Application\WebPage\WebPage;
|
use Combodo\iTop\Application\WebPage\WebPage;
|
||||||
use Combodo\iTop\Controller\AbstractController;
|
use Combodo\iTop\Controller\AbstractController;
|
||||||
|
use Combodo\iTop\Service\InterfaceDiscovery\InterfaceDiscovery;
|
||||||
use Dict;
|
use Dict;
|
||||||
use Exception;
|
use Exception;
|
||||||
use ExecutionKPI;
|
use ExecutionKPI;
|
||||||
@@ -47,7 +48,6 @@ use Symfony\Component\Form\FormRenderer;
|
|||||||
use Symfony\Component\Form\Forms;
|
use Symfony\Component\Form\Forms;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\Security\Csrf\CsrfTokenManager;
|
use Symfony\Component\Security\Csrf\CsrfTokenManager;
|
||||||
use Twig\Error\Error;
|
|
||||||
use Twig\Error\SyntaxError;
|
use Twig\Error\SyntaxError;
|
||||||
use Twig\RuntimeLoader\FactoryRuntimeLoader;
|
use Twig\RuntimeLoader\FactoryRuntimeLoader;
|
||||||
use utils;
|
use utils;
|
||||||
@@ -61,38 +61,38 @@ abstract class Controller extends AbstractController
|
|||||||
const ENUM_PAGE_TYPE_SETUP = 'setup';
|
const ENUM_PAGE_TYPE_SETUP = 'setup';
|
||||||
|
|
||||||
/** @var \Twig\Environment */
|
/** @var \Twig\Environment */
|
||||||
private $m_oTwig;
|
private $oTwig;
|
||||||
/** @var string */
|
/** @var string */
|
||||||
protected $m_sOperation;
|
protected $m_sOperation;
|
||||||
/** @var string */
|
/** @var string */
|
||||||
private $m_sModule;
|
private $m_sModule;
|
||||||
/** @var iTopWebPage|AjaxPage */
|
/** @var iTopWebPage|AjaxPage */
|
||||||
private $m_oPage;
|
private $oPage;
|
||||||
/** @var bool */
|
/** @var bool */
|
||||||
private $m_bCheckDemoMode = false;
|
private $bCheckDemoMode = false;
|
||||||
/** @var bool */
|
/** @var bool */
|
||||||
private $m_bMustBeAdmin = false;
|
private $bMustBeAdmin = false;
|
||||||
/** @var string */
|
/** @var string */
|
||||||
private $m_sMenuId = null;
|
private $sMenuId = null;
|
||||||
/** @var string */
|
/** @var string */
|
||||||
private $m_sDefaultOperation = 'Default';
|
private $sDefaultOperation = 'Default';
|
||||||
private $m_aDefaultParams;
|
private $aDefaultParams;
|
||||||
private $m_aLinkedScripts;
|
private $aLinkedScripts;
|
||||||
private $m_aLinkedStylesheets;
|
private $aLinkedStylesheets;
|
||||||
private $m_aSaas;
|
private $aSaas;
|
||||||
private $m_aAjaxTabs;
|
private $aAjaxTabs;
|
||||||
/** parameters for page's blocks
|
/** parameters for page's blocks
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
private $m_aBlockParams;
|
private $aBlockParams;
|
||||||
/** @var string */
|
/** @var string */
|
||||||
private $m_sAccessTokenConfigParamId = null;
|
private $sAccessTokenConfigParamId = null;
|
||||||
/** @var boolean false to disable breadcrumb */
|
/** @var boolean false to disable breadcrumb */
|
||||||
private $m_bIsBreadCrumbEnabled = true;
|
private $bIsBreadCrumbEnabled = true;
|
||||||
/** @var array contains same parameters as {@see iTopWebPage::SetBreadCrumbEntry()} */
|
/** @var array contains same parameters as {@see iTopWebPage::SetBreadCrumbEntry()} */
|
||||||
private $m_aBreadCrumbEntry = [];
|
private $aBreadCrumbEntry = [];
|
||||||
|
|
||||||
/** @var Request Request (from Symfony http_foundation component @link https://symfony.com/doc/current/components/http_foundation.html) */
|
/** @var Request Request (from Symfony http_foundation component @link https://symfony.com/doc/current/components/http_foundation.html) */
|
||||||
private Request $oRequest;
|
private Request $oRequest;
|
||||||
@@ -111,16 +111,17 @@ abstract class Controller extends AbstractController
|
|||||||
*/
|
*/
|
||||||
public function __construct($sViewPath = '', $sModuleName = 'core', $aAdditionalPaths = [])
|
public function __construct($sViewPath = '', $sModuleName = 'core', $aAdditionalPaths = [])
|
||||||
{
|
{
|
||||||
$this->m_aLinkedScripts = [];
|
$this->aLinkedScripts = [];
|
||||||
$this->m_aLinkedStylesheets = [];
|
$this->aLinkedStylesheets = [];
|
||||||
$this->m_aSaas = [];
|
$this->aSaas = [];
|
||||||
$this->m_aAjaxTabs = [];
|
$this->aAjaxTabs = [];
|
||||||
$this->m_aDefaultParams = [];
|
$this->aDefaultParams = [];
|
||||||
$this->m_aBlockParams = [];
|
$this->aBlockParams = [];
|
||||||
$this->SetModuleName($sModuleName);
|
$this->SetModuleName($sModuleName);
|
||||||
|
|
||||||
// Initialize Symfony components
|
// Initialize Symfony components
|
||||||
$this->InitSymfonyComponents($sViewPath, $sModuleName);
|
$this->InitSymfonyComponents($sViewPath, $sModuleName);
|
||||||
|
$this->InitDebugExtensions();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -136,11 +137,27 @@ abstract class Controller extends AbstractController
|
|||||||
// Twig environment
|
// Twig environment
|
||||||
$aAdditionalPaths[] = APPROOT.'lib/symfony/twig-bridge/Resources/views/Form';
|
$aAdditionalPaths[] = APPROOT.'lib/symfony/twig-bridge/Resources/views/Form';
|
||||||
$aAdditionalPaths[] = APPROOT.'templates';
|
$aAdditionalPaths[] = APPROOT.'templates';
|
||||||
|
foreach (InterfaceDiscovery::GetInstance()->FindItopClasses(iProfilerExtension::class) as $sExtension) {
|
||||||
|
/** @var \Combodo\iTop\Application\TwigBase\Controller\iProfilerExtension $oExtensionInstance */
|
||||||
|
$oExtensionInstance = $sExtension::GetInstance();
|
||||||
|
$path = $oExtensionInstance->GetTemplatesPath();
|
||||||
|
if (is_string($path)) {
|
||||||
|
if (!in_array($path, $aAdditionalPaths)) {
|
||||||
|
$aAdditionalPaths[] = $path;
|
||||||
|
}
|
||||||
|
} else if (is_array($path)) {
|
||||||
|
foreach ($path as $sPath) {
|
||||||
|
if (!in_array($sPath, $aAdditionalPaths)) {
|
||||||
|
$aAdditionalPaths[] = $sPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (strlen($sViewPath) > 0) {
|
if (strlen($sViewPath) > 0) {
|
||||||
$this->SetViewPath($sViewPath, $aAdditionalPaths);
|
$this->SetViewPath($sViewPath, $aAdditionalPaths);
|
||||||
if ($sModuleName != 'core') {
|
if ($sModuleName != 'core') {
|
||||||
try {
|
try {
|
||||||
$this->m_aDefaultParams = ['sIndexURL' => utils::GetAbsoluteUrlModulePage($this->m_sModule, 'index.php')];
|
$this->aDefaultParams = ['sIndexURL' => utils::GetAbsoluteUrlModulePage($this->m_sModule, 'index.php')];
|
||||||
}
|
}
|
||||||
catch (Exception $e) {
|
catch (Exception $e) {
|
||||||
IssueLog::Error($e->getMessage());
|
IssueLog::Error($e->getMessage());
|
||||||
@@ -170,7 +187,7 @@ abstract class Controller extends AbstractController
|
|||||||
$this->SetViewPath($sModulePath.'/view');
|
$this->SetViewPath($sModulePath.'/view');
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
$this->m_aDefaultParams = array('sIndexURL' => utils::GetAbsoluteUrlModulePage($this->m_sModule, 'index.php'));
|
$this->aDefaultParams = array('sIndexURL' => utils::GetAbsoluteUrlModulePage($this->m_sModule, 'index.php'));
|
||||||
}
|
}
|
||||||
catch (Exception $e)
|
catch (Exception $e)
|
||||||
{
|
{
|
||||||
@@ -194,7 +211,7 @@ abstract class Controller extends AbstractController
|
|||||||
},
|
},
|
||||||
]));
|
]));
|
||||||
$oTwig->addExtension(new FormExtension());
|
$oTwig->addExtension(new FormExtension());
|
||||||
$this->m_oTwig = $oTwig;
|
$this->oTwig = $oTwig;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -226,10 +243,7 @@ abstract class Controller extends AbstractController
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
$this->CheckAccess();
|
$this->CheckAccess();
|
||||||
$this->m_sOperation = utils::ReadParam('operation', $this->m_sDefaultOperation);
|
$this->m_sOperation = utils::ReadParam('operation', $this->sDefaultOperation);
|
||||||
|
|
||||||
$oKPI = new ExecutionKPI();
|
|
||||||
$oKPI->ComputeAndReport('Starting operation '.$this->m_sOperation);
|
|
||||||
|
|
||||||
if ($this->CallOperation(utils::ToCamelCase($this->m_sOperation))) {
|
if ($this->CallOperation(utils::ToCamelCase($this->m_sOperation))) {
|
||||||
return;
|
return;
|
||||||
@@ -264,7 +278,7 @@ abstract class Controller extends AbstractController
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
$this->CheckAccess();
|
$this->CheckAccess();
|
||||||
$this->m_sOperation = utils::ReadParam('operation', $this->m_sDefaultOperation);
|
$this->m_sOperation = utils::ReadParam('operation', $this->sDefaultOperation);
|
||||||
|
|
||||||
if ($this->CallOperation(utils::ToCamelCase($this->m_sOperation))) {
|
if ($this->CallOperation(utils::ToCamelCase($this->m_sOperation))) {
|
||||||
return;
|
return;
|
||||||
@@ -320,41 +334,41 @@ abstract class Controller extends AbstractController
|
|||||||
*/
|
*/
|
||||||
protected function CheckAccess()
|
protected function CheckAccess()
|
||||||
{
|
{
|
||||||
if ($this->m_bCheckDemoMode && MetaModel::GetConfig()->Get('demo_mode'))
|
if ($this->bCheckDemoMode && MetaModel::GetConfig()->Get('demo_mode'))
|
||||||
{
|
{
|
||||||
throw new Exception("Sorry, iTop is in <b>demonstration mode</b>: this feature is disabled.");
|
throw new Exception("Sorry, iTop is in <b>demonstration mode</b>: this feature is disabled.");
|
||||||
}
|
}
|
||||||
|
|
||||||
$sExecModule = utils::ReadParam('exec_module', "");
|
$sExecModule = utils::ReadParam('exec_module', "");
|
||||||
|
|
||||||
$sConfiguredAccessTokenValue = empty($this->m_sAccessTokenConfigParamId) ? "" : trim(MetaModel::GetConfig()->GetModuleSetting($sExecModule, $this->m_sAccessTokenConfigParamId));
|
$sConfiguredAccessTokenValue = empty($this->sAccessTokenConfigParamId) ? "" : trim(MetaModel::GetConfig()->GetModuleSetting($sExecModule, $this->sAccessTokenConfigParamId));
|
||||||
|
|
||||||
if (empty($sExecModule) || empty($sConfiguredAccessTokenValue)){
|
if (empty($sExecModule) || empty($sConfiguredAccessTokenValue)){
|
||||||
LoginWebPage::DoLogin($this->m_bMustBeAdmin);
|
LoginWebPage::DoLogin($this->bMustBeAdmin);
|
||||||
} else {
|
} else {
|
||||||
//token mode without login required
|
//token mode without login required
|
||||||
//N°7147 - Error HTTP 500 due to access_token not URL decoded
|
//N°7147 - Error HTTP 500 due to access_token not URL decoded
|
||||||
$sPassedToken = utils::ReadPostedParam($this->m_sAccessTokenConfigParamId, null, false, 'raw_data');
|
$sPassedToken = utils::ReadPostedParam($this->sAccessTokenConfigParamId, null, false, 'raw_data');
|
||||||
if (is_null($sPassedToken)){
|
if (is_null($sPassedToken)){
|
||||||
$sPassedToken = utils::ReadParam($this->m_sAccessTokenConfigParamId, null, false, 'raw_data');
|
$sPassedToken = utils::ReadParam($this->sAccessTokenConfigParamId, null, false, 'raw_data');
|
||||||
}
|
}
|
||||||
|
|
||||||
$sDecodedPassedToken = urldecode($sPassedToken);
|
$sDecodedPassedToken = urldecode($sPassedToken);
|
||||||
if ($sDecodedPassedToken !== $sConfiguredAccessTokenValue){
|
if ($sDecodedPassedToken !== $sConfiguredAccessTokenValue){
|
||||||
$sMsg = "Invalid token passed under '$this->m_sAccessTokenConfigParamId' http param to reach '$sExecModule' page.";
|
$sMsg = "Invalid token passed under '$this->sAccessTokenConfigParamId' http param to reach '$sExecModule' page.";
|
||||||
IssueLog::Error($sMsg, null,
|
IssueLog::Error($sMsg, null,
|
||||||
[
|
[
|
||||||
'sHtmlDecodedToken' => $sDecodedPassedToken,
|
'sHtmlDecodedToken' => $sDecodedPassedToken,
|
||||||
'conf param ID' => $this->m_sAccessTokenConfigParamId
|
'conf param ID' => $this->sAccessTokenConfigParamId
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
throw new Exception("Invalid token");
|
throw new Exception("Invalid token");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($this->m_sMenuId))
|
if (!empty($this->sMenuId))
|
||||||
{
|
{
|
||||||
ApplicationMenu::CheckMenuIdEnabled($this->m_sMenuId);
|
ApplicationMenu::CheckMenuIdEnabled($this->sMenuId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -364,7 +378,7 @@ abstract class Controller extends AbstractController
|
|||||||
*/
|
*/
|
||||||
private function GetDefaultParameters()
|
private function GetDefaultParameters()
|
||||||
{
|
{
|
||||||
return $this->m_aDefaultParams;
|
return $this->aDefaultParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -374,7 +388,7 @@ abstract class Controller extends AbstractController
|
|||||||
*/
|
*/
|
||||||
public function DisableInDemoMode()
|
public function DisableInDemoMode()
|
||||||
{
|
{
|
||||||
$this->m_bCheckDemoMode = true;
|
$this->bCheckDemoMode = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -384,7 +398,7 @@ abstract class Controller extends AbstractController
|
|||||||
*/
|
*/
|
||||||
public function AllowOnlyAdmin()
|
public function AllowOnlyAdmin()
|
||||||
{
|
{
|
||||||
$this->m_bMustBeAdmin = true;
|
$this->bMustBeAdmin = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -406,7 +420,7 @@ abstract class Controller extends AbstractController
|
|||||||
*/
|
*/
|
||||||
public function SetAccessTokenConfigParamId(string $m_sAccessTokenConfigParamId): void
|
public function SetAccessTokenConfigParamId(string $m_sAccessTokenConfigParamId): void
|
||||||
{
|
{
|
||||||
$this->m_sAccessTokenConfigParamId = trim($m_sAccessTokenConfigParamId) ?? "";
|
$this->sAccessTokenConfigParamId = trim($m_sAccessTokenConfigParamId) ?? "";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -418,7 +432,7 @@ abstract class Controller extends AbstractController
|
|||||||
*/
|
*/
|
||||||
public function SetMenuId($sMenuId)
|
public function SetMenuId($sMenuId)
|
||||||
{
|
{
|
||||||
$this->m_sMenuId = $sMenuId;
|
$this->sMenuId = $sMenuId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -430,7 +444,7 @@ abstract class Controller extends AbstractController
|
|||||||
*/
|
*/
|
||||||
public function SetDefaultOperation($sDefaultOperation)
|
public function SetDefaultOperation($sDefaultOperation)
|
||||||
{
|
{
|
||||||
$this->m_sDefaultOperation = $sDefaultOperation;
|
$this->sDefaultOperation = $sDefaultOperation;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -481,42 +495,49 @@ abstract class Controller extends AbstractController
|
|||||||
}
|
}
|
||||||
$aParams = array_merge($this->GetDefaultParameters(), $aParams);
|
$aParams = array_merge($this->GetDefaultParameters(), $aParams);
|
||||||
$this->CreatePage($sPageType);
|
$this->CreatePage($sPageType);
|
||||||
$sHTMLContent = $this->RenderTemplate($aParams, $sTemplateName, 'html');
|
$sHTMLContent = $this->RenderTemplate($aParams, $sTemplateName, 'html', $sErrorMsg);
|
||||||
if ($sHTMLContent !== false) {
|
if ($sHTMLContent !== false) {
|
||||||
$this->AddToPage($sHTMLContent);
|
$this->AddToPage($sHTMLContent);
|
||||||
}
|
}
|
||||||
$sJSScript = $this->RenderTemplate($aParams, $sTemplateName, 'js');
|
$sJSScript = $this->RenderTemplate($aParams, $sTemplateName, 'js', $sErrorMsg);
|
||||||
if ($sJSScript !== false) {
|
if ($sJSScript !== false) {
|
||||||
$this->AddScriptToPage($sJSScript);
|
$this->AddScriptToPage($sJSScript);
|
||||||
}
|
}
|
||||||
$sReadyScript = $this->RenderTemplate($aParams, $sTemplateName, 'ready.js');
|
$sReadyScript = $this->RenderTemplate($aParams, $sTemplateName, 'ready.js', $sErrorMsg);
|
||||||
if ($sReadyScript !== false) {
|
if ($sReadyScript !== false) {
|
||||||
$this->AddReadyScriptToPage($sReadyScript);
|
$this->AddReadyScriptToPage($sReadyScript);
|
||||||
}
|
}
|
||||||
$sStyle = $this->RenderTemplate($aParams, $sTemplateName, 'css');
|
$sStyle = $this->RenderTemplate($aParams, $sTemplateName, 'css', $sErrorMsg);
|
||||||
if ($sStyle !== false) {
|
if ($sStyle !== false) {
|
||||||
$this->AddStyleToPage($sStyle);
|
$this->AddStyleToPage($sStyle);
|
||||||
}
|
}
|
||||||
if ($sHTMLContent === false && $sJSScript === false && $sReadyScript === false && $sStyle === false) {
|
if ($sHTMLContent === false && $sJSScript === false && $sReadyScript === false && $sStyle === false) {
|
||||||
IssueLog::Error("Missing TWIG template for $sTemplateName");
|
if (utils::IsNullOrEmptyString($sErrorMsg)) {
|
||||||
|
$sErrorMsg = "Missing TWIG template for $sTemplateName";
|
||||||
|
}
|
||||||
|
IssueLog::Error($sErrorMsg);
|
||||||
|
$this->AddToPage($this->oTwig->render('application/forms/itop_error.html.twig', ['sControllerError' => $sErrorMsg]));
|
||||||
}
|
}
|
||||||
if (!empty($this->m_aAjaxTabs)) {
|
|
||||||
$this->m_oPage->AddTabContainer('TwigBaseTabContainer');
|
$this->ManageDebugExtensions($aParams);
|
||||||
$this->m_oPage->SetCurrentTabContainer('TwigBaseTabContainer');
|
|
||||||
|
if (!empty($this->aAjaxTabs)) {
|
||||||
|
$this->oPage->AddTabContainer('TwigBaseTabContainer');
|
||||||
|
$this->oPage->SetCurrentTabContainer('TwigBaseTabContainer');
|
||||||
}
|
}
|
||||||
foreach ($this->m_aAjaxTabs as $sTabCode => $aTabData) {
|
foreach ($this->aAjaxTabs as $sTabCode => $aTabData) {
|
||||||
$this->AddAjaxTabToPage($sTabCode, $aTabData['label'], $aTabData['url'], $aTabData['cache']);
|
$this->AddAjaxTabToPage($sTabCode, $aTabData['label'], $aTabData['url'], $aTabData['cache']);
|
||||||
}
|
}
|
||||||
foreach ($this->m_aLinkedScripts as $sLinkedScript) {
|
foreach ($this->aLinkedScripts as $sLinkedScript) {
|
||||||
$this->AddLinkedScriptToPage($sLinkedScript);
|
$this->AddLinkedScriptToPage($sLinkedScript);
|
||||||
}
|
}
|
||||||
foreach ($this->m_aLinkedStylesheets as $sLinkedStylesheet) {
|
foreach ($this->aLinkedStylesheets as $sLinkedStylesheet) {
|
||||||
$this->AddLinkedStylesheetToPage($sLinkedStylesheet);
|
$this->AddLinkedStylesheetToPage($sLinkedStylesheet);
|
||||||
}
|
}
|
||||||
foreach ($this->m_aSaas as $sSaasRelPath) {
|
foreach ($this->aSaas as $sSaasRelPath) {
|
||||||
$this->AddSaasToPage($sSaasRelPath);
|
$this->AddSaasToPage($sSaasRelPath);
|
||||||
}
|
}
|
||||||
foreach ($this->m_aBlockParams as $sKey => $value) {
|
foreach ($this->aBlockParams as $sKey => $value) {
|
||||||
$this->SetBlockParamToPage($sKey, $value);
|
$this->SetBlockParamToPage($sKey, $value);
|
||||||
}
|
}
|
||||||
$this->OutputPage();
|
$this->OutputPage();
|
||||||
@@ -646,7 +667,7 @@ abstract class Controller extends AbstractController
|
|||||||
*/
|
*/
|
||||||
public function AddLinkedScript($sScript)
|
public function AddLinkedScript($sScript)
|
||||||
{
|
{
|
||||||
$this->m_aLinkedScripts[] = $sScript;
|
$this->aLinkedScripts[] = $sScript;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -659,7 +680,7 @@ abstract class Controller extends AbstractController
|
|||||||
*/
|
*/
|
||||||
public function AddLinkedStylesheet($sStylesheet)
|
public function AddLinkedStylesheet($sStylesheet)
|
||||||
{
|
{
|
||||||
$this->m_aLinkedStylesheets[] = $sStylesheet;
|
$this->aLinkedStylesheets[] = $sStylesheet;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -671,7 +692,7 @@ abstract class Controller extends AbstractController
|
|||||||
*/
|
*/
|
||||||
public function AddSaas($sSaasRelPath)
|
public function AddSaas($sSaasRelPath)
|
||||||
{
|
{
|
||||||
$this->m_aSaas[] = $sSaasRelPath;
|
$this->aSaas[] = $sSaasRelPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -690,7 +711,7 @@ abstract class Controller extends AbstractController
|
|||||||
if (is_null($sLabel)) {
|
if (is_null($sLabel)) {
|
||||||
$sLabel = Dict::S($sCode);
|
$sLabel = Dict::S($sCode);
|
||||||
}
|
}
|
||||||
$this->m_aAjaxTabs[$sCode] = array('label' => $sLabel, 'url' => $sURL, 'cache' => $bCache);
|
$this->aAjaxTabs[$sCode] = array('label' => $sLabel, 'url' => $sURL, 'cache' => $bCache);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -699,7 +720,7 @@ abstract class Controller extends AbstractController
|
|||||||
*/
|
*/
|
||||||
public function SetBlockParams(array $aBlockParams)
|
public function SetBlockParams(array $aBlockParams)
|
||||||
{
|
{
|
||||||
$this->m_aBlockParams = $aBlockParams;
|
$this->aBlockParams = $aBlockParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -707,7 +728,7 @@ abstract class Controller extends AbstractController
|
|||||||
* @see Controller::SetBreadCrumbEntry() to set breadcrumb content (by default will be title)
|
* @see Controller::SetBreadCrumbEntry() to set breadcrumb content (by default will be title)
|
||||||
*/
|
*/
|
||||||
public function DisableBreadCrumb() {
|
public function DisableBreadCrumb() {
|
||||||
$this->m_bIsBreadCrumbEnabled = false;
|
$this->bIsBreadCrumbEnabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -715,7 +736,7 @@ abstract class Controller extends AbstractController
|
|||||||
* @see iTopWebPage::SetBreadCrumbEntry()
|
* @see iTopWebPage::SetBreadCrumbEntry()
|
||||||
*/
|
*/
|
||||||
public function SetBreadCrumbEntry($sId, $sLabel, $sDescription, $sUrl = '', $sIcon = '') {
|
public function SetBreadCrumbEntry($sId, $sLabel, $sDescription, $sUrl = '', $sIcon = '') {
|
||||||
$this->m_aBreadCrumbEntry = [$sId, $sLabel, $sDescription, $sUrl, $sIcon];
|
$this->aBreadCrumbEntry = [$sId, $sLabel, $sDescription, $sUrl, $sIcon];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetRequest(): Request
|
public function GetRequest(): Request
|
||||||
@@ -764,67 +785,79 @@ abstract class Controller extends AbstractController
|
|||||||
* @return string|false
|
* @return string|false
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
private function RenderTemplate($aParams, $sName, $sTemplateFileExtension)
|
private function RenderTemplate(array $aParams, string $sName, string $sTemplateFileExtension, string &$sErrorMsg = null): string|false
|
||||||
{
|
{
|
||||||
if (empty($this->m_oTwig))
|
$sTemplateFile = $sName.'.'.$sTemplateFileExtension.'.twig';
|
||||||
|
if (empty($this->oTwig))
|
||||||
{
|
{
|
||||||
throw new Exception('Not initialized. Call Controller::InitFromModule() or Controller::SetViewPath() before any display');
|
throw new Exception('Not initialized. Call Controller::InitFromModule() or Controller::SetViewPath() before any display');
|
||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return $this->m_oTwig->render($sName.'.'.$sTemplateFileExtension.'.twig', $aParams);
|
return $this->oTwig->render($sTemplateFile, $aParams);
|
||||||
}
|
}
|
||||||
catch (SyntaxError $e) {
|
catch (SyntaxError $e) {
|
||||||
IssueLog::Error($e->getMessage().' - file: '.$e->getFile().'('.$e->getLine().')');
|
IssueLog::Error($e->getMessage().' - file: '.$e->getFile().'('.$e->getLine().')');
|
||||||
|
return $this->oTwig->render('application/forms/itop_error.html.twig', ['sControllerError' => $e->getMessage()]);
|
||||||
}
|
}
|
||||||
catch (Error $e) {
|
catch (Exception $e) {
|
||||||
if (strpos($e->getMessage(), 'Unable to find template') === false)
|
$sExceptionMessage = $e->getMessage();
|
||||||
{
|
if (str_contains($sExceptionMessage, 'at line')) {
|
||||||
IssueLog::Error($e->getMessage());
|
IssueLog::Error($sExceptionMessage);
|
||||||
|
return $this->oTwig->render('application/forms/itop_error.html.twig', ['sControllerError' => $sExceptionMessage]);
|
||||||
}
|
}
|
||||||
|
if (!str_contains($sExceptionMessage, 'Unable to find template'))
|
||||||
|
{
|
||||||
|
IssueLog::Error($sExceptionMessage);
|
||||||
|
}
|
||||||
|
if (is_null($sErrorMsg)) {
|
||||||
|
$sErrorMsg = '';
|
||||||
|
}
|
||||||
|
$sErrorMsg .= $sExceptionMessage."\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $sPageType
|
* @param string $sPageType
|
||||||
*
|
*
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
private function CreatePage($sPageType)
|
private function CreatePage(string $sPageType): void
|
||||||
{
|
{
|
||||||
switch ($sPageType)
|
switch ($sPageType)
|
||||||
{
|
{
|
||||||
case self::ENUM_PAGE_TYPE_HTML:
|
case self::ENUM_PAGE_TYPE_HTML:
|
||||||
$this->m_oPage = new iTopWebPage($this->GetOperationTitle(), false);
|
$this->oPage = new iTopWebPage($this->GetOperationTitle(), false);
|
||||||
$this->m_oPage->add_http_headers();
|
$this->oPage->add_http_headers();
|
||||||
|
|
||||||
if ($this->m_bIsBreadCrumbEnabled) {
|
if ($this->bIsBreadCrumbEnabled) {
|
||||||
if (count($this->m_aBreadCrumbEntry) > 0) {
|
if (count($this->aBreadCrumbEntry) > 0) {
|
||||||
list($sId, $sTitle, $sDescription, $sUrl, $sIcon) = $this->m_aBreadCrumbEntry;
|
list($sId, $sTitle, $sDescription, $sUrl, $sIcon) = $this->aBreadCrumbEntry;
|
||||||
$this->m_oPage->SetBreadCrumbEntry($sId, $sTitle, $sDescription, $sUrl, $sIcon);
|
$this->oPage->SetBreadCrumbEntry($sId, $sTitle, $sDescription, $sUrl, $sIcon);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$this->m_oPage->DisableBreadCrumb();
|
$this->oPage->DisableBreadCrumb();
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case self::ENUM_PAGE_TYPE_BASIC_HTML:
|
case self::ENUM_PAGE_TYPE_BASIC_HTML:
|
||||||
$this->m_oPage = new WebPage($this->GetOperationTitle());
|
$this->oPage = new WebPage($this->GetOperationTitle());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case self::ENUM_PAGE_TYPE_AJAX:
|
case self::ENUM_PAGE_TYPE_AJAX:
|
||||||
$this->m_oPage = new AjaxPage($this->GetOperationTitle());
|
$this->oPage = new AjaxPage($this->GetOperationTitle());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case self::ENUM_PAGE_TYPE_SETUP:
|
case self::ENUM_PAGE_TYPE_SETUP:
|
||||||
$this->m_oPage = new SetupPage($this->GetOperationTitle());
|
$this->oPage = new SetupPage($this->GetOperationTitle());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
$this->m_oTwig->addGlobal('UIBlockParent', [$this->m_oPage]);
|
$this->oTwig->addGlobal('UIBlockParent', [$this->oPage]);
|
||||||
$this->m_oTwig->addGlobal('oPage', $this->m_oPage);
|
$this->oTwig->addGlobal('oPage', $this->oPage);
|
||||||
|
$this->oTwig->addGlobal('debug', utils::IsDevelopmentEnvironment());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -853,42 +886,42 @@ abstract class Controller extends AbstractController
|
|||||||
*/
|
*/
|
||||||
private function AddToPage($sContent)
|
private function AddToPage($sContent)
|
||||||
{
|
{
|
||||||
$this->m_oPage->add($sContent);
|
$this->oPage->add($sContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function AddReadyScriptToPage($sScript)
|
private function AddReadyScriptToPage($sScript)
|
||||||
{
|
{
|
||||||
$this->m_oPage->add_ready_script($sScript);
|
$this->oPage->add_ready_script($sScript);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function AddScriptToPage($sScript)
|
private function AddScriptToPage($sScript)
|
||||||
{
|
{
|
||||||
$this->m_oPage->add_script($sScript);
|
$this->oPage->add_script($sScript);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function AddLinkedScriptToPage($sLinkedScript)
|
private function AddLinkedScriptToPage($sLinkedScript)
|
||||||
{
|
{
|
||||||
$this->m_oPage->LinkScriptFromURI($sLinkedScript);
|
$this->oPage->LinkScriptFromURI($sLinkedScript);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function AddLinkedStylesheetToPage($sLinkedStylesheet)
|
private function AddLinkedStylesheetToPage($sLinkedStylesheet)
|
||||||
{
|
{
|
||||||
$this->m_oPage->LinkStylesheetFromURI($sLinkedStylesheet);
|
$this->oPage->LinkStylesheetFromURI($sLinkedStylesheet);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function AddStyleToPage($sStyle)
|
private function AddStyleToPage($sStyle)
|
||||||
{
|
{
|
||||||
$this->m_oPage->add_style($sStyle);
|
$this->oPage->add_style($sStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function AddSaasToPage($sSaasRelPath)
|
private function AddSaasToPage($sSaasRelPath)
|
||||||
{
|
{
|
||||||
$this->m_oPage->add_saas($sSaasRelPath);
|
$this->oPage->add_saas($sSaasRelPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function AddAjaxTabToPage($sCode, $sTitle, $sURL, $bCache)
|
private function AddAjaxTabToPage($sCode, $sTitle, $sURL, $bCache)
|
||||||
{
|
{
|
||||||
$this->m_oPage->AddAjaxTab($sCode, $sURL, $bCache, $sTitle);
|
$this->oPage->AddAjaxTab($sCode, $sURL, $bCache, $sTitle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -898,7 +931,7 @@ abstract class Controller extends AbstractController
|
|||||||
*/
|
*/
|
||||||
private function SetBlockParamToPage(string $sKey, $value)
|
private function SetBlockParamToPage(string $sKey, $value)
|
||||||
{
|
{
|
||||||
$this->m_oPage->SetBlockParam($sKey, $value);
|
$this->oPage->SetBlockParam($sKey, $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -906,6 +939,49 @@ abstract class Controller extends AbstractController
|
|||||||
*/
|
*/
|
||||||
private function OutputPage()
|
private function OutputPage()
|
||||||
{
|
{
|
||||||
$this->m_oPage->output();
|
$this->oPage->output();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function InitDebugExtensions()
|
||||||
|
{
|
||||||
|
foreach (InterfaceDiscovery::GetInstance()->FindItopClasses(iProfilerExtension::class) as $sExtension) {
|
||||||
|
/** @var \Combodo\iTop\Application\TwigBase\Controller\iProfilerExtension $oExtensionInstance */
|
||||||
|
$oExtensionInstance = $sExtension::GetInstance();
|
||||||
|
$oExtensionInstance->Init();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $aParams
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @throws \ReflectionException
|
||||||
|
* @throws \Twig\Error\LoaderError
|
||||||
|
* @throws \Twig\Error\RuntimeError
|
||||||
|
* @throws \Twig\Error\SyntaxError
|
||||||
|
*/
|
||||||
|
private function ManageDebugExtensions(array $aParams): void
|
||||||
|
{
|
||||||
|
foreach (InterfaceDiscovery::GetInstance()->FindItopClasses(iProfilerExtension::class) as $sExtension) {
|
||||||
|
/** @var \Combodo\iTop\Application\TwigBase\Controller\iProfilerExtension $oExtensionInstance */
|
||||||
|
$oExtensionInstance = $sExtension::GetInstance();
|
||||||
|
if ($oExtensionInstance->IsEnabled()) {
|
||||||
|
$sDebugTemplate = $oExtensionInstance->GetDebugTemplate();
|
||||||
|
$aDebugParams = $oExtensionInstance->GetDebugParams($aParams);
|
||||||
|
$aLinkedScripts = $oExtensionInstance->GetLinkedScripts();
|
||||||
|
if (is_array($aLinkedScripts)) {
|
||||||
|
$this->aLinkedScripts = array_merge($this->aLinkedScripts, $aLinkedScripts);
|
||||||
|
}
|
||||||
|
$aLinkedStylesheets = $oExtensionInstance->GetLinkedStylesheets();
|
||||||
|
if (is_array($aLinkedStylesheets)) {
|
||||||
|
$this->aLinkedStylesheets = array_merge($this->aLinkedStylesheets, $aLinkedStylesheets);
|
||||||
|
}
|
||||||
|
$aSaas = $oExtensionInstance->GetSaas();
|
||||||
|
if (is_array($aSaas)) {
|
||||||
|
$this->aSaas = array_merge($this->aSaas, $aSaas);
|
||||||
|
}
|
||||||
|
$this->AddToPage($this->oTwig->render($sDebugTemplate, $aDebugParams));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* @copyright Copyright (C) 2010-2025 Combodo SARL
|
||||||
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Combodo\iTop\Application\TwigBase\Controller;
|
||||||
|
|
||||||
|
interface iProfilerExtension
|
||||||
|
{
|
||||||
|
public static function GetInstance(): iProfilerExtension;
|
||||||
|
public function Init();
|
||||||
|
public function IsEnabled(): bool;
|
||||||
|
public function GetTemplatesPath(): null|string|array;
|
||||||
|
public function GetDebugTemplate(): string;
|
||||||
|
public function GetDebugParams(array $aParams): array;
|
||||||
|
public function GetLinkedScripts(): null|array;
|
||||||
|
public function GetLinkedStylesheets(): null|array;
|
||||||
|
public function GetSaas(): null|array;
|
||||||
|
}
|
||||||
@@ -32,6 +32,8 @@ class KpiLogData
|
|||||||
public $iPeakMemory;
|
public $iPeakMemory;
|
||||||
/** @var array */
|
/** @var array */
|
||||||
public $aData;
|
public $aData;
|
||||||
|
// Computed
|
||||||
|
public float $fDuration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $sType
|
* @param string $sType
|
||||||
@@ -56,6 +58,7 @@ class KpiLogData
|
|||||||
$this->iCurrentMemory = $iCurrentMemory;
|
$this->iCurrentMemory = $iCurrentMemory;
|
||||||
$this->iPeakMemory = $iPeakMemory;
|
$this->iPeakMemory = $iPeakMemory;
|
||||||
$this->aData = $aData;
|
$this->aData = $aData;
|
||||||
|
$this->fDuration = sprintf('%01.4f', $this->fStopTime - $this->fStartTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -74,12 +77,11 @@ class KpiLogData
|
|||||||
*/
|
*/
|
||||||
public function GetCSV()
|
public function GetCSV()
|
||||||
{
|
{
|
||||||
$fDuration = sprintf('%01.4f', $this->fStopTime - $this->fStartTime);
|
|
||||||
$sType = $this->RemoveQuotes($this->sType);
|
$sType = $this->RemoveQuotes($this->sType);
|
||||||
$sOperation = $this->RemoveQuotes($this->sOperation);
|
$sOperation = $this->RemoveQuotes($this->sOperation);
|
||||||
$sArguments = $this->RemoveQuotes($this->sArguments);
|
$sArguments = $this->RemoveQuotes($this->sArguments);
|
||||||
$sExtension = $this->RemoveQuotes($this->sExtension);
|
$sExtension = $this->RemoveQuotes($this->sExtension);
|
||||||
return "\"$sType\",\"$sOperation\",\"$sArguments\",$this->fStartTime,$this->fStopTime,$fDuration,\"$sExtension\",$this->iInitialMemory,$this->iCurrentMemory,$this->iPeakMemory";
|
return "\"$sType\",\"$sOperation\",\"$sArguments\",$this->fStartTime,$this->fStopTime,$this->fDuration,\"$sExtension\",$this->iInitialMemory,$this->iCurrentMemory,$this->iPeakMemory";
|
||||||
}
|
}
|
||||||
|
|
||||||
private function RemoveQuotes(string $sEntry): string
|
private function RemoveQuotes(string $sEntry): string
|
||||||
|
|||||||
6
templates/application/forms/itop_error.html.twig
Normal file
6
templates/application/forms/itop_error.html.twig
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{# @copyright Copyright (C) 2010-2025 Combodo SARL #}
|
||||||
|
{# @license http://opensource.org/licenses/AGPL-3.0 #}
|
||||||
|
|
||||||
|
{% if sControllerError %}
|
||||||
|
{% UIAlert ForDanger { sTitle:'UI:Error:TwigController'|dict_s, sContent:sControllerError } %}{% EndUIAlert %}
|
||||||
|
{% endif %}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
{% include "base/components/input/inputlabel.html.twig" %}
|
{% include "base/components/input/inputlabel.html.twig" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<select id="{{ oUIBlock.GetId() }}" name="{{ oUIBlock.GetName() }}"
|
<select id="{{ oUIBlock.GetId() }}" name="{{ oUIBlock.GetName() }}"
|
||||||
{% if oUIBlock.GetSubmitOnChange() %} onChange="this.form.trigger('submit');" {% endif %}
|
{% if oUIBlock.GetSubmitOnChange() %} onChange="$(this).parents('form:first').trigger('submit');" {% endif %}
|
||||||
{% if oUIBlock.IsMultiple() %} multiple {% endif %}
|
{% if oUIBlock.IsMultiple() %} multiple {% endif %}
|
||||||
class="{% if oUIBlock.IsHidden() %}ibo-is-hidden{% endif %}{% if oUIBlock.GetAdditionalCSSClassesAsString() %} {{ oUIBlock.GetAdditionalCSSClassesAsString() }}{% endif %}"
|
class="{% if oUIBlock.IsHidden() %}ibo-is-hidden{% endif %}{% if oUIBlock.GetAdditionalCSSClassesAsString() %} {{ oUIBlock.GetAdditionalCSSClassesAsString() }}{% endif %}"
|
||||||
{% if oUIBlock.GetDataAttributes() %}
|
{% if oUIBlock.GetDataAttributes() %}
|
||||||
|
|||||||
Reference in New Issue
Block a user