From 06dbdcb5cd855e66eaca0405b677f8fb1f5e0fd7 Mon Sep 17 00:00:00 2001 From: Eric Espie Date: Wed, 29 Oct 2025 16:52:19 +0100 Subject: [PATCH] =?UTF-8?q?N=C2=B08772=20-=20Turbo=20WIP?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TwigBase/Controller/Controller.php | 108 ++++++++---------- sources/Application/WebPage/iTopWebPage.php | 4 +- .../application/forms/itop_debug.html.twig | 6 +- .../forms/itop_debug_update.html.twig | 2 +- 4 files changed, 55 insertions(+), 65 deletions(-) diff --git a/sources/Application/TwigBase/Controller/Controller.php b/sources/Application/TwigBase/Controller/Controller.php index 1a08df324..40b6347ee 100644 --- a/sources/Application/TwigBase/Controller/Controller.php +++ b/sources/Application/TwigBase/Controller/Controller.php @@ -56,11 +56,11 @@ use ZipArchive; abstract class Controller extends AbstractController { - const ENUM_PAGE_TYPE_HTML = 'html'; - const ENUM_PAGE_TYPE_BASIC_HTML = 'basic_html'; - const ENUM_PAGE_TYPE_AJAX = 'ajax'; + const ENUM_PAGE_TYPE_HTML = 'html'; + const ENUM_PAGE_TYPE_BASIC_HTML = 'basic_html'; + const ENUM_PAGE_TYPE_AJAX = 'ajax'; const ENUM_PAGE_TYPE_TURBO_FORM_AJAX = 'turbo_ajax'; - const ENUM_PAGE_TYPE_SETUP = 'setup'; + const ENUM_PAGE_TYPE_SETUP = 'setup'; /** @var \Twig\Environment */ private $oTwig; @@ -190,12 +190,10 @@ abstract class Controller extends AbstractController $sModulePath = dirname(dirname($this->GetDir())); $this->SetModuleName(basename($sModulePath)); $this->SetViewPath($sModulePath.'/view'); - try - { + try { $this->aDefaultParams = array('sIndexURL' => utils::GetAbsoluteUrlModulePage($this->m_sModule, 'index.php')); } - catch (Exception $e) - { + catch (Exception $e) { IssueLog::Error($e->getMessage()); } } @@ -245,8 +243,7 @@ abstract class Controller extends AbstractController */ public function HandleOperation() { - try - { + try { $this->CheckAccess(); $this->m_sOperation = utils::ReadParam('operation', $this->sDefaultOperation); @@ -261,8 +258,7 @@ abstract class Controller extends AbstractController $this->DisplayBadRequest(); } - catch (Exception $e) - { + catch (Exception $e) { http_response_code(500); $oP = new ErrorPage(Dict::S('UI:PageTitle:FatalError')); $oP->add("

".Dict::S('UI:FatalErrorMessage')."

\n"); @@ -280,8 +276,7 @@ abstract class Controller extends AbstractController */ public function HandleAjaxOperation() { - try - { + try { $this->CheckAccess(); $this->m_sOperation = utils::ReadParam('operation', $this->sDefaultOperation); @@ -296,8 +291,7 @@ abstract class Controller extends AbstractController $this->DisplayPageNotFound(); } - catch (Exception $e) - { + catch (Exception $e) { http_response_code(500); $aResponse = array('sError' => $e->getMessage()); echo json_encode($aResponse); @@ -312,6 +306,7 @@ abstract class Controller extends AbstractController } $this->$sMethodName(); + return true; } @@ -334,13 +329,12 @@ abstract class Controller extends AbstractController } /** - * @since 3.0.0 N°3606 - Adapt TwigBase Controller for combodo-monitoring extension * @throws \Exception + * @since 3.0.0 N°3606 - Adapt TwigBase Controller for combodo-monitoring extension */ protected function CheckAccess() { - if ($this->bCheckDemoMode && MetaModel::GetConfig()->Get('demo_mode')) - { + if ($this->bCheckDemoMode && MetaModel::GetConfig()->Get('demo_mode')) { throw new Exception("Sorry, iTop is in demonstration mode: this feature is disabled."); } @@ -348,31 +342,30 @@ abstract class Controller extends AbstractController $sConfiguredAccessTokenValue = empty($this->sAccessTokenConfigParamId) ? "" : trim(MetaModel::GetConfig()->GetModuleSetting($sExecModule, $this->sAccessTokenConfigParamId)); - if (empty($sExecModule) || empty($sConfiguredAccessTokenValue)){ + if (empty($sExecModule) || empty($sConfiguredAccessTokenValue)) { LoginWebPage::DoLogin($this->bMustBeAdmin); } else { //token mode without login required //N°7147 - Error HTTP 500 due to access_token not URL decoded $sPassedToken = utils::ReadPostedParam($this->sAccessTokenConfigParamId, null, false, 'raw_data'); - if (is_null($sPassedToken)){ + if (is_null($sPassedToken)) { $sPassedToken = utils::ReadParam($this->sAccessTokenConfigParamId, null, false, 'raw_data'); } $sDecodedPassedToken = urldecode($sPassedToken); - if ($sDecodedPassedToken !== $sConfiguredAccessTokenValue){ + if ($sDecodedPassedToken !== $sConfiguredAccessTokenValue) { $sMsg = "Invalid token passed under '$this->sAccessTokenConfigParamId' http param to reach '$sExecModule' page."; IssueLog::Error($sMsg, null, [ 'sHtmlDecodedToken' => $sDecodedPassedToken, - 'conf param ID' => $this->sAccessTokenConfigParamId, + 'conf param ID' => $this->sAccessTokenConfigParamId, ] ); throw new Exception("Invalid token"); } } - if (!empty($this->sMenuId)) - { + if (!empty($this->sMenuId)) { ApplicationMenu::CheckMenuIdEnabled($this->sMenuId); } } @@ -482,7 +475,7 @@ abstract class Controller extends AbstractController $this->DisplayPage($aParams, $sTemplateName, 'setup'); } - public function DisplayTurboAjaxPage ($aParams = array(), $sTemplateName = 'turbo-ajax-update.html.twig') + public function DisplayTurboAjaxPage($aParams = array(), $sTemplateName = 'turbo-ajax-update.html.twig') { $this->DisplayPage($aParams, $sTemplateName, self::ENUM_PAGE_TYPE_TURBO_FORM_AJAX); } @@ -498,7 +491,7 @@ abstract class Controller extends AbstractController * * @throws \Exception */ - public function DisplayPage($aParams = array(), $sTemplateName = null, $sPageType = 'html') + public function DisplayPage($aParams = array(), $sTemplateName = null, $sPageType = self::ENUM_PAGE_TYPE_HTML) { if (empty($sTemplateName)) { $sTemplateName = $this->m_sOperation; @@ -569,8 +562,7 @@ abstract class Controller extends AbstractController $oKpi = new ExecutionKPI(); http_response_code($iResponseCode); header('Content-Type: application/json'); - foreach ($aHeaders as $sHeader) - { + foreach ($aHeaders as $sHeader) { header($sHeader); } $sJSON = json_encode($aParams); @@ -623,16 +615,13 @@ abstract class Controller extends AbstractController $sArchiveFileFullPath = tempnam(SetupUtils::GetTmpDir(), 'itop_download-').'.zip'; $oArchive = new ZipArchive(); $oArchive->open($sArchiveFileFullPath, ZipArchive::CREATE); - foreach ($aFiles as $sFile) - { + foreach ($aFiles as $sFile) { $oArchive->addFile($sFile, basename($sFile)); } $oArchive->close(); - if ($bUnlinkFiles) - { - foreach ($aFiles as $sFile) - { + if ($bUnlinkFiles) { + foreach ($aFiles as $sFile) { unlink($sFile); } } @@ -645,8 +634,7 @@ abstract class Controller extends AbstractController $sFileMimeType = utils::GetFileMimeType($sFilePath); header('Content-Type: '.$sFileMimeType); - if ($bFileTransfer) - { + if ($bFileTransfer) { header('Content-Disposition: attachment; filename="'.$sDownloadArchiveName.'"'); } @@ -662,8 +650,7 @@ abstract class Controller extends AbstractController readfile($sFilePath); - if ($bRemoveFile) - { + if ($bRemoveFile) { unlink($sFilePath); } exit(0); @@ -675,6 +662,7 @@ abstract class Controller extends AbstractController * @api * * @param string $sScript Script path to link + * * @since 3.2.0 $sScript must be absolute URI */ public function AddLinkedScript($sScript) @@ -688,6 +676,7 @@ abstract class Controller extends AbstractController * @api * * @param string $sStylesheet Stylesheet path to link + * * @since 3.2.0 $sScript must be absolute URI */ public function AddLinkedStylesheet($sStylesheet) @@ -710,13 +699,13 @@ abstract class Controller extends AbstractController /** * Add an AJAX tab to the current page * - * @param string $sCode Code of the tab + * @api + * * @param string $sURL URL to call when the tab is activated * @param bool $bCache If true, cache the result for the current web page * @param string $sLabel Label of the tab (if null the code is translated) * - * @api - * + * @param string $sCode Code of the tab */ public function AddAjaxTab($sCode, $sURL, $bCache = true, $sLabel = null) { @@ -728,6 +717,7 @@ abstract class Controller extends AbstractController /** * @param array $aBlockParams + * * @since 3.0.0 */ public function SetBlockParams(array $aBlockParams) @@ -747,18 +737,20 @@ abstract class Controller extends AbstractController } /** - * @since 2.7.7 3.0.1 3.1.0 N°4760 method creation * @see Controller::SetBreadCrumbEntry() to set breadcrumb content (by default will be title) + * @since 2.7.7 3.0.1 3.1.0 N°4760 method creation */ - public function DisableBreadCrumb() { + public function DisableBreadCrumb() + { $this->bIsBreadCrumbEnabled = false; } /** - * @since 2.7.7 3.0.1 3.1.0 N°4760 method creation * @see iTopWebPage::SetBreadCrumbEntry() + * @since 2.7.7 3.0.1 3.1.0 N°4760 method creation */ - public function SetBreadCrumbEntry($sId, $sLabel, $sDescription, $sUrl = '', $sIcon = '') { + public function SetBreadCrumbEntry($sId, $sLabel, $sDescription, $sUrl = '', $sIcon = '') + { $this->aBreadCrumbEntry = [$sId, $sLabel, $sDescription, $sUrl, $sIcon]; } @@ -779,7 +771,7 @@ abstract class Controller extends AbstractController */ public function GetFormBuilder(AbstractFormBlock $oFormBlock, mixed $data = null): FormBuilderInterface { - return $this->oFormFactoryBuilder->getFormFactory()->createNamedBuilder($oFormBlock->GetName(), $oFormBlock->GetFormType(), $data,$oFormBlock->GetOptions()); + return $this->oFormFactoryBuilder->getFormFactory()->createNamedBuilder($oFormBlock->GetName(), $oFormBlock->GetFormType(), $data, $oFormBlock->GetOptions()); } /** @@ -797,7 +789,8 @@ abstract class Controller extends AbstractController if (is_null($data)) { $data = $type::GetDefaultData(); } - return $this->GetFormBuilder($type, $data,$options)->getForm(); + + return $this->GetFormBuilder($type, $data, $options)->getForm(); } /** @@ -811,26 +804,25 @@ abstract class Controller extends AbstractController private function RenderTemplate(array $aParams, string $sName, string $sTemplateFileExtension, string &$sErrorMsg = null): string|false { $sTemplateFile = $sName.'.'.$sTemplateFileExtension.'.twig'; - if (empty($this->oTwig)) - { + if (empty($this->oTwig)) { throw new Exception('Not initialized. Call Controller::InitFromModule() or Controller::SetViewPath() before any display'); } - try - { + try { return $this->oTwig->render($sTemplateFile, $aParams); } catch (SyntaxError $e) { IssueLog::Error($e->getMessage().' - file: '.$e->getFile().'('.$e->getLine().')'); + return $this->oTwig->render('application/forms/itop_error.html.twig', ['sControllerError' => $e->getMessage()]); } catch (Exception $e) { $sExceptionMessage = $e->getMessage(); if (str_contains($sExceptionMessage, 'at line')) { IssueLog::Error($sExceptionMessage); + return $this->oTwig->render('application/forms/itop_error.html.twig', ['sControllerError' => $sExceptionMessage]); } - if (!str_contains($sExceptionMessage, 'Unable to find template')) - { + if (!str_contains($sExceptionMessage, 'Unable to find template')) { IssueLog::Error($sExceptionMessage); } if (is_null($sErrorMsg)) { @@ -849,8 +841,7 @@ abstract class Controller extends AbstractController */ private function CreatePage(string $sPageType): void { - switch ($sPageType) - { + switch ($sPageType) { case self::ENUM_PAGE_TYPE_HTML: $this->oPage = new iTopWebPage($this->GetOperationTitle(), false); $this->oPage->add_http_headers(); @@ -885,7 +876,7 @@ abstract class Controller extends AbstractController } $this->oTwig->addGlobal('UIBlockParent', [$this->oPage]); $this->oTwig->addGlobal('oPage', $this->oPage); - $this->oTwig->addGlobal('debug', utils::IsDevelopmentEnvironment()); + //$this->oTwig->addGlobal('debug', utils::IsDevelopmentEnvironment()); } /** @@ -959,11 +950,10 @@ abstract class Controller extends AbstractController } } - - /** * @param string $sKey * @param $value + * * @since 3.0.0 */ private function SetBlockParamToPage(string $sKey, $value) diff --git a/sources/Application/WebPage/iTopWebPage.php b/sources/Application/WebPage/iTopWebPage.php index a3c738fae..5692ff562 100644 --- a/sources/Application/WebPage/iTopWebPage.php +++ b/sources/Application/WebPage/iTopWebPage.php @@ -33,11 +33,9 @@ use Combodo\iTop\Renderer\Console\ConsoleBlockRenderer; use ContextTag; use DateTimeFormat; use DBSearch; -use DeprecatedCallsLog; use Dict; use ExecutionKPI; use InlineImage; -use iPageUIBlockExtension; use MetaModel; use UserRights; use utils; @@ -756,7 +754,7 @@ HTML; } } - // Render HTKL content + // Render HTML content $sHtml = $this->RenderContent(); // Echo global HTML diff --git a/templates/application/forms/itop_debug.html.twig b/templates/application/forms/itop_debug.html.twig index df7755e7a..8de1a923b 100644 --- a/templates/application/forms/itop_debug.html.twig +++ b/templates/application/forms/itop_debug.html.twig @@ -1,6 +1,8 @@ {# @copyright Copyright (C) 2010-2025 Combodo SARL #} {# @license http://opensource.org/licenses/AGPL-3.0 #} -
+ +
{{ sProfilerContent|raw }} -
\ No newline at end of file +
+ \ No newline at end of file diff --git a/templates/application/forms/itop_debug_update.html.twig b/templates/application/forms/itop_debug_update.html.twig index 3c3a928fe..5aceb8a0f 100644 --- a/templates/application/forms/itop_debug_update.html.twig +++ b/templates/application/forms/itop_debug_update.html.twig @@ -1,7 +1,7 @@ {# @copyright Copyright (C) 2010-2025 Combodo SARL #} {# @license http://opensource.org/licenses/AGPL-3.0 #} - +