From 344cce9fdde45788b61e1b58b48540975f7c1bb0 Mon Sep 17 00:00:00 2001 From: Eric Date: Mon, 26 Jul 2021 17:20:22 +0200 Subject: [PATCH] =?UTF-8?q?N=C2=B04076=20-=20Allow=20block=20parameters=20?= =?UTF-8?q?to=20change=20the=20behaviour=20of=20blocks=20on=20the=20page?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/UI.php | 19 ++----- .../TwigBase/Controller/Controller.php | 44 ++++++++++----- .../Component/GlobalSearch/GlobalSearch.php | 4 +- .../UI/Base/Layout/TopBar/TopBarFactory.php | 10 ++-- sources/application/WebPage/AjaxPage.php | 26 +++++---- sources/application/WebPage/NiceWebPage.php | 2 +- sources/application/WebPage/WebPage.php | 56 ++++++++++++++----- sources/application/WebPage/iTopWebPage.php | 38 +++++++++---- .../application/WebPage/iTopWizardWebPage.php | 1 - .../components/global-search/layout.html.twig | 2 +- .../components/global-search/layout.js.twig | 1 - 11 files changed, 126 insertions(+), 77 deletions(-) diff --git a/pages/UI.php b/pages/UI.php index e76923ca4..236776133 100644 --- a/pages/UI.php +++ b/pages/UI.php @@ -547,31 +547,24 @@ try // Save search to history // - Prepare icon $sQueryIconUrl = null; - if(!empty($sClassName)) - { + if(!empty($sClassName)) { $sQueryIconUrl = MetaModel::GetClassIcon($sClassName, false); } // - Prepare label $sQueryLabel = null; - if($sQuery !== $sFullText) - { + if ($sQuery !== $sFullText) { $sQueryLabel = $sFullText; } GlobalSearchHelper::AddQueryToHistory($sQuery, $sQueryIconUrl, $sQueryLabel); - $oP->GetTopBarLayout() - ->GetGlobalSearch() - ->SetQuery($sQuery) - ->SetLastQueries(GlobalSearchHelper::GetLastQueries()); + $oP->AddBlockParam('global_search.query', $sQuery); // Check the needle length $iMinLenth = MetaModel::GetConfig()->Get('full_text_needle_min'); - foreach ($aFullTextNeedles as $sNeedle) - { - if (strlen($sNeedle) < $iMinLenth) - { + foreach ($aFullTextNeedles as $sNeedle) { + if (strlen($sNeedle) < $iMinLenth) { $oP->p(Dict::Format('UI:Search:NeedleTooShort', $sNeedle, $iMinLenth)); $key = array_search($sNeedle, $aFullTextNeedles); - if($key!== false) + if ($key !== false) { unset($aFullTextNeedles[$key]); } diff --git a/sources/application/TwigBase/Controller/Controller.php b/sources/application/TwigBase/Controller/Controller.php index 353f4dcc5..f21da5fdf 100644 --- a/sources/application/TwigBase/Controller/Controller.php +++ b/sources/application/TwigBase/Controller/Controller.php @@ -65,6 +65,7 @@ abstract class Controller private $m_aLinkedStylesheets; private $m_aSaas; private $m_aAjaxTabs; + private $m_aBlockParams; /** @var string */ private $m_sAccessTokenConfigParamId = null; @@ -76,21 +77,19 @@ abstract class Controller */ public function __construct($sViewPath, $sModuleName = 'core') { - $this->m_aLinkedScripts = array(); - $this->m_aLinkedStylesheets = array(); - $this->m_aSaas = array(); - $this->m_aAjaxTabs = array(); - $this->m_aDefaultParams = array(); + $this->m_aLinkedScripts = []; + $this->m_aLinkedStylesheets = []; + $this->m_aSaas = []; + $this->m_aAjaxTabs = []; + $this->m_aDefaultParams = []; + $this->m_aBlockParams = []; $this->SetViewPath($sViewPath); $this->SetModuleName($sModuleName); - if ($sModuleName != 'core') - { - try - { - $this->m_aDefaultParams = array('sIndexURL' => utils::GetAbsoluteUrlModulePage($this->m_sModule, 'index.php')); + if ($sModuleName != 'core') { + try { + $this->m_aDefaultParams = ['sIndexURL' => utils::GetAbsoluteUrlModulePage($this->m_sModule, 'index.php')]; } - catch (Exception $e) - { + catch (Exception $e) { IssueLog::Error($e->getMessage()); } } @@ -392,6 +391,9 @@ abstract class Controller foreach ($this->m_aSaas as $sSaasRelPath) { $this->AddSaasToPage($sSaasRelPath); } + foreach ($this->m_aBlockParams as $sKey => $value) { + $this->SetBlockParamToPage($sKey, $value); + } $this->OutputPage(); } @@ -550,13 +552,20 @@ abstract class Controller */ public function AddAjaxTab($sCode, $sURL, $bCache = true, $sLabel = null) { - if (is_null($sLabel)) - { + if (is_null($sLabel)) { $sLabel = Dict::S($sCode); } $this->m_aAjaxTabs[$sCode] = array('label' => $sLabel, 'url' => $sURL, 'cache' => $bCache); } + /** + * @param array $aBlockParams + */ + public function AddBlockParams(array $aBlockParams) + { + $this->m_aBlockParams = $aBlockParams; + } + /** * @param $aParams * @param $sName @@ -595,7 +604,7 @@ abstract class Controller switch ($sPageType) { case self::ENUM_PAGE_TYPE_HTML: - $this->m_oPage = new iTopWebPage($this->GetOperationTitle()); + $this->m_oPage = new iTopWebPage($this->GetOperationTitle(), false); $this->m_oPage->add_xframe_options(); break; @@ -679,6 +688,11 @@ abstract class Controller $this->m_oPage->AddAjaxTab($sCode, $sURL, $bCache, $sTitle); } + public function SetBlockParamToPage(string $sKey, $value) + { + $this->m_oPage->SetBlockParam($sKey, $value); + } + /** * @throws \Exception */ diff --git a/sources/application/UI/Base/Component/GlobalSearch/GlobalSearch.php b/sources/application/UI/Base/Component/GlobalSearch/GlobalSearch.php index b6445e808..ad244f8c6 100644 --- a/sources/application/UI/Base/Component/GlobalSearch/GlobalSearch.php +++ b/sources/application/UI/Base/Component/GlobalSearch/GlobalSearch.php @@ -70,8 +70,8 @@ class GlobalSearch extends UIBlock implements iKeyboardShortcut $this->SetEndpoint(static::DEFAULT_ENDPOINT_REL_URL); $this->SetQuery(''); $this->SetLastQueries($aLastQueries); - $this->bShowHistory = (bool) MetaModel::GetConfig()->Get('global_search.show_history'); - $this->iMaxHistoryResults = (int) MetaModel::GetConfig()->Get('global_search.max_history_results'); + $this->bShowHistory = (bool)MetaModel::GetConfig()->Get('global_search.show_history'); + $this->iMaxHistoryResults = (int)MetaModel::GetConfig()->Get('global_search.max_history_results'); } /** diff --git a/sources/application/UI/Base/Layout/TopBar/TopBarFactory.php b/sources/application/UI/Base/Layout/TopBar/TopBarFactory.php index 1ac0ced57..b71211cc5 100644 --- a/sources/application/UI/Base/Layout/TopBar/TopBarFactory.php +++ b/sources/application/UI/Base/Layout/TopBar/TopBarFactory.php @@ -41,6 +41,7 @@ class TopBarFactory * @param array|null $aBreadcrumbsEntry Current breadcrumbs entry to add * * @return \Combodo\iTop\Application\UI\Base\Layout\TopBar\TopBar + * @throws \ConfigException * @throws \CoreException * @throws \CoreUnexpectedValue * @throws \MySQLException @@ -49,18 +50,15 @@ class TopBarFactory { $oTopBar = new TopBar(TopBar::BLOCK_CODE); - if (utils::GetConfig()->Get('quick_create.enabled') === true) - { + if (utils::GetConfig()->Get('quick_create.enabled') === true) { $oTopBar->SetQuickCreate(QuickCreateFactory::MakeFromUserHistory()); } - if (utils::GetConfig()->Get('global_search.enabled') === true) - { + if (utils::GetConfig()->Get('global_search.enabled') === true) { $oTopBar->SetGlobalSearch(GlobalSearchFactory::MakeFromUserHistory()); } - if(utils::GetConfig()->Get('breadcrumb.enabled') === true) - { + if (utils::GetConfig()->Get('breadcrumb.enabled') === true) { $oBreadcrumbs = new Breadcrumbs($aBreadcrumbsEntry, Breadcrumbs::BLOCK_CODE); $oTopBar->SetBreadcrumbs($oBreadcrumbs); diff --git a/sources/application/WebPage/AjaxPage.php b/sources/application/WebPage/AjaxPage.php index 0d4ed1ca7..4a75c9b0b 100644 --- a/sources/application/WebPage/AjaxPage.php +++ b/sources/application/WebPage/AjaxPage.php @@ -177,25 +177,27 @@ class AjaxPage extends WebPage implements iTabbedPage $aData['aPage'] = [ 'sAbsoluteUrlAppRoot' => addslashes(utils::GetAbsoluteUrlAppRoot()), - 'sTitle' => $this->s_title, - 'aMetadata' => [ + 'sTitle' => $this->s_title, + 'aMetadata' => [ 'sCharset' => static::PAGES_CHARSET, 'sLang' => $this->GetLanguageForMetadata(), ], - 'aCssFiles' => $this->a_linked_stylesheets, - 'aCssInline' => $this->a_styles, - 'aJsFiles' => $this->a_linked_scripts, - 'aJsInlineLive' => $this->a_scripts, + 'aCssFiles' => $this->a_linked_stylesheets, + 'aCssInline' => $this->a_styles, + 'aJsFiles' => $this->a_linked_scripts, + 'aJsInlineLive' => $this->a_scripts, 'aJsInlineOnDomReady' => $this->GetReadyScripts(), - 'aJsInlineOnInit' => $this->a_init_scripts, - 'bEscapeContent' => ($this->sContentType == 'text/html') && ($this->sContentDisposition == 'inline'), + 'aJsInlineOnInit' => $this->a_init_scripts, + 'bEscapeContent' => ($this->sContentType == 'text/html') && ($this->sContentDisposition == 'inline'), // TODO 3.0.0: TEMP, used while developping, remove it. - 'sSanitizedContent' => utils::FilterXSS($this->s_content), - 'sDeferredContent' => utils::FilterXSS(addslashes(str_replace("\n", '', $this->s_deferred_content))), - 'sCapturedOutput' => utils::FilterXSS($s_captured_output), - 'sPromiseId' => $this->sPromiseId + 'sSanitizedContent' => utils::FilterXSS($this->s_content), + 'sDeferredContent' => utils::FilterXSS(addslashes(str_replace("\n", '', $this->s_deferred_content))), + 'sCapturedOutput' => utils::FilterXSS($s_captured_output), + 'sPromiseId' => $this->sPromiseId, ]; + $aData['aBlockParams'] = $this->GetBlockParams(); + $oTwigEnv = TwigHelper::GetTwigEnvironment(BlockRenderer::TWIG_BASE_PATH, BlockRenderer::TWIG_ADDITIONAL_PATHS); // Render final TWIG into global HTML $oKpi = new ExecutionKPI(); diff --git a/sources/application/WebPage/NiceWebPage.php b/sources/application/WebPage/NiceWebPage.php index b44a74db1..c6bdc988b 100644 --- a/sources/application/WebPage/NiceWebPage.php +++ b/sources/application/WebPage/NiceWebPage.php @@ -30,7 +30,7 @@ class NiceWebPage extends WebPage $this->m_sRootUrl = $this->GetAbsoluteUrlAppRoot(); parent::__construct($s_title, $bPrintable); - $this->LoadTheme(); + $this->LoadTheme(); } /** diff --git a/sources/application/WebPage/WebPage.php b/sources/application/WebPage/WebPage.php index 23e651438..92af6176a 100644 --- a/sources/application/WebPage/WebPage.php +++ b/sources/application/WebPage/WebPage.php @@ -99,6 +99,8 @@ class WebPage implements Page protected $a_styles; /** @var array Stylesheets linked (external) to the page through URIs */ protected $a_linked_stylesheets; + /** @var array Parameters to be used by page blocks */ + protected $aBlockParams; protected $a_headers; protected $a_base; protected $iNextId; @@ -133,7 +135,7 @@ class WebPage implements Page * @param string $s_title * @param bool $bPrintable */ - public function __construct($s_title, $bPrintable = false) + public function __construct(string $s_title, bool $bPrintable = false) { $this->s_title = $s_title; $this->s_content = ""; @@ -146,8 +148,8 @@ class WebPage implements Page $this->InitializeDictEntries(); $this->InitializeStyles(); $this->InitializeLinkedStylesheets(); - $this->a_headers = array(); - $this->a_base = array('href' => '', 'target' => ''); + $this->a_headers = []; + $this->a_base = ['href' => '', 'target' => '']; $this->iNextId = 0; $this->iTransactionId = 0; $this->sContentType = ''; @@ -155,7 +157,8 @@ class WebPage implements Page $this->sContentFileName = ''; $this->bTrashUnexpectedOutput = false; $this->s_OutputFormat = utils::ReadParam('output_format', 'html'); - $this->a_OutputOptions = array(); + $this->a_OutputOptions = []; + $this->aBlockParams = []; $this->bHasCollapsibleSection = false; $this->bPrintable = $bPrintable; $this->bAddJSDict = true; @@ -1168,24 +1171,26 @@ JS; // Base structure of data to pass to the TWIG template $aData['aPage'] = [ 'sAbsoluteUrlAppRoot' => addslashes(utils::GetAbsoluteUrlAppRoot()), - 'sTitle' => $this->s_title, - 'aMetadata' => [ + 'sTitle' => $this->s_title, + 'aMetadata' => [ 'sCharset' => static::PAGES_CHARSET, - 'sLang' => $this->GetLanguageForMetadata(), + 'sLang' => $this->GetLanguageForMetadata(), ], - 'aCssFiles' => $this->a_linked_stylesheets, - 'aCssInline' => $this->a_styles, - 'aJsInlineEarly' => $this->a_early_scripts, - 'aJsFiles' => $this->a_linked_scripts, - 'aJsInlineLive' => $this->a_scripts, + 'aCssFiles' => $this->a_linked_stylesheets, + 'aCssInline' => $this->a_styles, + 'aJsInlineEarly' => $this->a_early_scripts, + 'aJsFiles' => $this->a_linked_scripts, + 'aJsInlineLive' => $this->a_scripts, 'aJsInlineOnDomReady' => $this->GetReadyScripts(), - 'aJsInlineOnInit' => $this->a_init_scripts, + 'aJsInlineOnInit' => $this->a_init_scripts, // TODO 3.0.0: TEMP, used while developing, remove it. - 'sCapturedOutput' => utils::FilterXSS($s_captured_output), - 'sDeferredContent' => utils::FilterXSS($this->s_deferred_content), + 'sCapturedOutput' => utils::FilterXSS($s_captured_output), + 'sDeferredContent' => utils::FilterXSS($this->s_deferred_content), ]; + $aData['aBlockParams'] = $this->GetBlockParams(); + if ($this->a_base['href'] != '') { $aData['aPage']['aMetadata']['sBaseUrl'] = $this->a_base['href']; } @@ -1602,4 +1607,25 @@ EOD { return $this->sTemplateRelPath; } + + /** + * @return array + */ + public function GetBlockParams(): array + { + return $this->aBlockParams; + } + + /** + * @param string $sKey + * @param $value + * + * @return $this + */ + public function SetBlockParam(string $sKey, $value) + { + $this->aBlockParams[$sKey] = $value; + + return $this; + } } diff --git a/sources/application/WebPage/iTopWebPage.php b/sources/application/WebPage/iTopWebPage.php index 79f9fa106..2b355c307 100644 --- a/sources/application/WebPage/iTopWebPage.php +++ b/sources/application/WebPage/iTopWebPage.php @@ -72,7 +72,11 @@ class iTopWebPage extends NiceWebPage implements iTabbedPage * @param string $sTitle * @param bool $bPrintable * - * @throws \Exception + * @throws \ConfigException + * @throws \CoreException + * @throws \CoreUnexpectedValue + * @throws \DictExceptionMissingString + * @throws \MySQLException */ public function __construct($sTitle, $bPrintable = false) { @@ -102,10 +106,9 @@ class iTopWebPage extends NiceWebPage implements iTabbedPage $this->add_header("Content-type: text/html; charset=".self::PAGES_CHARSET); $this->no_cache(); $this->add_xframe_options(); - if (!$this->IsPrintableVersion()) - { + if (!$this->IsPrintableVersion()) { $this->PrepareLayout(); - } else{ + } else { $oPrintHeader = $this->OutputPrintable(); $this->AddUiBlock($oPrintHeader); } @@ -800,16 +803,18 @@ HTML; // Base structure of data to pass to the TWIG template $aData['aPage'] = [ 'sAbsoluteUrlAppRoot' => $sAbsoluteUrlAppRoot, - 'sTitle' => $this->s_title, - 'sFaviconUrl' => $sFaviconUrl, - 'aMetadata' => [ + 'sTitle' => $this->s_title, + 'sFaviconUrl' => $sFaviconUrl, + 'aMetadata' => [ 'sCharset' => static::PAGES_CHARSET, - 'sLang' => $sMetadataLanguage, + 'sLang' => $sMetadataLanguage, ], - 'oPrintHeader' => $oPrintHeader, - 'isPrintable' => $this->IsPrintableVersion(), + 'oPrintHeader' => $oPrintHeader, + 'isPrintable' => $this->IsPrintableVersion(), ]; + $aData['aBlockParams'] = $this->GetBlockParams(); + // Base tag // Note: We might consider to put the app_root_url parameter here, but that would need a BIG rework on iTop AND the extensions to replace all the "../images|js|css/xxx.yyy"... if (!empty($this->a_base['href'])) { @@ -1167,4 +1172,17 @@ EOF return $oBlock; } + + public function SetBlockParam(string $sKey, $value) + { + $oGlobalSearch = $this->GetTopBarLayout()->GetGlobalSearch(); + $sGlobalSearchId = $oGlobalSearch->GetId(); + switch ($sKey) { + case "$sGlobalSearchId.sQuery": + $oGlobalSearch->SetQuery($value); + break; + } + + return parent::SetBlockParam($sKey, $value); // TODO: Change the autogenerated stub + } } diff --git a/sources/application/WebPage/iTopWizardWebPage.php b/sources/application/WebPage/iTopWizardWebPage.php index 1d4bd5840..8ce4521bc 100644 --- a/sources/application/WebPage/iTopWizardWebPage.php +++ b/sources/application/WebPage/iTopWizardWebPage.php @@ -53,4 +53,3 @@ class iTopWizardWebPage extends iTopWebPage parent::output(); } } -?> diff --git a/templates/base/components/global-search/layout.html.twig b/templates/base/components/global-search/layout.html.twig index d752115b4..4456c5ca7 100644 --- a/templates/base/components/global-search/layout.html.twig +++ b/templates/base/components/global-search/layout.html.twig @@ -1,7 +1,7 @@