mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-24 02:58:43 +02:00
N°8796 - Add PHP code style validation in iTop and extensions - format whole code base
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2025 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -6,20 +7,19 @@
|
||||
|
||||
namespace Combodo\iTop\Application\TwigBase\Controller;
|
||||
|
||||
|
||||
abstract class AbstractProfilerExtension implements iProfilerExtension
|
||||
{
|
||||
public function Init()
|
||||
{
|
||||
}
|
||||
|
||||
public abstract function GetTemplatesPath(): null|string|array;
|
||||
abstract public function GetTemplatesPath(): null|string|array;
|
||||
|
||||
public abstract function IsEnabled(): bool;
|
||||
abstract public function IsEnabled(): bool;
|
||||
|
||||
public abstract function GetDebugTemplate(): string;
|
||||
abstract public function GetDebugTemplate(): string;
|
||||
|
||||
public abstract function GetDebugParams(array $aParams): array;
|
||||
abstract public function GetDebugParams(array $aParams): array;
|
||||
|
||||
public function GetLinkedScripts(): ?array
|
||||
{
|
||||
@@ -35,4 +35,4 @@ abstract class AbstractProfilerExtension implements iProfilerExtension
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
@@ -55,10 +56,10 @@ 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_SETUP = 'setup';
|
||||
public const ENUM_PAGE_TYPE_HTML = 'html';
|
||||
public const ENUM_PAGE_TYPE_BASIC_HTML = 'basic_html';
|
||||
public const ENUM_PAGE_TYPE_AJAX = 'ajax';
|
||||
public const ENUM_PAGE_TYPE_SETUP = 'setup';
|
||||
|
||||
/** @var \Twig\Environment */
|
||||
private $oTwig;
|
||||
@@ -147,7 +148,7 @@ abstract class Controller extends AbstractController
|
||||
if (!in_array($path, $aAdditionalPaths)) {
|
||||
$aAdditionalPaths[] = $path;
|
||||
}
|
||||
} else if (is_array($path)) {
|
||||
} elseif (is_array($path)) {
|
||||
foreach ($path as $sPath) {
|
||||
if (!in_array($sPath, $aAdditionalPaths)) {
|
||||
$aAdditionalPaths[] = $sPath;
|
||||
@@ -160,8 +161,7 @@ abstract class Controller extends AbstractController
|
||||
if ($sModuleName != 'core') {
|
||||
try {
|
||||
$this->aDefaultParams = ['sIndexURL' => utils::GetAbsoluteUrlModulePage($this->m_sModule, 'index.php')];
|
||||
}
|
||||
catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
IssueLog::Error($e->getMessage());
|
||||
}
|
||||
}
|
||||
@@ -187,12 +187,9 @@ abstract class Controller extends AbstractController
|
||||
$sModulePath = dirname(dirname($this->GetDir()));
|
||||
$this->SetModuleName(basename($sModulePath));
|
||||
$this->SetViewPath($sModulePath.'/view');
|
||||
try
|
||||
{
|
||||
$this->aDefaultParams = array('sIndexURL' => utils::GetAbsoluteUrlModulePage($this->m_sModule, 'index.php'));
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
try {
|
||||
$this->aDefaultParams = ['sIndexURL' => utils::GetAbsoluteUrlModulePage($this->m_sModule, 'index.php')];
|
||||
} catch (Exception $e) {
|
||||
IssueLog::Error($e->getMessage());
|
||||
}
|
||||
}
|
||||
@@ -242,8 +239,7 @@ abstract class Controller extends AbstractController
|
||||
*/
|
||||
public function HandleOperation()
|
||||
{
|
||||
try
|
||||
{
|
||||
try {
|
||||
$this->CheckAccess();
|
||||
$this->m_sOperation = utils::ReadParam('operation', $this->sDefaultOperation);
|
||||
|
||||
@@ -257,9 +253,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");
|
||||
@@ -277,8 +271,7 @@ abstract class Controller extends AbstractController
|
||||
*/
|
||||
public function HandleAjaxOperation()
|
||||
{
|
||||
try
|
||||
{
|
||||
try {
|
||||
$this->CheckAccess();
|
||||
$this->m_sOperation = utils::ReadParam('operation', $this->sDefaultOperation);
|
||||
|
||||
@@ -292,11 +285,9 @@ abstract class Controller extends AbstractController
|
||||
}
|
||||
|
||||
$this->DisplayPageNotFound();
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
} catch (Exception $e) {
|
||||
http_response_code(500);
|
||||
$aResponse = array('sError' => $e->getMessage());
|
||||
$aResponse = ['sError' => $e->getMessage()];
|
||||
echo json_encode($aResponse);
|
||||
}
|
||||
}
|
||||
@@ -336,8 +327,7 @@ abstract class Controller extends AbstractController
|
||||
*/
|
||||
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.");
|
||||
}
|
||||
|
||||
@@ -345,31 +335,32 @@ 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,
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -459,7 +450,7 @@ abstract class Controller extends AbstractController
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function DisplayAjaxPage($aParams = array(), $sTemplateName = null)
|
||||
public function DisplayAjaxPage($aParams = [], $sTemplateName = null)
|
||||
{
|
||||
$this->DisplayPage($aParams, $sTemplateName, 'ajax');
|
||||
}
|
||||
@@ -474,7 +465,7 @@ abstract class Controller extends AbstractController
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function DisplaySetupPage($aParams = array(), $sTemplateName = null)
|
||||
public function DisplaySetupPage($aParams = [], $sTemplateName = null)
|
||||
{
|
||||
$this->DisplayPage($aParams, $sTemplateName, 'setup');
|
||||
}
|
||||
@@ -490,7 +481,7 @@ abstract class Controller extends AbstractController
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function DisplayPage($aParams = array(), $sTemplateName = null, $sPageType = 'html')
|
||||
public function DisplayPage($aParams = [], $sTemplateName = null, $sPageType = 'html')
|
||||
{
|
||||
if (empty($sTemplateName)) {
|
||||
$sTemplateName = $this->m_sOperation;
|
||||
@@ -554,13 +545,12 @@ abstract class Controller extends AbstractController
|
||||
* @param int $iResponseCode HTTP response code
|
||||
* @param array $aHeaders additional HTTP headers
|
||||
*/
|
||||
public function DisplayJSONPage($aParams = array(), $iResponseCode = 200, $aHeaders = array())
|
||||
public function DisplayJSONPage($aParams = [], $iResponseCode = 200, $aHeaders = [])
|
||||
{
|
||||
$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);
|
||||
@@ -583,7 +573,7 @@ abstract class Controller extends AbstractController
|
||||
*
|
||||
* @since 3.0.1 3.1.0 Add $sReportFileName parameter
|
||||
*/
|
||||
public function DownloadZippedPage($aParams = array(), $sTemplateName = null, $sReportFileName = 'itop-system-information-report')
|
||||
public function DownloadZippedPage($aParams = [], $sTemplateName = null, $sReportFileName = 'itop-system-information-report')
|
||||
{
|
||||
if (empty($sTemplateName)) {
|
||||
$sTemplateName = $this->m_sOperation;
|
||||
@@ -598,7 +588,7 @@ abstract class Controller extends AbstractController
|
||||
file_put_contents($sHTMLReport, ob_get_contents());
|
||||
ob_end_clean();
|
||||
|
||||
$this->ZipDownloadRemoveFile(array($sHTMLReport), $sZIPReportFile, true);
|
||||
$this->ZipDownloadRemoveFile([$sHTMLReport], $sZIPReportFile, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -613,16 +603,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);
|
||||
}
|
||||
}
|
||||
@@ -630,13 +617,12 @@ abstract class Controller extends AbstractController
|
||||
$this->SendFileContent($sArchiveFileFullPath, $sDownloadArchiveName.'.zip', true, true);
|
||||
}
|
||||
|
||||
final protected function SendFileContent($sFilePath, $sDownloadArchiveName = null, $bFileTransfer = true, $bRemoveFile = false, $aHeaders = array())
|
||||
final protected function SendFileContent($sFilePath, $sDownloadArchiveName = null, $bFileTransfer = true, $bRemoveFile = false, $aHeaders = [])
|
||||
{
|
||||
$sFileMimeType = utils::GetFileMimeType($sFilePath);
|
||||
header('Content-Type: '.$sFileMimeType);
|
||||
|
||||
if ($bFileTransfer)
|
||||
{
|
||||
if ($bFileTransfer) {
|
||||
header('Content-Disposition: attachment; filename="'.$sDownloadArchiveName.'"');
|
||||
}
|
||||
|
||||
@@ -652,8 +638,7 @@ abstract class Controller extends AbstractController
|
||||
|
||||
readfile($sFilePath);
|
||||
|
||||
if ($bRemoveFile)
|
||||
{
|
||||
if ($bRemoveFile) {
|
||||
unlink($sFilePath);
|
||||
}
|
||||
exit(0);
|
||||
@@ -713,7 +698,7 @@ abstract class Controller extends AbstractController
|
||||
if (is_null($sLabel)) {
|
||||
$sLabel = Dict::S($sCode);
|
||||
}
|
||||
$this->aAjaxTabs[$sCode] = array('label' => $sLabel, 'url' => $sURL, 'cache' => $bCache);
|
||||
$this->aAjaxTabs[$sCode] = ['label' => $sLabel, 'url' => $sURL, 'cache' => $bCache];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -729,7 +714,8 @@ 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)
|
||||
*/
|
||||
public function DisableBreadCrumb() {
|
||||
public function DisableBreadCrumb()
|
||||
{
|
||||
$this->bIsBreadCrumbEnabled = false;
|
||||
}
|
||||
|
||||
@@ -737,7 +723,8 @@ abstract class Controller extends AbstractController
|
||||
* @since 2.7.7 3.0.1 3.1.0 N°4760 method creation
|
||||
* @see iTopWebPage::SetBreadCrumbEntry()
|
||||
*/
|
||||
public function SetBreadCrumbEntry($sId, $sLabel, $sDescription, $sUrl = '', $sIcon = '') {
|
||||
public function SetBreadCrumbEntry($sId, $sLabel, $sDescription, $sUrl = '', $sIcon = '')
|
||||
{
|
||||
$this->aBreadCrumbEntry = [$sId, $sLabel, $sDescription, $sUrl, $sIcon];
|
||||
}
|
||||
|
||||
@@ -758,7 +745,7 @@ abstract class Controller extends AbstractController
|
||||
*/
|
||||
public function GetFormBuilder(string $type = FormType::class, mixed $data = null, array $options = []): FormBuilderInterface
|
||||
{
|
||||
return $this->oFormFactoryBuilder->getFormFactory()->createBuilder($type, $data,$options);
|
||||
return $this->oFormFactoryBuilder->getFormFactory()->createBuilder($type, $data, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -776,7 +763,7 @@ 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();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -790,26 +777,21 @@ 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) {
|
||||
} 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) {
|
||||
} 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)) {
|
||||
@@ -828,8 +810,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();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2025 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -17,4 +18,4 @@ interface iProfilerExtension
|
||||
public function GetLinkedScripts(): null|array;
|
||||
public function GetLinkedStylesheets(): null|array;
|
||||
public function GetSaas(): null|array;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -75,7 +76,7 @@ class DataTableUIBlockFactory extends AbstractUIBlockFactory
|
||||
* @throws \OQLException
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
public static function MakeForResult(WebPage $oPage, string $sListId, DBObjectSet $oSet, $aExtraParams = array())
|
||||
public static function MakeForResult(WebPage $oPage, string $sListId, DBObjectSet $oSet, $aExtraParams = [])
|
||||
{
|
||||
$oDataTable = DataTableUIBlockFactory::MakeForRendering($sListId, $oSet, $aExtraParams);
|
||||
if ($oPage->IsPrintableVersion()) {
|
||||
@@ -105,7 +106,7 @@ class DataTableUIBlockFactory extends AbstractUIBlockFactory
|
||||
* @throws \OQLException
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
public static function MakeForObject(WebPage $oPage, string $sListId, DBObjectSet $oSet, $aExtraParams = array())
|
||||
public static function MakeForObject(WebPage $oPage, string $sListId, DBObjectSet $oSet, $aExtraParams = [])
|
||||
{
|
||||
$oDataTable = DataTableUIBlockFactory::MakeForRendering($sListId, $oSet, $aExtraParams);
|
||||
if ($oPage->IsPrintableVersion()) {
|
||||
@@ -190,7 +191,7 @@ class DataTableUIBlockFactory extends AbstractUIBlockFactory
|
||||
}
|
||||
|
||||
// Panel subtitle
|
||||
if(!empty($oDataTable->GetInitDisplayData()) && isset($oDataTable->GetInitDisplayData()['recordsTotal'])){
|
||||
if (!empty($oDataTable->GetInitDisplayData()) && isset($oDataTable->GetInitDisplayData()['recordsTotal'])) {
|
||||
$iCount = $oDataTable->GetInitDisplayData()['recordsTotal'];
|
||||
} else {
|
||||
$iCount = $oSet->Count();
|
||||
@@ -200,7 +201,7 @@ class DataTableUIBlockFactory extends AbstractUIBlockFactory
|
||||
$sSubTitle = Dict::Format('UI:Pagination:HeaderSelection', $sCountHtml, '<span class="ibo-datatable--selected-count">0</span>');
|
||||
} else {
|
||||
$sSubTitle = Dict::Format('UI:Pagination:HeaderNoSelection', $sCountHtml);
|
||||
}
|
||||
}
|
||||
|
||||
if (utils::IsNotNullOrEmptyString($sFilterListUrl)) {
|
||||
$sSubTitle = '<a href="'.$sFilterListUrl.'" title="'.Dict::S('UI:Menu:FilterList').'">'.$sSubTitle.'</a>';
|
||||
@@ -292,15 +293,15 @@ class DataTableUIBlockFactory extends AbstractUIBlockFactory
|
||||
* @throws \DictExceptionMissingString
|
||||
* @throws \MySQLException
|
||||
*/
|
||||
public static function MakeForRendering(string $sListId, DBObjectSet $oSet, $aExtraParams = array())
|
||||
public static function MakeForRendering(string $sListId, DBObjectSet $oSet, $aExtraParams = [])
|
||||
{
|
||||
$oDataTable = new DataTable('datatable_'.$sListId);
|
||||
$aLists = array();
|
||||
$aLists = [];
|
||||
|
||||
// Initialize and check the parameters
|
||||
$bViewLink = isset($aExtraParams['view_link']) ? $aExtraParams['view_link'] : true;
|
||||
// Check if there is a list of aliases to limit the display to...
|
||||
$aDisplayAliases = isset($aExtraParams['display_aliases']) ? explode(',', $aExtraParams['display_aliases']) : array();
|
||||
$aDisplayAliases = isset($aExtraParams['display_aliases']) ? explode(',', $aExtraParams['display_aliases']) : [];
|
||||
$sZListName = isset($aExtraParams['zlist']) ? ($aExtraParams['zlist']) : 'list';
|
||||
|
||||
$sLinkageAttribute = isset($aExtraParams['link_attr']) ? $aExtraParams['link_attr'] : '';
|
||||
@@ -317,9 +318,11 @@ class DataTableUIBlockFactory extends AbstractUIBlockFactory
|
||||
}
|
||||
}
|
||||
|
||||
$aExtraFieldsRaw = isset($aExtraParams['extra_fields']) ? explode(',',
|
||||
trim($aExtraParams['extra_fields'])) : array();
|
||||
$aExtraFields = array();
|
||||
$aExtraFieldsRaw = isset($aExtraParams['extra_fields']) ? explode(
|
||||
',',
|
||||
trim($aExtraParams['extra_fields'])
|
||||
) : [];
|
||||
$aExtraFields = [];
|
||||
$sAttCode = '';
|
||||
foreach ($aExtraFieldsRaw as $sFieldName) {
|
||||
// Ignore attributes not of the main queried class
|
||||
@@ -332,10 +335,10 @@ class DataTableUIBlockFactory extends AbstractUIBlockFactory
|
||||
} else {
|
||||
$aExtraFields['*'][] = $sFieldName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$aClassAliases = $oSet->GetFilter()->GetSelectedClasses();
|
||||
$aAuthorizedClasses = array();
|
||||
$aAuthorizedClasses = [];
|
||||
foreach ($aClassAliases as $sAlias => $sClassName) {
|
||||
if ((UserRights::IsActionAllowed($sClassName, UR_ACTION_READ, $oSet) != UR_ALLOWED_NO) &&
|
||||
((count($aDisplayAliases) == 0) || (in_array($sAlias, $aDisplayAliases)))) {
|
||||
@@ -345,65 +348,65 @@ class DataTableUIBlockFactory extends AbstractUIBlockFactory
|
||||
foreach ($aAuthorizedClasses as $sAlias => $sClassName) {
|
||||
// In case there is only 1 "alias" for the extra fields and it is the fallback ("*"), then consider that all fields are for the current alias.
|
||||
// This is for the particular use case when the zlist is set to false and extra fields are specified.
|
||||
if ( (count($aExtraFields) === 1) && (array_keys($aExtraFields)[0] === '*') ) {
|
||||
if ((count($aExtraFields) === 1) && (array_keys($aExtraFields)[0] === '*')) {
|
||||
$aLists[$sAlias] = $aExtraFields['*'];
|
||||
}
|
||||
// Regular use case, dispatch fields to their corresponding aliases
|
||||
else if (array_key_exists($sAlias, $aExtraFields)) {
|
||||
elseif (array_key_exists($sAlias, $aExtraFields)) {
|
||||
$aLists[$sAlias] = $aExtraFields[$sAlias];
|
||||
}
|
||||
}
|
||||
// Finally, if unknown alias, ignore fields
|
||||
else {
|
||||
$aLists[$sAlias] = array();
|
||||
$aLists[$sAlias] = [];
|
||||
}
|
||||
|
||||
// If zlist specified, merge its fields with the currently present
|
||||
if ($sZListName !== false) {
|
||||
if ($sZListName !== false) {
|
||||
$aDefaultList = MetaModel::FlattenZList(MetaModel::GetZListItems($sClassName, $sZListName));
|
||||
$aLists[$sAlias] = array_merge($aDefaultList, $aLists[$sAlias]);
|
||||
}
|
||||
}
|
||||
|
||||
// Filter the list to removed linked set since we are not able to display them here
|
||||
// Filter the list to removed linked set since we are not able to display them here
|
||||
foreach ($aLists[$sAlias] as $index => $sAttCode) {
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClassName, $sAttCode);
|
||||
if ($oAttDef instanceof AttributeLinkedSet) {
|
||||
// Removed from the display list
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClassName, $sAttCode);
|
||||
if ($oAttDef instanceof AttributeLinkedSet) {
|
||||
// Removed from the display list
|
||||
unset($aLists[$sAlias][$index]);
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($aLists[$sAlias])) {
|
||||
unset($aLists[$sAlias], $aAuthorizedClasses[$sAlias]);
|
||||
}
|
||||
}
|
||||
|
||||
// Only for main class
|
||||
if (!empty($sLinkageAttribute) && $sClassName === $oSet->GetFilter()->GetClass()) {
|
||||
// The set to display is in fact a set of links between the object specified in the $sLinkageAttribute
|
||||
// and other objects...
|
||||
// The display will then group all the attributes related to the link itself:
|
||||
// | Link_attr1 | link_attr2 | ... || Object_attr1 | Object_attr2 | Object_attr3 | .. | Object_attr_n |
|
||||
$aDisplayList = array();
|
||||
$aAttDefs = MetaModel::ListAttributeDefs($sClassName);
|
||||
assert(isset($aAttDefs[$sLinkageAttribute]));
|
||||
$oAttDef = $aAttDefs[$sLinkageAttribute];
|
||||
assert($oAttDef->IsExternalKey());
|
||||
// First display all the attributes specific to the link record
|
||||
// The set to display is in fact a set of links between the object specified in the $sLinkageAttribute
|
||||
// and other objects...
|
||||
// The display will then group all the attributes related to the link itself:
|
||||
// | Link_attr1 | link_attr2 | ... || Object_attr1 | Object_attr2 | Object_attr3 | .. | Object_attr_n |
|
||||
$aDisplayList = [];
|
||||
$aAttDefs = MetaModel::ListAttributeDefs($sClassName);
|
||||
assert(isset($aAttDefs[$sLinkageAttribute]));
|
||||
$oAttDef = $aAttDefs[$sLinkageAttribute];
|
||||
assert($oAttDef->IsExternalKey());
|
||||
// First display all the attributes specific to the link record
|
||||
foreach ($aLists[$sAlias] as $sLinkAttCode) {
|
||||
$oLinkAttDef = $aAttDefs[$sLinkAttCode];
|
||||
if ((!$oLinkAttDef->IsExternalKey()) && (!$oLinkAttDef->IsExternalField())) {
|
||||
$aDisplayList[] = $sLinkAttCode;
|
||||
$oLinkAttDef = $aAttDefs[$sLinkAttCode];
|
||||
if ((!$oLinkAttDef->IsExternalKey()) && (!$oLinkAttDef->IsExternalField())) {
|
||||
$aDisplayList[] = $sLinkAttCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Then display all the attributes neither specific to the link record nor to the 'linkage' object (because the latter are constant)
|
||||
// Then display all the attributes neither specific to the link record nor to the 'linkage' object (because the latter are constant)
|
||||
foreach ($aLists[$sAlias] as $sLinkAttCode) {
|
||||
$oLinkAttDef = $aAttDefs[$sLinkAttCode];
|
||||
if (($oLinkAttDef->IsExternalKey() && ($sLinkAttCode != $sLinkageAttribute))
|
||||
|| ($oLinkAttDef->IsExternalField() && ($oLinkAttDef->GetKeyAttCode() != $sLinkageAttribute))) {
|
||||
$aDisplayList[] = $sLinkAttCode;
|
||||
$oLinkAttDef = $aAttDefs[$sLinkAttCode];
|
||||
if (($oLinkAttDef->IsExternalKey() && ($sLinkAttCode != $sLinkageAttribute))
|
||||
|| ($oLinkAttDef->IsExternalField() && ($oLinkAttDef->GetKeyAttCode() != $sLinkageAttribute))) {
|
||||
$aDisplayList[] = $sLinkAttCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
// First display all the attributes specific to the link
|
||||
// Then display all the attributes linked to the other end of the relationship
|
||||
// First display all the attributes specific to the link
|
||||
// Then display all the attributes linked to the other end of the relationship
|
||||
$aLists[$sAlias] = $aDisplayList;
|
||||
}
|
||||
}
|
||||
@@ -460,7 +463,7 @@ class DataTableUIBlockFactory extends AbstractUIBlockFactory
|
||||
|
||||
$sIdName = isset($aExtraParams["id_for_select"]) ? $aExtraParams["id_for_select"] : "";
|
||||
// Load only the requested columns
|
||||
$aColumnsToLoad = array();
|
||||
$aColumnsToLoad = [];
|
||||
foreach ($oCustomSettings->aColumns as $sAlias => $aColumnsInfo) {
|
||||
foreach ($aColumnsInfo as $sAttCode => $aData) {
|
||||
$bForceLoad = false;
|
||||
@@ -488,7 +491,7 @@ class DataTableUIBlockFactory extends AbstractUIBlockFactory
|
||||
$oSet->OptimizeColumnLoad($aColumnsToLoad);
|
||||
|
||||
$aColumnDefinition = [];
|
||||
$iIndexColumn=0;
|
||||
$iIndexColumn = 0;
|
||||
|
||||
$bSelectMode = isset($aExtraParams['selection_mode']) ? $aExtraParams['selection_mode'] == true : false;
|
||||
$bSingleSelectMode = isset($aExtraParams['selection_type']) ? ($aExtraParams['selection_type'] == 'single') : false;
|
||||
@@ -509,12 +512,11 @@ class DataTableUIBlockFactory extends AbstractUIBlockFactory
|
||||
$sCode = ($aData['code'] == '_key_') ? 'friendlyname' : $aData['code'];
|
||||
if ($aData['sort'] != 'none') {
|
||||
$aSortOrder[$sClassAlias.'.'.$sCode] = ($aData['sort'] == 'asc'); // true for ascending, false for descending
|
||||
$aSortDatable=[$iIndexColumn,$aData['sort']];
|
||||
}
|
||||
elseif (isset($oCustomSettings->aSortOrder[$sAttCode])){
|
||||
$aSortDatable = [$iIndexColumn,$aData['sort']];
|
||||
} elseif (isset($oCustomSettings->aSortOrder[$sAttCode])) {
|
||||
$aSortOrder[$sClassAlias.'.'.$sCode] = $oCustomSettings->aSortOrder[$sAttCode]; // true for ascending, false for descending
|
||||
}
|
||||
|
||||
|
||||
if ($aData['checked']) {
|
||||
if ($sAttCode == '_key_') {
|
||||
if ($bViewLink) {
|
||||
@@ -557,7 +559,7 @@ class DataTableUIBlockFactory extends AbstractUIBlockFactory
|
||||
|
||||
$aOptions = [];
|
||||
if ($oDefaultSettings != null) {
|
||||
$aOptions['oDefaultSettings'] = json_encode(array('iDefaultPageSize' => $oDefaultSettings->iDefaultPageSize, 'oColumns' => $oDefaultSettings->aColumns));
|
||||
$aOptions['oDefaultSettings'] = json_encode(['iDefaultPageSize' => $oDefaultSettings->iDefaultPageSize, 'oColumns' => $oDefaultSettings->aColumns]);
|
||||
}
|
||||
|
||||
// Selection mode
|
||||
@@ -568,7 +570,7 @@ class DataTableUIBlockFactory extends AbstractUIBlockFactory
|
||||
$aOptions['select_mode'] = "single";
|
||||
}
|
||||
}
|
||||
$aOptions['selectionMode'] = $aExtraParams['selectionMode']?? 'positive';
|
||||
$aOptions['selectionMode'] = $aExtraParams['selectionMode'] ?? 'positive';
|
||||
|
||||
// Sort
|
||||
$aOptions['sort'] = $aSortDatable;
|
||||
@@ -600,9 +602,8 @@ class DataTableUIBlockFactory extends AbstractUIBlockFactory
|
||||
} else {
|
||||
$aOptions['sSelectedRows'] = '[]';
|
||||
}
|
||||
$aExtraParams['table_id']=$sTableId;
|
||||
$aExtraParams['list_id']=$sListId;
|
||||
|
||||
$aExtraParams['table_id'] = $sTableId;
|
||||
$aExtraParams['list_id'] = $sListId;
|
||||
|
||||
$oDataTable->SetOptions($aOptions);
|
||||
$oDataTable->SetAjaxUrl(utils::GetAbsoluteUrlAppRoot()."pages/ajax.render.php");
|
||||
@@ -623,7 +624,7 @@ class DataTableUIBlockFactory extends AbstractUIBlockFactory
|
||||
$oDataTable->SetRowActions($aExtraParams['row_actions']);
|
||||
}
|
||||
|
||||
if (isset($aExtraParams['creation_in_modal_js_handler'])){
|
||||
if (isset($aExtraParams['creation_in_modal_js_handler'])) {
|
||||
$oDataTable->SetModalCreationHandler($aExtraParams['creation_in_modal_js_handler']);
|
||||
}
|
||||
|
||||
@@ -671,18 +672,17 @@ class DataTableUIBlockFactory extends AbstractUIBlockFactory
|
||||
$aColumnDefinition["data"] = "";
|
||||
$aColumnDefinition["render"]["display"] = "";
|
||||
if ($sSelectMode != "single") {
|
||||
$aColumnDefinition["render"]["display"] = $aColumnDefinition["render"]["display"] . " var oCheckboxElem = $('<span class=\"row_input\"><input type=\"checkbox\" class=\"selectList".$sTableId."\" name=\"selectObject[]\" value='+row.id+' /></span>');";
|
||||
$aColumnDefinition["render"]["display"] = $aColumnDefinition["render"]["display"]." var oCheckboxElem = $('<span class=\"row_input\"><input type=\"checkbox\" class=\"selectList".$sTableId."\" name=\"selectObject[]\" value='+row.id+' /></span>');";
|
||||
} else {
|
||||
$aColumnDefinition["render"]["display"] = $aColumnDefinition["render"]["display"]." var oCheckboxElem = $('<span class=\"row_input\"><input type=\"radio\" class=\"selectList".$sTableId."\" name=\"selectObject[]\" value='+ row.id +' /></span>');";
|
||||
}
|
||||
else {
|
||||
$aColumnDefinition["render"]["display"] = $aColumnDefinition["render"]["display"] . " var oCheckboxElem = $('<span class=\"row_input\"><input type=\"radio\" class=\"selectList".$sTableId."\" name=\"selectObject[]\" value='+ row.id +' /></span>');";
|
||||
}
|
||||
$aColumnDefinition["render"]["display"] = $aColumnDefinition["render"]["display"] . " if (row.limited_access) { oCheckboxElem.html('-'); } else { oCheckboxElem.find(':input').attr('data-object-id', row.id).attr('data-target-object-id', row.target_id); }";
|
||||
$aColumnDefinition["render"]["display"] = $aColumnDefinition["render"]["display"]. " return oCheckboxElem.prop('outerHTML'); ";
|
||||
$aColumnDefinition["render"]["display"] = $aColumnDefinition["render"]["display"]." if (row.limited_access) { oCheckboxElem.html('-'); } else { oCheckboxElem.find(':input').attr('data-object-id', row.id).attr('data-target-object-id', row.target_id); }";
|
||||
$aColumnDefinition["render"]["display"] = $aColumnDefinition["render"]["display"]." return oCheckboxElem.prop('outerHTML'); ";
|
||||
array_push($aColumnsDefinitions, $aColumnDefinition);
|
||||
}
|
||||
|
||||
foreach ($aColumns as $sClassAlias => $aClassColumns) {
|
||||
$sClassName=$aClassAliases[$sClassAlias];
|
||||
$sClassName = $aClassAliases[$sClassAlias];
|
||||
foreach ($aClassColumns as $sAttCode => $aData) {
|
||||
if ($aData['checked'] == "true") {
|
||||
$aColumnDefinition["width"] = "auto";
|
||||
@@ -803,7 +803,7 @@ JS;
|
||||
"data": '.$sAjaxData.',
|
||||
"method": "post",
|
||||
"pages": 5 // number of pages to cache
|
||||
} )'
|
||||
} )',
|
||||
]);
|
||||
if (count($aJsFiles) > 0) {
|
||||
foreach ($aJsFiles as $sJsFile) {
|
||||
@@ -954,4 +954,4 @@ JS;
|
||||
/** Don't provide the standard object creation feature */
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
@@ -19,7 +20,6 @@
|
||||
|
||||
namespace Combodo\iTop\Application\UI\Base\Component\QuickCreate;
|
||||
|
||||
|
||||
use appUserPreferences;
|
||||
use DBObject;
|
||||
use MetaModel;
|
||||
@@ -60,10 +60,8 @@ class QuickCreateHelper
|
||||
$aHistoryEntries = appUserPreferences::GetPref(static::USER_PREF_CODE, []);
|
||||
|
||||
// Remove same entry from history to avoid duplicates
|
||||
for ($iIdx = 0; $iIdx < count($aHistoryEntries); $iIdx++)
|
||||
{
|
||||
if ($aHistoryEntries[$iIdx]['class'] === $sClass)
|
||||
{
|
||||
for ($iIdx = 0; $iIdx < count($aHistoryEntries); $iIdx++) {
|
||||
if ($aHistoryEntries[$iIdx]['class'] === $sClass) {
|
||||
unset($aHistoryEntries[$iIdx]);
|
||||
}
|
||||
}
|
||||
@@ -92,33 +90,28 @@ class QuickCreateHelper
|
||||
|
||||
static::Truncate($aHistoryEntries, 'quick_create.max_history_results');
|
||||
|
||||
for($iIdx = 0; $iIdx < count($aHistoryEntries); $iIdx++)
|
||||
{
|
||||
for ($iIdx = 0; $iIdx < count($aHistoryEntries); $iIdx++) {
|
||||
$sClass = $aHistoryEntries[$iIdx]['class'];
|
||||
|
||||
if (!MetaModel::IsValidClass($sClass)) {
|
||||
continue;
|
||||
}
|
||||
// Add class icon
|
||||
if(!isset($aHistoryEntries[$iIdx]['icon_url']))
|
||||
{
|
||||
if (!isset($aHistoryEntries[$iIdx]['icon_url'])) {
|
||||
$sClassIconUrl = MetaModel::GetClassIcon($sClass, false);
|
||||
// Mind that some classes don't have an icon
|
||||
if(!empty($sClassIconUrl))
|
||||
{
|
||||
if (!empty($sClassIconUrl)) {
|
||||
$aHistoryEntries[$iIdx]['icon_url'] = $sClassIconUrl;
|
||||
}
|
||||
}
|
||||
|
||||
// Add class label
|
||||
if(!isset($aHistoryEntries[$iIdx]['label_html']))
|
||||
{
|
||||
if (!isset($aHistoryEntries[$iIdx]['label_html'])) {
|
||||
$aHistoryEntries[$iIdx]['label_html'] = utils::EscapeHtml(MetaModel::GetName($sClass));
|
||||
}
|
||||
|
||||
// Add URL
|
||||
if(!isset($aHistoryEntries[$iIdx]['target_url']))
|
||||
{
|
||||
if (!isset($aHistoryEntries[$iIdx]['target_url'])) {
|
||||
$aHistoryEntries[$iIdx]['target_url'] = DBObject::ComputeStandardUIPage($sClass).'?operation=new&class='.$sClass;
|
||||
}
|
||||
}
|
||||
@@ -138,20 +131,18 @@ class QuickCreateHelper
|
||||
{
|
||||
$aHistoryEntries = appUserPreferences::GetPref(static::USER_PREF_CODE, []);
|
||||
static::Truncate($aHistoryEntries, 'quick_create.max_history_results');
|
||||
$aPopularClassesNames = UserRights::GetAllowedClasses(UR_ACTION_CREATE, array('popular'), false);
|
||||
$aPopularClassesNames = UserRights::GetAllowedClasses(UR_ACTION_CREATE, ['popular'], false);
|
||||
|
||||
// Prevent classes in both Popular and Recent to appear twice
|
||||
for($iIdx = 0; $iIdx < count($aHistoryEntries); $iIdx++)
|
||||
{
|
||||
for ($iIdx = 0; $iIdx < count($aHistoryEntries); $iIdx++) {
|
||||
if (($key = array_search($aHistoryEntries[$iIdx]['class'], $aPopularClassesNames)) !== false) {
|
||||
unset($aPopularClassesNames[$key]);
|
||||
}
|
||||
}
|
||||
//die(var_dump($aPopularClassesNames));
|
||||
static::Truncate($aPopularClassesNames, 'quick_create.max_popular_results');
|
||||
$aPopularClasses = array();
|
||||
foreach($aPopularClassesNames as $sClass)
|
||||
{
|
||||
$aPopularClasses = [];
|
||||
foreach ($aPopularClassesNames as $sClass) {
|
||||
if (!MetaModel::IsValidClass($sClass)) {
|
||||
continue;
|
||||
}
|
||||
@@ -167,12 +158,12 @@ class QuickCreateHelper
|
||||
// Add URL
|
||||
$sTargetUrl = DBObject::ComputeStandardUIPage($sClass).'?operation=new&class='.$sClass;
|
||||
|
||||
$aPopularClasses[] = array(
|
||||
$aPopularClasses[] = [
|
||||
'class' => $sClass,
|
||||
'icon_url' => $sClassIconUrl,
|
||||
'label_html' => $sLabelHtml,
|
||||
'target_url' => $sTargetUrl
|
||||
);
|
||||
'target_url' => $sTargetUrl,
|
||||
];
|
||||
}
|
||||
return $aPopularClasses;
|
||||
}
|
||||
@@ -186,11 +177,9 @@ class QuickCreateHelper
|
||||
protected static function Truncate(array &$aEntries, string $sMaxEntriesParam = 'global_search.max_history_results'): void
|
||||
{
|
||||
$iMaxResults = (int) MetaModel::GetConfig()->Get($sMaxEntriesParam);
|
||||
if(count($aEntries) > $iMaxResults)
|
||||
{
|
||||
if (count($aEntries) > $iMaxResults) {
|
||||
$aEntries = array_slice($aEntries, 0, $iMaxResults);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
@@ -19,7 +20,6 @@
|
||||
|
||||
namespace Combodo\iTop\Application\UI\Base\Layout\ActivityPanel;
|
||||
|
||||
|
||||
use appUserPreferences;
|
||||
use AttributeDateTime;
|
||||
use cmdbAbstractObject;
|
||||
@@ -102,7 +102,6 @@ class ActivityPanel extends UIBlock
|
||||
/** @var bool */
|
||||
protected $bPrefilterEditsOnLogs;
|
||||
|
||||
|
||||
/**
|
||||
* ActivityPanel constructor.
|
||||
*
|
||||
@@ -166,7 +165,6 @@ class ActivityPanel extends UIBlock
|
||||
$this->AddCaseLogTab($sCaseLogAttCode);
|
||||
}
|
||||
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -185,7 +183,8 @@ class ActivityPanel extends UIBlock
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function GetObjectId(): int {
|
||||
public function GetObjectId(): int
|
||||
{
|
||||
return $this->oObject->GetKey();
|
||||
}
|
||||
|
||||
@@ -194,7 +193,8 @@ class ActivityPanel extends UIBlock
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function GetObjectClass(): string {
|
||||
public function GetObjectClass(): string
|
||||
{
|
||||
return get_class($this->oObject);
|
||||
}
|
||||
|
||||
@@ -210,7 +210,7 @@ class ActivityPanel extends UIBlock
|
||||
public function SetObjectMode(string $sMode)
|
||||
{
|
||||
// Consistency check
|
||||
if(!in_array($sMode, cmdbAbstractObject::EnumDisplayModes())){
|
||||
if (!in_array($sMode, cmdbAbstractObject::EnumDisplayModes())) {
|
||||
throw new Exception("Activity panel: Object mode '$sMode' not allowed, should be either ".implode(' / ', cmdbAbstractObject::EnumDisplayModes()));
|
||||
}
|
||||
|
||||
@@ -300,8 +300,7 @@ class ActivityPanel extends UIBlock
|
||||
// Reset entries
|
||||
$this->aEntries = [];
|
||||
|
||||
foreach ($aEntries as $oEntry)
|
||||
{
|
||||
foreach ($aEntries as $oEntry) {
|
||||
$this->AddEntry($oEntry);
|
||||
}
|
||||
|
||||
@@ -315,8 +314,7 @@ class ActivityPanel extends UIBlock
|
||||
*/
|
||||
public function GetEntries(): array
|
||||
{
|
||||
if ($this->bAreEntriesSorted === false)
|
||||
{
|
||||
if ($this->bAreEntriesSorted === false) {
|
||||
$this->SortEntries();
|
||||
}
|
||||
|
||||
@@ -335,18 +333,15 @@ class ActivityPanel extends UIBlock
|
||||
|
||||
$aCurrentGroup = ['author_login' => null, 'origin' => null, 'entries' => []];
|
||||
$aPreviousEntryData = ['author_login' => null, 'origin' => null];
|
||||
foreach($this->GetEntries() as $sId => $oEntry)
|
||||
{
|
||||
foreach ($this->GetEntries() as $sId => $oEntry) {
|
||||
// New entry data
|
||||
$sAuthorLogin = $oEntry->GetAuthorLogin();
|
||||
$sOrigin = $oEntry->GetOrigin();
|
||||
|
||||
// Check if it's time to change of group
|
||||
if(($sAuthorLogin !== $aPreviousEntryData['author_login']) || ($sOrigin !== $aPreviousEntryData['origin']))
|
||||
{
|
||||
if (($sAuthorLogin !== $aPreviousEntryData['author_login']) || ($sOrigin !== $aPreviousEntryData['origin'])) {
|
||||
// Flush current group if necessary
|
||||
if(empty($aCurrentGroup['entries']) === false)
|
||||
{
|
||||
if (empty($aCurrentGroup['entries']) === false) {
|
||||
$aGroupedEntries[] = $aCurrentGroup;
|
||||
}
|
||||
|
||||
@@ -359,8 +354,7 @@ class ActivityPanel extends UIBlock
|
||||
}
|
||||
|
||||
// Flush last group
|
||||
if(empty($aCurrentGroup['entries']) === false)
|
||||
{
|
||||
if (empty($aCurrentGroup['entries']) === false) {
|
||||
$aGroupedEntries[] = $aCurrentGroup;
|
||||
}
|
||||
|
||||
@@ -374,16 +368,14 @@ class ActivityPanel extends UIBlock
|
||||
*/
|
||||
protected function SortEntries()
|
||||
{
|
||||
if(count($this->aEntries) > 1)
|
||||
{
|
||||
uasort($this->aEntries, function($oEntryA, $oEntryB){
|
||||
if (count($this->aEntries) > 1) {
|
||||
uasort($this->aEntries, function ($oEntryA, $oEntryB) {
|
||||
/** @var ActivityEntry $oEntryA */
|
||||
/** @var ActivityEntry $oEntryB */
|
||||
$sDateTimeA = $oEntryA->GetRawDateTime();
|
||||
$sDateTimeB = $oEntryB->GetRawDateTime();
|
||||
|
||||
if ($sDateTimeA === $sDateTimeB)
|
||||
{
|
||||
if ($sDateTimeA === $sDateTimeB) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -409,14 +401,12 @@ class ActivityPanel extends UIBlock
|
||||
$this->bAreEntriesSorted = false;
|
||||
|
||||
// Add case log to the panel and update metadata when necessary
|
||||
if ($oEntry instanceof CaseLogEntry)
|
||||
{
|
||||
if ($oEntry instanceof CaseLogEntry) {
|
||||
$sCaseLogAttCode = $oEntry->GetAttCode();
|
||||
$sAuthorLogin = $oEntry->GetAuthorLogin();
|
||||
|
||||
// Initialize case log metadata
|
||||
if ($this->HasCaseLogTab($sCaseLogAttCode) === false)
|
||||
{
|
||||
if ($this->HasCaseLogTab($sCaseLogAttCode) === false) {
|
||||
$this->AddCaseLogTab($sCaseLogAttCode);
|
||||
}
|
||||
|
||||
@@ -427,8 +417,7 @@ class ActivityPanel extends UIBlock
|
||||
// - Message count
|
||||
$this->aCaseLogs[$sCaseLogAttCode]['total_messages_count']++;
|
||||
// - Authors
|
||||
if(array_key_exists($sAuthorLogin, $this->aCaseLogs[$sCaseLogAttCode]['authors']) === false)
|
||||
{
|
||||
if (array_key_exists($sAuthorLogin, $this->aCaseLogs[$sCaseLogAttCode]['authors']) === false) {
|
||||
$this->aCaseLogs[$sCaseLogAttCode]['authors'][$sAuthorLogin] = [
|
||||
'messages_count' => 0,
|
||||
];
|
||||
@@ -449,12 +438,10 @@ class ActivityPanel extends UIBlock
|
||||
*/
|
||||
public function RemoveEntry(string $sEntryId)
|
||||
{
|
||||
if (array_key_exists($sEntryId, $this->aEntries))
|
||||
{
|
||||
if (array_key_exists($sEntryId, $this->aEntries)) {
|
||||
// Recompute case logs metadata only if necessary
|
||||
$oEntry = $this->aEntries[$sEntryId];
|
||||
if ($oEntry instanceof CaseLogEntry)
|
||||
{
|
||||
if ($oEntry instanceof CaseLogEntry) {
|
||||
$sCaseLogAttCode = $oEntry->GetAttCode();
|
||||
$sAuthorLogin = $oEntry->GetAuthorLogin();
|
||||
|
||||
@@ -463,8 +450,7 @@ class ActivityPanel extends UIBlock
|
||||
$this->aCaseLogs[$sCaseLogAttCode]['total_messages_count']--;
|
||||
// - Authors
|
||||
$this->aCaseLogs[$sCaseLogAttCode]['authors'][$sAuthorLogin]['messages_count']--;
|
||||
if($this->aCaseLogs[$sCaseLogAttCode]['authors'][$sAuthorLogin]['messages_count'] === 0)
|
||||
{
|
||||
if ($this->aCaseLogs[$sCaseLogAttCode]['authors'][$sAuthorLogin]['messages_count'] === 0) {
|
||||
unset($this->aCaseLogs[$sCaseLogAttCode]['authors'][$sAuthorLogin]);
|
||||
}
|
||||
}
|
||||
@@ -563,8 +549,7 @@ class ActivityPanel extends UIBlock
|
||||
protected function AddCaseLogTab(string $sAttCode)
|
||||
{
|
||||
// Add case log only if not already existing
|
||||
if (!array_key_exists($sAttCode, $this->aCaseLogs))
|
||||
{
|
||||
if (!array_key_exists($sAttCode, $this->aCaseLogs)) {
|
||||
$iFlags = ($this->GetObject()->IsNew()) ? $this->GetObject()->GetInitialStateAttributeFlags($sAttCode) : $this->GetObject()->GetAttributeFlags($sAttCode);
|
||||
$bIsHidden = (OPT_ATT_HIDDEN === ($iFlags & OPT_ATT_HIDDEN));
|
||||
$bIsReadOnly = (OPT_ATT_READONLY === ($iFlags & OPT_ATT_READONLY));
|
||||
@@ -614,8 +599,7 @@ class ActivityPanel extends UIBlock
|
||||
*/
|
||||
protected function RemoveCaseLogTab(string $sAttCode)
|
||||
{
|
||||
if (array_key_exists($sAttCode, $this->aCaseLogs))
|
||||
{
|
||||
if (array_key_exists($sAttCode, $this->aCaseLogs)) {
|
||||
unset($this->aCaseLogs[$sAttCode]);
|
||||
}
|
||||
|
||||
@@ -693,7 +677,7 @@ class ActivityPanel extends UIBlock
|
||||
*/
|
||||
public function SetCaseLogTabEntryForm(string $sCaseLogId, CaseLogEntryForm $oCaseLogEntryForm)
|
||||
{
|
||||
if ($this->HasCaseLogTab($sCaseLogId)){
|
||||
if ($this->HasCaseLogTab($sCaseLogId)) {
|
||||
$this->aCaseLogTabsEntryForms[$sCaseLogId] = $oCaseLogEntryForm;
|
||||
}
|
||||
|
||||
@@ -743,8 +727,7 @@ class ActivityPanel extends UIBlock
|
||||
foreach ($this->GetCaseLogTabsEntryForms() as $oCaseLogEntryForm) {
|
||||
if ($oCaseLogEntryForm->IsSubmitAutonomous()) {
|
||||
$iAutonomousSubmission++;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$iBridgedSubmissions++;
|
||||
}
|
||||
}
|
||||
@@ -948,7 +931,7 @@ class ActivityPanel extends UIBlock
|
||||
*/
|
||||
public function GetSubBlocks(): array
|
||||
{
|
||||
$aSubBlocks = array();
|
||||
$aSubBlocks = [];
|
||||
|
||||
foreach ($this->GetCaseLogTabsEntryForms() as $sCaseLogId => $oCaseLogEntryForm) {
|
||||
$aSubBlocks[$oCaseLogEntryForm->GetId()] = $oCaseLogEntryForm;
|
||||
@@ -967,4 +950,4 @@ class ActivityPanel extends UIBlock
|
||||
{
|
||||
return \UserRights::IsActionAllowed($this->GetObjectClass(), UR_ACTION_MODIFY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
@@ -61,9 +62,9 @@ class NiceWebPage extends WebPage
|
||||
'js/searchformforeignkeys.js',
|
||||
];
|
||||
|
||||
const DEFAULT_PAGE_TEMPLATE_REL_PATH = 'pages/backoffice/nicewebpage/layout';
|
||||
public const DEFAULT_PAGE_TEMPLATE_REL_PATH = 'pages/backoffice/nicewebpage/layout';
|
||||
|
||||
var $m_sRootUrl;
|
||||
public $m_sRootUrl;
|
||||
|
||||
public function __construct($s_title, $bPrintable = false)
|
||||
{
|
||||
@@ -145,8 +146,7 @@ JS
|
||||
$this->LinkScriptFromAppRoot('node_modules/jquery/dist/jquery.min.js');
|
||||
$this->LinkScriptFromAppRoot('js/ajax_hook.js');
|
||||
$this->LinkScriptFromAppRoot('js/jquery.blockUI.js');
|
||||
if (utils::IsDevelopmentEnvironment()) // Needed since many other plugins still rely on oldies like $.browser
|
||||
{
|
||||
if (utils::IsDevelopmentEnvironment()) { // Needed since many other plugins still rely on oldies like $.browser
|
||||
$this->LinkScriptFromAppRoot('js/jquery-migrate.dev-params.js');
|
||||
$this->LinkScriptFromAppRoot('node_modules/jquery-migrate/dist/jquery-migrate.js');
|
||||
} else {
|
||||
@@ -170,11 +170,10 @@ JS
|
||||
$this->add_dict_entries('UI:Combo');
|
||||
}
|
||||
|
||||
|
||||
public function SetRootUrl($sRootUrl)
|
||||
{
|
||||
$this->m_sRootUrl = $sRootUrl;
|
||||
}
|
||||
{
|
||||
$this->m_sRootUrl = $sRootUrl;
|
||||
}
|
||||
|
||||
public function small_p($sText)
|
||||
{
|
||||
@@ -191,7 +190,7 @@ JS
|
||||
return utils::GetAbsoluteUrlModulesRoot();
|
||||
}
|
||||
|
||||
function GetApplicationContext()
|
||||
public function GetApplicationContext()
|
||||
{
|
||||
$oAppContext = new ApplicationContext();
|
||||
return $oAppContext->GetForLink();
|
||||
@@ -203,11 +202,9 @@ JS
|
||||
// $aTopLevelClasses = array('bizService', 'bizContact', 'logInfra', 'bizDocument');
|
||||
// These are classes wich root class is cmdbAbstractObject !
|
||||
$this->add("<select id=\"select_$sName\" name=\"$sName\">");
|
||||
$aValidClasses = array();
|
||||
foreach(MetaModel::GetClasses('bizmodel') as $sClassName)
|
||||
{
|
||||
if (is_null($iActionCode) || UserRights::IsActionAllowed($sClassName, $iActionCode))
|
||||
{
|
||||
$aValidClasses = [];
|
||||
foreach (MetaModel::GetClasses('bizmodel') as $sClassName) {
|
||||
if (is_null($iActionCode) || UserRights::IsActionAllowed($sClassName, $iActionCode)) {
|
||||
$sSelected = ($sClassName == $sDefaultValue) ? " SELECTED" : "";
|
||||
$sDescription = MetaModel::GetClassDescription($sClassName);
|
||||
$sDisplayName = MetaModel::GetName($sClassName);
|
||||
@@ -224,8 +221,7 @@ JS
|
||||
public function add_select($aChoices, $sName, $sDefaultValue, $iWidthPx)
|
||||
{
|
||||
$this->add("<select id=\"select_$sName\" name=\"$sName\">");
|
||||
foreach($aChoices as $sKey => $sValue)
|
||||
{
|
||||
foreach ($aChoices as $sKey => $sValue) {
|
||||
$sSelected = ($sKey == $sDefaultValue) ? " SELECTED" : "";
|
||||
$this->add("<option style=\"width: ".$iWidthPx." px;\" value=\"".htmlspecialchars($sKey)."\"$sSelected>".utils::EscapeHtml($sValue)."</option>");
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -30,10 +31,10 @@ use MetaModel;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use UserRights;
|
||||
use utils;
|
||||
|
||||
use const APPROOT;
|
||||
use const MODULESROOT;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Simple helper class to ease the production of HTML pages
|
||||
*
|
||||
@@ -64,7 +65,7 @@ class WebPage implements Page
|
||||
/**
|
||||
* @since 2.7.0 N°2529
|
||||
*/
|
||||
const PAGES_CHARSET = 'utf-8';
|
||||
public const PAGES_CHARSET = 'utf-8';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
@@ -149,7 +150,7 @@ class WebPage implements Page
|
||||
* @var string Rel. path to the template to use for the rendering. File name must be without the extension.
|
||||
* @since 3.0.0
|
||||
*/
|
||||
const DEFAULT_PAGE_TEMPLATE_REL_PATH = 'pages/backoffice/webpage/layout';
|
||||
public const DEFAULT_PAGE_TEMPLATE_REL_PATH = 'pages/backoffice/webpage/layout';
|
||||
|
||||
protected $s_title;
|
||||
protected $s_content;
|
||||
@@ -210,7 +211,6 @@ class WebPage implements Page
|
||||
protected $oContentLayout;
|
||||
protected $sTemplateRelPath;
|
||||
|
||||
|
||||
/**
|
||||
* @var bool|string|string[]
|
||||
*/
|
||||
@@ -341,7 +341,7 @@ class WebPage implements Page
|
||||
* @return void
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function add_twig_template($sViewPath, $sTemplateName, $aParams = array(), $sDefaultType = 'html')
|
||||
public function add_twig_template($sViewPath, $sTemplateName, $aParams = [], $sDefaultType = 'html')
|
||||
{
|
||||
TwigHelper::RenderIntoPage($this, $sViewPath, $sTemplateName, $aParams, $sDefaultType);
|
||||
}
|
||||
@@ -399,7 +399,7 @@ class WebPage implements Page
|
||||
* @inheritDoc
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function table($aConfig, $aData, $aParams = array())
|
||||
public function table($aConfig, $aData, $aParams = [])
|
||||
{
|
||||
$oDataTable = $this->GetTableBlock($aConfig, $aData);
|
||||
$oDataTable->AddOption("bFullscreen", true);
|
||||
@@ -421,7 +421,7 @@ class WebPage implements Page
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function GetTable($aConfig, $aData, $aParams = array())
|
||||
public function GetTable($aConfig, $aData, $aParams = [])
|
||||
{
|
||||
static $iNbTables = 0;
|
||||
$iNbTables++;
|
||||
@@ -429,15 +429,13 @@ class WebPage implements Page
|
||||
$sHtml .= "<table class=\"listResults\">\n";
|
||||
$sHtml .= "<thead>\n";
|
||||
$sHtml .= "<tr>\n";
|
||||
foreach ($aConfig as $sName => $aDef)
|
||||
{
|
||||
foreach ($aConfig as $sName => $aDef) {
|
||||
$sHtml .= "<th title=\"".$aDef['description']."\">".$aDef['label']."</th>\n";
|
||||
}
|
||||
$sHtml .= "</tr>\n";
|
||||
$sHtml .= "</thead>\n";
|
||||
$sHtml .= "<tbody>\n";
|
||||
foreach ($aData as $aRow)
|
||||
{
|
||||
foreach ($aData as $aRow) {
|
||||
$sHtml .= $this->GetTableRow($aRow, $aConfig);
|
||||
}
|
||||
$sHtml .= "</tbody>\n";
|
||||
@@ -455,25 +453,19 @@ class WebPage implements Page
|
||||
public function GetTableRow($aRow, $aConfig)
|
||||
{
|
||||
$sHtml = '';
|
||||
if (isset($aRow['@class'])) // Row specific class, for hilighting certain rows
|
||||
{
|
||||
if (isset($aRow['@class'])) { // Row specific class, for hilighting certain rows
|
||||
$sHtml .= "<tr class=\"{$aRow['@class']}\">";
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$sHtml .= "<tr>";
|
||||
}
|
||||
foreach ($aConfig as $sName => $aAttribs)
|
||||
{
|
||||
foreach ($aConfig as $sName => $aAttribs) {
|
||||
$sClass = isset($aAttribs['class']) ? 'class="'.$aAttribs['class'].'"' : '';
|
||||
|
||||
// Prepare metadata
|
||||
// - From table config.
|
||||
$sMetadata = '';
|
||||
if(isset($aAttribs['metadata']))
|
||||
{
|
||||
foreach($aAttribs['metadata'] as $sMetadataProp => $sMetadataValue)
|
||||
{
|
||||
if (isset($aAttribs['metadata'])) {
|
||||
foreach ($aAttribs['metadata'] as $sMetadataProp => $sMetadataValue) {
|
||||
$sMetadataPropSanitized = str_replace('_', '-', $sMetadataProp);
|
||||
$sMetadataValueSanitized = utils::HtmlEntities($sMetadataValue);
|
||||
$sMetadata .= 'data-'.$sMetadataPropSanitized.'="'.$sMetadataValueSanitized.'" ';
|
||||
@@ -481,13 +473,10 @@ class WebPage implements Page
|
||||
}
|
||||
|
||||
// Prepare value
|
||||
if(is_array($aRow[$sName]))
|
||||
{
|
||||
if (is_array($aRow[$sName])) {
|
||||
$sValueHtml = ($aRow[$sName]['value_html'] === '') ? ' ' : $aRow[$sName]['value_html'];
|
||||
$sMetadata .= 'data-value-raw="'.utils::HtmlEntities($aRow[$sName]['value_raw']).'" ';
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$sValueHtml = ($aRow[$sName] === '') ? ' ' : $aRow[$sName];
|
||||
}
|
||||
|
||||
@@ -555,7 +544,7 @@ class WebPage implements Page
|
||||
|
||||
// Ensure file is within the app folder
|
||||
$sFileRelPathWithoutQueryParams = explode("?", $sFileRelPath)[0];
|
||||
if (false === utils::RealPath(APPROOT . $sFileRelPathWithoutQueryParams, APPROOT)) {
|
||||
if (false === utils::RealPath(APPROOT.$sFileRelPathWithoutQueryParams, APPROOT)) {
|
||||
IssueLog::Warning("Linked resource added to page with a path from outside app directory, it will be ignored.", LogChannels::CONSOLE, [
|
||||
"linked_resource_uri" => $sFileRelPath,
|
||||
"request_uri" => $_SERVER['REQUEST_URI'] ?? '' /* CLI */,
|
||||
@@ -570,7 +559,7 @@ class WebPage implements Page
|
||||
$sAppRootUrl .= '/';
|
||||
}
|
||||
|
||||
$this->LinkResourceFromURI($sAppRootUrl . $sFileRelPath, $sResourceType);
|
||||
$this->LinkResourceFromURI($sAppRootUrl.$sFileRelPath, $sResourceType);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -593,7 +582,7 @@ class WebPage implements Page
|
||||
|
||||
// Ensure file is within the app folder
|
||||
$sFileRelPathWithoutQueryParams = explode("?", $sFileRelPath)[0];
|
||||
$sFileAbsPath = MODULESROOT . $sFileRelPathWithoutQueryParams;
|
||||
$sFileAbsPath = MODULESROOT.$sFileRelPathWithoutQueryParams;
|
||||
// For modules only, we don't check real path if symlink as the file would not be in under MODULESROOT
|
||||
if (false === is_link($sFileAbsPath) && false === utils::RealPath($sFileAbsPath, MODULESROOT)) {
|
||||
IssueLog::Warning("Linked resource added to page with a path from outside current env. directory, it will be ignored.", LogChannels::CONSOLE, [
|
||||
@@ -603,7 +592,7 @@ class WebPage implements Page
|
||||
return;
|
||||
}
|
||||
|
||||
$this->LinkResourceFromURI(utils::GetAbsoluteUrlModulesRoot() . $sFileRelPath, $sResourceType);
|
||||
$this->LinkResourceFromURI(utils::GetAbsoluteUrlModulesRoot().$sFileRelPath, $sResourceType);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1019,8 +1008,10 @@ class WebPage implements Page
|
||||
*/
|
||||
protected function get_dict_signature()
|
||||
{
|
||||
return str_replace('_', '', Dict::GetUserLanguage()).'-'.md5(implode(',',
|
||||
$this->a_dict_entries).'|'.implode(',', $this->a_dict_entries_prefixes));
|
||||
return str_replace('_', '', Dict::GetUserLanguage()).'-'.md5(implode(
|
||||
',',
|
||||
$this->a_dict_entries
|
||||
).'|'.implode(',', $this->a_dict_entries_prefixes));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1028,13 +1019,11 @@ class WebPage implements Page
|
||||
*/
|
||||
protected function get_dict_file_content()
|
||||
{
|
||||
$aEntries = array();
|
||||
foreach ($this->a_dict_entries as $sCode)
|
||||
{
|
||||
$aEntries = [];
|
||||
foreach ($this->a_dict_entries as $sCode) {
|
||||
$aEntries[$sCode] = Dict::S($sCode);
|
||||
}
|
||||
foreach ($this->a_dict_entries_prefixes as $sPrefix)
|
||||
{
|
||||
foreach ($this->a_dict_entries_prefixes as $sPrefix) {
|
||||
$aEntries = array_merge($aEntries, Dict::ExportEntries($sPrefix));
|
||||
}
|
||||
|
||||
@@ -1168,8 +1157,7 @@ JS;
|
||||
{
|
||||
$sCssRelPath = utils::GetCSSFromSASS($sSaasRelPath);
|
||||
$sRootUrl = utils::GetAbsoluteUrlAppRoot();
|
||||
if ($sRootUrl === '')
|
||||
{
|
||||
if ($sRootUrl === '') {
|
||||
// We're running the setup of the first install...
|
||||
$sRootUrl = '../';
|
||||
}
|
||||
@@ -1323,8 +1311,7 @@ JS;
|
||||
$aPossibleAttFlags = MetaModel::EnumPossibleAttributeFlags();
|
||||
|
||||
$sHtml = "<div class=\"ibo-details\">\n";
|
||||
foreach ($aFields as $aAttrib)
|
||||
{
|
||||
foreach ($aFields as $aAttrib) {
|
||||
$sLayout = isset($aAttrib['layout']) ? $aAttrib['layout'] : 'small';
|
||||
|
||||
// Prepare metadata attributes
|
||||
@@ -1335,13 +1322,10 @@ JS;
|
||||
$sDataInputType = isset($aAttrib['inputtype']) ? 'data-input-type="'.utils::HtmlEntities($aAttrib['inputtype']).'"' : '';
|
||||
// - Attribute flags
|
||||
$sDataAttributeFlags = '';
|
||||
if(isset($aAttrib['attflags']))
|
||||
{
|
||||
foreach($aPossibleAttFlags as $sFlagCode => $iFlagValue)
|
||||
{
|
||||
if (isset($aAttrib['attflags'])) {
|
||||
foreach ($aPossibleAttFlags as $sFlagCode => $iFlagValue) {
|
||||
// Note: Skip normal flag as we don't need it.
|
||||
if($sFlagCode === 'normal')
|
||||
{
|
||||
if ($sFlagCode === 'normal') {
|
||||
continue;
|
||||
}
|
||||
$sFormattedFlagCode = str_ireplace('_', '-', $sFlagCode);
|
||||
@@ -1356,23 +1340,18 @@ JS;
|
||||
$sHtml .= "<div class=\"ibo-field--label\">{$aAttrib['label']}</div>\n";
|
||||
|
||||
// By Rom, for csv import, proposed to show several values for column selection
|
||||
if (is_array($aAttrib['value']))
|
||||
{
|
||||
if (is_array($aAttrib['value'])) {
|
||||
$sHtml .= "<div class=\"ibo-field--value\">".implode("</div><div>", $aAttrib['value'])."</div>\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$sHtml .= "<div class=\"ibo-field--value\">".$aAttrib['value']."</div>\n";
|
||||
}
|
||||
// Checking if we should add comments & infos
|
||||
$sComment = (isset($aAttrib['comments'])) ? $aAttrib['comments'] : '';
|
||||
$sInfo = (isset($aAttrib['infos'])) ? $aAttrib['infos'] : '';
|
||||
if ($sComment !== '')
|
||||
{
|
||||
if ($sComment !== '') {
|
||||
$sHtml .= "<div class=\"ibo-field--comments\">$sComment</div>\n";
|
||||
}
|
||||
if ($sInfo !== '')
|
||||
{
|
||||
if ($sInfo !== '') {
|
||||
$sHtml .= "<div class=\"ibo-field--infos\">$sInfo</div>\n";
|
||||
}
|
||||
|
||||
@@ -1397,26 +1376,26 @@ JS;
|
||||
* @return string The HTML fragment corresponding to the radio buttons
|
||||
*/
|
||||
public function GetRadioButtons(
|
||||
$aAllowedValues, $value, $iId, $sFieldName, $bMandatory, $bVertical, $sValidationField
|
||||
$aAllowedValues,
|
||||
$value,
|
||||
$iId,
|
||||
$sFieldName,
|
||||
$bMandatory,
|
||||
$bVertical,
|
||||
$sValidationField
|
||||
) {
|
||||
$idx = 0;
|
||||
$sHTMLValue = '';
|
||||
foreach ($aAllowedValues as $key => $display_value)
|
||||
{
|
||||
if ((count($aAllowedValues) == 1) && ($bMandatory == 'true'))
|
||||
{
|
||||
foreach ($aAllowedValues as $key => $display_value) {
|
||||
if ((count($aAllowedValues) == 1) && ($bMandatory == 'true')) {
|
||||
// When there is only once choice, select it by default
|
||||
$sSelected = 'checked';
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$sSelected = ($value == $key) ? 'checked' : '';
|
||||
}
|
||||
$sHTMLValue .= "<input type=\"radio\" id=\"{$iId}_{$key}\" name=\"radio_$sFieldName\" onChange=\"$('#{$iId}').val(this.value).trigger('change');\" value=\"$key\" $sSelected><label class=\"radio\" for=\"{$iId}_{$key}\"> $display_value</label> ";
|
||||
if ($bVertical)
|
||||
{
|
||||
if ($idx == 0)
|
||||
{
|
||||
if ($bVertical) {
|
||||
if ($idx == 0) {
|
||||
// Validation icon at the end of the first line
|
||||
$sHTMLValue .= " {$sValidationField}\n";
|
||||
}
|
||||
@@ -1425,8 +1404,7 @@ JS;
|
||||
$idx++;
|
||||
}
|
||||
$sHTMLValue .= "<input type=\"hidden\" id=\"$iId\" name=\"$sFieldName\" value=\"$value\"/>";
|
||||
if (!$bVertical)
|
||||
{
|
||||
if (!$bVertical) {
|
||||
// Validation icon at the end of the line
|
||||
$sHTMLValue .= " {$sValidationField}\n";
|
||||
}
|
||||
@@ -1457,26 +1435,18 @@ JS;
|
||||
protected function ob_get_clean_safe()
|
||||
{
|
||||
$sOutput = ob_get_contents();
|
||||
if ($sOutput === false)
|
||||
{
|
||||
if ($sOutput === false) {
|
||||
$sMsg = "Design/integration issue: No output buffer. Some piece of code has called ob_get_clean() or ob_end_clean() without calling ob_start()";
|
||||
if ($this->bTrashUnexpectedOutput)
|
||||
{
|
||||
if ($this->bTrashUnexpectedOutput) {
|
||||
IssueLog::Error($sMsg);
|
||||
$sOutput = '';
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$sOutput = $sMsg;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ob_end_clean(); // on some versions of PHP doing so when the output buffering is stopped can cause a notice
|
||||
if ($this->bTrashUnexpectedOutput)
|
||||
{
|
||||
if (trim($sOutput) != '')
|
||||
{
|
||||
if ($this->bTrashUnexpectedOutput) {
|
||||
if (trim($sOutput) != '') {
|
||||
if (Utils::GetConfig() && Utils::GetConfig()->Get('debug_report_spurious_chars')) {
|
||||
IssueLog::Error("Trashing unexpected output:'$sOutput'\n");
|
||||
}
|
||||
@@ -1706,11 +1676,10 @@ JS;
|
||||
*
|
||||
* @return bool True if the format is Ok, false otherwise
|
||||
*/
|
||||
function IsOutputFormatAvailable($sOutputFormat)
|
||||
public function IsOutputFormatAvailable($sOutputFormat)
|
||||
{
|
||||
$bResult = false;
|
||||
switch ($sOutputFormat)
|
||||
{
|
||||
switch ($sOutputFormat) {
|
||||
case 'html':
|
||||
$bResult = true; // Always supported
|
||||
break;
|
||||
@@ -1743,8 +1712,7 @@ JS;
|
||||
*/
|
||||
public function GetOutputOption($sFormat, $sOptionName)
|
||||
{
|
||||
if (isset($this->a_OutputOptions[$sFormat][$sOptionName]))
|
||||
{
|
||||
if (isset($this->a_OutputOptions[$sFormat][$sOptionName])) {
|
||||
return $this->a_OutputOptions[$sFormat][$sOptionName];
|
||||
}
|
||||
|
||||
@@ -1760,12 +1728,9 @@ JS;
|
||||
*/
|
||||
public function SetOutputOption($sFormat, $sOptionName, $sValue)
|
||||
{
|
||||
if (!isset($this->a_OutputOptions[$sFormat]))
|
||||
{
|
||||
$this->a_OutputOptions[$sFormat] = array($sOptionName => $sValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!isset($this->a_OutputOptions[$sFormat])) {
|
||||
$this->a_OutputOptions[$sFormat] = [$sOptionName => $sValue];
|
||||
} else {
|
||||
$this->a_OutputOptions[$sFormat][$sOptionName] = $sValue;
|
||||
}
|
||||
}
|
||||
@@ -1776,7 +1741,7 @@ JS;
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function RenderPopupMenuItems($aActions, $aFavoriteActions = array())
|
||||
public function RenderPopupMenuItems($aActions, $aFavoriteActions = [])
|
||||
{
|
||||
$sPrevUrl = '';
|
||||
$sHtml = '';
|
||||
@@ -1784,12 +1749,14 @@ JS;
|
||||
foreach ($aActions as $sActionId => $aAction) {
|
||||
$sDataActionId = 'data-action-id="'.$sActionId.'"';
|
||||
$sClass = isset($aAction['css_classes']) ? 'class="'.implode(' ', $aAction['css_classes']).'"' : '';
|
||||
$sOnClick = isset($aAction['onclick']) ? 'onclick="'.htmlspecialchars($aAction['onclick'], ENT_QUOTES,
|
||||
"UTF-8").'"' : '';
|
||||
$sOnClick = isset($aAction['onclick']) ? 'onclick="'.htmlspecialchars(
|
||||
$aAction['onclick'],
|
||||
ENT_QUOTES,
|
||||
"UTF-8"
|
||||
).'"' : '';
|
||||
$sTarget = isset($aAction['target']) ? "target=\"{$aAction['target']}\"" : "";
|
||||
if (empty($aAction['url'])) {
|
||||
if ($sPrevUrl != '') // Don't output consecutively two separators...
|
||||
{
|
||||
if ($sPrevUrl != '') { // Don't output consecutively two separators...
|
||||
$sHtml .= "<li $sDataActionId>{$aAction['label']}</li>";
|
||||
}
|
||||
$sPrevUrl = '';
|
||||
@@ -1859,8 +1826,6 @@ JS;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return the language for the page metadata based on the current user
|
||||
*
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -48,11 +49,11 @@ use utils;
|
||||
class iTopWebPage extends NiceWebPage implements iTabbedPage
|
||||
{
|
||||
/** @var string ENUM_BREADCRUMB_ENTRY_ICON_TYPE_IMAGE */
|
||||
const ENUM_BREADCRUMB_ENTRY_ICON_TYPE_IMAGE = 'image';
|
||||
public const ENUM_BREADCRUMB_ENTRY_ICON_TYPE_IMAGE = 'image';
|
||||
/** @var string ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES */
|
||||
const ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES = 'css_classes';
|
||||
public const ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES = 'css_classes';
|
||||
/** @var string DEFAULT_BREADCRUMB_ENTRY_ICON_TYPE */
|
||||
const DEFAULT_BREADCRUMB_ENTRY_ICON_TYPE = self::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_IMAGE;
|
||||
public const DEFAULT_BREADCRUMB_ENTRY_ICON_TYPE = self::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_IMAGE;
|
||||
|
||||
/** @inheritDoc */
|
||||
protected const COMPATIBILITY_MOVED_LINKED_SCRIPTS_REL_PATH = [
|
||||
@@ -79,7 +80,7 @@ class iTopWebPage extends NiceWebPage implements iTabbedPage
|
||||
];
|
||||
|
||||
/** @var string DEFAULT_PAGE_TEMPLATE_REL_PATH The relative path (from <ITOP>/templates/) to the default page template */
|
||||
const DEFAULT_PAGE_TEMPLATE_REL_PATH = 'pages/backoffice/itopwebpage/layout';
|
||||
public const DEFAULT_PAGE_TEMPLATE_REL_PATH = 'pages/backoffice/itopwebpage/layout';
|
||||
|
||||
private $m_aMessages;
|
||||
|
||||
@@ -145,7 +146,7 @@ class iTopWebPage extends NiceWebPage implements iTabbedPage
|
||||
|
||||
utils::InitArchiveMode();
|
||||
|
||||
$this->m_aMessages = array();
|
||||
$this->m_aMessages = [];
|
||||
$this->SetRootUrl(utils::GetAbsoluteUrlAppRoot());
|
||||
$this->add_header("Content-type: text/html; charset=".self::PAGES_CHARSET);
|
||||
$this->no_cache();
|
||||
@@ -283,7 +284,7 @@ class iTopWebPage extends NiceWebPage implements iTabbedPage
|
||||
*/
|
||||
protected function PrepareLayout()
|
||||
{
|
||||
$aDaysMin = array(
|
||||
$aDaysMin = [
|
||||
Dict::S('DayOfWeek-Sunday-Min'),
|
||||
Dict::S('DayOfWeek-Monday-Min'),
|
||||
Dict::S('DayOfWeek-Tuesday-Min'),
|
||||
@@ -291,8 +292,8 @@ class iTopWebPage extends NiceWebPage implements iTabbedPage
|
||||
Dict::S('DayOfWeek-Thursday-Min'),
|
||||
Dict::S('DayOfWeek-Friday-Min'),
|
||||
Dict::S('DayOfWeek-Saturday-Min'),
|
||||
);
|
||||
$aMonthsShort = array(
|
||||
];
|
||||
$aMonthsShort = [
|
||||
Dict::S('Month-01-Short'),
|
||||
Dict::S('Month-02-Short'),
|
||||
Dict::S('Month-03-Short'),
|
||||
@@ -305,12 +306,12 @@ class iTopWebPage extends NiceWebPage implements iTabbedPage
|
||||
Dict::S('Month-10-Short'),
|
||||
Dict::S('Month-11-Short'),
|
||||
Dict::S('Month-12-Short'),
|
||||
);
|
||||
];
|
||||
$sTimeFormat = AttributeDateTime::GetFormat()->ToTimeFormat();
|
||||
$oTimeFormat = new DateTimeFormat($sTimeFormat);
|
||||
|
||||
// Date picker options
|
||||
$aPickerOptions = array(
|
||||
$aPickerOptions = [
|
||||
'showOn' => 'button',
|
||||
'buttonText' => '', // N°6455 class will be added after JQuery UI widget
|
||||
'dateFormat' => AttributeDate::GetFormat()->ToDatePicker(),
|
||||
@@ -320,7 +321,7 @@ class iTopWebPage extends NiceWebPage implements iTabbedPage
|
||||
'dayNamesMin' => $aDaysMin,
|
||||
'monthNamesShort' => $aMonthsShort,
|
||||
'firstDay' => (int)Dict::S('Calendar-FirstDayOfWeek'),
|
||||
);
|
||||
];
|
||||
$sJSDatePickerOptions = json_encode($aPickerOptions);
|
||||
|
||||
// Time picker additional options
|
||||
@@ -339,8 +340,7 @@ class iTopWebPage extends NiceWebPage implements iTabbedPage
|
||||
$aPickerOptions['controlType'] = 'select';
|
||||
$aPickerOptions['closeText'] = Dict::S('UI:Button:Ok');
|
||||
$sJSDateTimePickerOptions = json_encode($aPickerOptions);
|
||||
if ($sTimePickerLang != '"en"')
|
||||
{
|
||||
if ($sTimePickerLang != '"en"') {
|
||||
// More options that cannot be passed via json_encode since they must be evaluated client-side
|
||||
$aMoreJSOptions = ",
|
||||
'timeText': $.timepicker.regional[$sTimePickerLang].timeText,
|
||||
@@ -428,19 +428,18 @@ JS
|
||||
$.blockUI.defaults.message= '<i class="fas fa-fw fa-spin fa-sync-alt"></i>';
|
||||
$.blockUI.defaults.overlayCSS = {}
|
||||
JS
|
||||
);
|
||||
);
|
||||
|
||||
// TODO 3.0.0: To preserve
|
||||
$this->add_ready_script(InlineImage::FixImagesWidth());
|
||||
// TODO 3.0.0: To preserve
|
||||
$this->add_ready_script(InlineImage::FixImagesWidth());
|
||||
|
||||
// user pref for client side
|
||||
// see GetUserPreference() in utils.js
|
||||
$sUserPrefs = appUserPreferences::GetAsJSON();
|
||||
$this->add_script("var oUserPreferences = $sUserPrefs;");
|
||||
// user pref for client side
|
||||
// see GetUserPreference() in utils.js
|
||||
$sUserPrefs = appUserPreferences::GetAsJSON();
|
||||
$this->add_script("var oUserPreferences = $sUserPrefs;");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see static::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_IMAGE, static::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES
|
||||
*
|
||||
@@ -481,7 +480,6 @@ JS
|
||||
$this->GetTopBarLayout()->SetBreadcrumbs(new Breadcrumbs($this->GetBreadCrumbsNewEntry(), Breadcrumbs::BLOCK_CODE));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @return \Combodo\iTop\Application\UI\Base\Layout\NavigationMenu\NavigationMenu
|
||||
@@ -592,11 +590,9 @@ JS
|
||||
{
|
||||
$aNewEntry = null;
|
||||
|
||||
if ($this->bBreadCrumbEnabled)
|
||||
{
|
||||
if ($this->bBreadCrumbEnabled) {
|
||||
// Default entry values
|
||||
if (is_null($this->sBreadCrumbEntryId))
|
||||
{
|
||||
if (is_null($this->sBreadCrumbEntryId)) {
|
||||
$this->sBreadCrumbEntryId = $this->s_title;
|
||||
$this->sBreadCrumbEntryLabel = $this->s_title;
|
||||
$this->sBreadCrumbEntryDescription = $this->s_title;
|
||||
@@ -632,8 +628,7 @@ JS
|
||||
|
||||
// Call the extensions to add content to the page, warning they can also add styles or scripts through as they have access to the iTopWebPage
|
||||
/** @var \iPageUIBlockExtension $oExtensionInstance */
|
||||
foreach (MetaModel::EnumPlugins('iPageUIBlockExtension') as $oExtensionInstance)
|
||||
{
|
||||
foreach (MetaModel::EnumPlugins('iPageUIBlockExtension') as $oExtensionInstance) {
|
||||
$oBlock = $oExtensionInstance->GetBannerBlock();
|
||||
if ($oBlock) {
|
||||
$oBanner->AddSubBlock($oBlock);
|
||||
@@ -643,7 +638,6 @@ JS
|
||||
return $oBanner;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render the header UIBlock which can come from both iTop itself and from extensions
|
||||
*
|
||||
@@ -673,11 +667,10 @@ JS
|
||||
}
|
||||
|
||||
// Access mode
|
||||
$sRestrictionMessage ='';
|
||||
$sRestrictionMessage = '';
|
||||
if (!MetaModel::DBHasAccess(ACCESS_ADMIN_WRITE)) {
|
||||
$sRestrictionMessage = Dict::S('UI:AccessRO-All');
|
||||
}
|
||||
elseif (!MetaModel::DBHasAccess(ACCESS_USER_WRITE)) {
|
||||
} elseif (!MetaModel::DBHasAccess(ACCESS_USER_WRITE)) {
|
||||
$sRestrictionMessage = Dict::S('UI:AccessRO-Users');
|
||||
}
|
||||
|
||||
@@ -707,8 +700,7 @@ HTML;
|
||||
|
||||
// Call the extensions to add content to the page, warning they can also add styles or scripts through as they have access to the iTopWebPage
|
||||
/** @var \iPageUIBlockExtension $oExtensionInstance */
|
||||
foreach (MetaModel::EnumPlugins('iPageUIBlockExtension') as $oExtensionInstance)
|
||||
{
|
||||
foreach (MetaModel::EnumPlugins('iPageUIBlockExtension') as $oExtensionInstance) {
|
||||
$oBlock = $oExtensionInstance->GetHeaderBlock();
|
||||
if ($oBlock) {
|
||||
$oHeader->AddSubBlock($oBlock);
|
||||
@@ -718,7 +710,6 @@ HTML;
|
||||
return $oHeader;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render the footer UIBlock which can come from both iTop itself and from extensions
|
||||
*
|
||||
@@ -875,7 +866,7 @@ HTML;
|
||||
$aData['aLayouts']['oPageContent'] = $this->GetContentLayout();
|
||||
$aData['aDeferredBlocks']['oPageContent'] = $this->GetDeferredBlocks($this->GetContentLayout());
|
||||
// - Prepare generic templates
|
||||
$aData['aTemplates'] = array();
|
||||
$aData['aTemplates'] = [];
|
||||
|
||||
// TODO 3.1 Replace hardcoded 'Please wait' with dict entries
|
||||
|
||||
@@ -888,12 +879,12 @@ HTML;
|
||||
|
||||
// - Small loader template
|
||||
$oSmallLoaderTemplateContentBlock = new UIContentBlock();
|
||||
$oSmallLoaderTemplateContentBlock->AddSubBlock(SpinnerUIBlockFactory::MakeSmall(null , 'Please wait'));
|
||||
$oSmallLoaderTemplateContentBlock->AddSubBlock(SpinnerUIBlockFactory::MakeSmall(null, 'Please wait'));
|
||||
$aData['aTemplates'][] = TemplateUIBlockFactory::MakeForBlock('ibo-small-loading-placeholder-template', $oSmallLoaderTemplateContentBlock);
|
||||
|
||||
// - Large loader template
|
||||
$oLargeLoaderTemplateContentBlock = new UIContentBlock();
|
||||
$oLargeLoaderTemplateContentBlock->AddSubBlock(SpinnerUIBlockFactory::MakeLarge(null , 'Please wait'));
|
||||
$oLargeLoaderTemplateContentBlock->AddSubBlock(SpinnerUIBlockFactory::MakeLarge(null, 'Please wait'));
|
||||
$aData['aTemplates'][] = TemplateUIBlockFactory::MakeForBlock('ibo-large-loading-placeholder-template', $oLargeLoaderTemplateContentBlock);
|
||||
|
||||
// - Do not show again template
|
||||
@@ -954,7 +945,7 @@ HTML;
|
||||
*/
|
||||
public function AddTabContainer($sTabContainer, $sPrefix = '', iUIContentBlock $oParentBlock = null)
|
||||
{
|
||||
if(is_null($oParentBlock)) {
|
||||
if (is_null($oParentBlock)) {
|
||||
$oParentBlock = PanelUIBlockFactory::MakeNeutral('');
|
||||
$this->AddUiBlock($oParentBlock);
|
||||
}
|
||||
@@ -1056,14 +1047,11 @@ HTML;
|
||||
$sCurrentTabContainer = $this->m_oTabs->GetCurrentTabContainer();
|
||||
$sCurrentTab = $this->m_oTabs->GetCurrentTab();
|
||||
|
||||
if (!empty($sCurrentTabContainer) && !empty($sCurrentTab))
|
||||
{
|
||||
if (!empty($sCurrentTabContainer) && !empty($sCurrentTab)) {
|
||||
$iOffset = $this->m_oTabs->GetCurrentTabLength();
|
||||
|
||||
return array('tc' => $sCurrentTabContainer, 'tab' => $sCurrentTab, 'offset' => $iOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ['tc' => $sCurrentTabContainer, 'tab' => $sCurrentTab, 'offset' => $iOffset];
|
||||
} else {
|
||||
return parent::start_capture();
|
||||
}
|
||||
}
|
||||
@@ -1073,19 +1061,13 @@ HTML;
|
||||
*/
|
||||
public function end_capture($offset)
|
||||
{
|
||||
if (is_array($offset))
|
||||
{
|
||||
if ($this->m_oTabs->TabExists($offset['tc'], $offset['tab']))
|
||||
{
|
||||
if (is_array($offset)) {
|
||||
if ($this->m_oTabs->TabExists($offset['tc'], $offset['tab'])) {
|
||||
$sCaptured = $this->m_oTabs->TruncateTab($offset['tc'], $offset['tab'], $offset['offset']);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$sCaptured = '';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$sCaptured = parent::end_capture($offset);
|
||||
}
|
||||
|
||||
@@ -1112,13 +1094,12 @@ HTML;
|
||||
*/
|
||||
public function AddApplicationMessage($sHtmlMessage, $sHtmlIcon = null, $sTip = null)
|
||||
{
|
||||
if (strlen($sHtmlMessage))
|
||||
{
|
||||
$this->m_aMessages[] = array(
|
||||
if (strlen($sHtmlMessage)) {
|
||||
$this->m_aMessages[] = [
|
||||
'icon' => $sHtmlIcon,
|
||||
'message' => $sHtmlMessage,
|
||||
'tip' => $sTip,
|
||||
);
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user