mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-28 06:34:14 +01:00
N°8772 - Turbo WIP
This commit is contained in:
@@ -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("<h1>".Dict::S('UI:FatalErrorMessage')."</h1>\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 <b>demonstration mode</b>: 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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{# @copyright Copyright (C) 2010-2025 Combodo SARL #}
|
||||
{# @license http://opensource.org/licenses/AGPL-3.0 #}
|
||||
|
||||
<div id="itop_profiler">
|
||||
<turbo-frame id="itop_profiler_turbo_frame">
|
||||
<div id="turbo_itop_profiler">
|
||||
{{ sProfilerContent|raw }}
|
||||
</div>
|
||||
</div>
|
||||
</turbo-frame>
|
||||
@@ -1,7 +1,7 @@
|
||||
{# @copyright Copyright (C) 2010-2025 Combodo SARL #}
|
||||
{# @license http://opensource.org/licenses/AGPL-3.0 #}
|
||||
|
||||
<turbo-stream action="update" target="itop_profiler">
|
||||
<turbo-stream action="update" target="turbo_itop_profiler">
|
||||
<template>
|
||||
{{ sProfilerContent|raw }}
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user