mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-12 23:14:18 +01: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 (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
@@ -27,6 +28,4 @@ namespace Combodo\iTop\Controller;
|
||||
*/
|
||||
class AbstractAppController extends \Symfony\Bundle\FrameworkBundle\Controller\AbstractController
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -25,4 +26,4 @@ abstract class AbstractController implements iController
|
||||
{
|
||||
return isset($_SERVER['HTTP_X_REQUESTED_WITH']) && ($_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -98,11 +99,9 @@ class AjaxRenderController
|
||||
$aObj[$sAlias."/".$sAttCode] = $aObject[$sAlias]->GetAsHTML($sAttCode);
|
||||
$bExcludeRawValue = false;
|
||||
// Only retrieve raw (stored) value for simple fields
|
||||
foreach (cmdbAbstractObject::GetAttDefClassesToExcludeFromMarkupMetadataRawValue() as $sAttDefClassToExclude)
|
||||
{
|
||||
foreach (cmdbAbstractObject::GetAttDefClassesToExcludeFromMarkupMetadataRawValue() as $sAttDefClassToExclude) {
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||
if (is_a($oAttDef, $sAttDefClassToExclude, true))
|
||||
{
|
||||
if (is_a($oAttDef, $sAttDefClassToExclude, true)) {
|
||||
$bExcludeRawValue = true;
|
||||
break;
|
||||
}
|
||||
@@ -110,7 +109,7 @@ class AjaxRenderController
|
||||
|
||||
if (!$bExcludeRawValue) {
|
||||
$oRawValue = $aObject[$sAlias]->Get($sAttCode);
|
||||
if(($oRawValue instanceof AttributeTagSet) || ($oRawValue instanceof ormSet)){
|
||||
if (($oRawValue instanceof AttributeTagSet) || ($oRawValue instanceof ormSet)) {
|
||||
$aObj[$sAlias."/".$sAttCode."/raw"] = implode(", ", $oRawValue->GetValues());
|
||||
} else {
|
||||
$aObj[$sAlias."/".$sAttCode."/raw"] = $oRawValue;
|
||||
@@ -150,18 +149,18 @@ class AjaxRenderController
|
||||
$aErr = error_get_last();
|
||||
if (($aErr !== null) && ($aErr['type'] & (E_ERROR | E_PARSE | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR))) {
|
||||
ob_end_clean();
|
||||
echo json_encode(array('code' => 'error', 'percentage' => 100, 'message' => Dict::Format('UI:Error_Details', $aErr['message'])));
|
||||
echo json_encode(['code' => 'error', 'percentage' => 100, 'message' => Dict::Format('UI:Error_Details', $aErr['message'])]);
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
$token = utils::ReadParam('token', null);
|
||||
$sTokenForDisplay = utils::HtmlEntities($token);
|
||||
$aResult = array( // Fallback error, just in case
|
||||
$aResult = [ // Fallback error, just in case
|
||||
'code' => 'error',
|
||||
'percentage' => 100,
|
||||
'message' => "Export not found for token: '$sTokenForDisplay'",
|
||||
);
|
||||
];
|
||||
$data = '';
|
||||
if ($token === null) {
|
||||
if ($bTokenOnly) {
|
||||
@@ -171,14 +170,14 @@ class AjaxRenderController
|
||||
$sExpression = utils::ReadParam('expression', null, false, 'raw_data');
|
||||
$iQueryId = utils::ReadParam('query', null);
|
||||
if ($sExpression === null) {
|
||||
$oQuerySearch = DBObjectSearch::FromOQL('SELECT QueryOQL WHERE id = :query_id', array('query_id' => $iQueryId));
|
||||
$oQuerySearch = DBObjectSearch::FromOQL('SELECT QueryOQL WHERE id = :query_id', ['query_id' => $iQueryId]);
|
||||
$oQuerySearch->UpdateContextFromUser();
|
||||
$oQueries = new DBObjectSet($oQuerySearch);
|
||||
if ($oQueries->Count() > 0) {
|
||||
$oQuery = $oQueries->Fetch();
|
||||
$sExpression = $oQuery->Get('oql');
|
||||
} else {
|
||||
$aResult = array('code' => 'error', 'percentage' => 100, 'message' => "Invalid query phrasebook identifier: '$iQueryId'");
|
||||
$aResult = ['code' => 'error', 'percentage' => 100, 'message' => "Invalid query phrasebook identifier: '$iQueryId'"];
|
||||
}
|
||||
}
|
||||
if ($sExpression !== null) {
|
||||
@@ -226,10 +225,10 @@ class AjaxRenderController
|
||||
}
|
||||
$oPage->SetData($aResult);
|
||||
} catch (BulkExportException $e) {
|
||||
$aResult = array('code' => 'error', 'percentage' => 100, 'message' => utils::HtmlEntities($e->GetLocalizedMessage()));
|
||||
$aResult = ['code' => 'error', 'percentage' => 100, 'message' => utils::HtmlEntities($e->GetLocalizedMessage())];
|
||||
$oPage->SetData($aResult);
|
||||
} catch (Exception $e) {
|
||||
$aResult = array('code' => 'error', 'percentage' => 100, 'message' => utils::HtmlEntities($e->getMessage()));
|
||||
$aResult = ['code' => 'error', 'percentage' => 100, 'message' => utils::HtmlEntities($e->getMessage())];
|
||||
$oPage->SetData($aResult);
|
||||
}
|
||||
}
|
||||
@@ -249,7 +248,7 @@ class AjaxRenderController
|
||||
$oPage->SetData($aResult);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* @param string $sFilter
|
||||
*
|
||||
* @return array
|
||||
@@ -258,7 +257,7 @@ class AjaxRenderController
|
||||
public static function SearchAndRefresh(string $sFilter): array
|
||||
{
|
||||
$extraParams = utils::ReadParam('extra_params', '', false, 'raw_data');
|
||||
$aExtraParams = array();
|
||||
$aExtraParams = [];
|
||||
if (is_array($extraParams)) {
|
||||
$aExtraParams = $extraParams;
|
||||
} else {
|
||||
@@ -279,9 +278,9 @@ class AjaxRenderController
|
||||
|
||||
$sTableId = utils::ReadParam('list_id', '');
|
||||
$iLength = utils::ReadParam('end', 10, false, utils::ENUM_SANITIZATION_FILTER_INTEGER);
|
||||
$aColumns = utils::ReadParam('columns', array(), false, 'raw_data');
|
||||
$aColumns = utils::ReadParam('columns', [], false, 'raw_data');
|
||||
$sSelectMode = utils::ReadParam('select_mode', '');
|
||||
$aClassAliases = utils::ReadParam('class_aliases', array());
|
||||
$aClassAliases = utils::ReadParam('class_aliases', []);
|
||||
$aResult = DataTableUIBlockFactory::GetOptionsForRendering($aColumns, $sSelectMode, $sFilter, $iLength, $aClassAliases, $aExtraParams, $sTableId);
|
||||
|
||||
return $aResult;
|
||||
@@ -301,10 +300,10 @@ class AjaxRenderController
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
* @throws \OQLException
|
||||
*/
|
||||
public static function Search(string $sEncoding, string $sFilter):array
|
||||
public static function Search(string $sEncoding, string $sFilter): array
|
||||
{
|
||||
$extraParams = utils::ReadParam('extra_params', '', false, 'raw_data');
|
||||
$aExtraParams = array();
|
||||
$aExtraParams = [];
|
||||
if (is_array($extraParams)) {
|
||||
$aExtraParams = $extraParams;
|
||||
} else {
|
||||
@@ -340,8 +339,8 @@ class AjaxRenderController
|
||||
// The first column is used for the selection (radio / checkbox) and is not sortable
|
||||
$iSortCol--;
|
||||
}
|
||||
$aColumns = utils::ReadParam('columns', array(), false, 'raw_data');
|
||||
$aClassAliases = utils::ReadParam('class_aliases', array());
|
||||
$aColumns = utils::ReadParam('columns', [], false, 'raw_data');
|
||||
$aClassAliases = utils::ReadParam('class_aliases', []);
|
||||
|
||||
foreach ($aColumns as $sClass => $aAttCodes) {
|
||||
foreach ($aAttCodes as $sAttCode => $aAttProperties) {
|
||||
@@ -405,11 +404,11 @@ class AjaxRenderController
|
||||
IssueLog::Warning(
|
||||
"ajax.render.php received an invalid array for columns : check max_input_vars value in php.ini !",
|
||||
null,
|
||||
array(
|
||||
[
|
||||
'controller' => '\Combodo\iTop\Controller\AjaxRenderController::Search',
|
||||
'max_input_vars' => $iMaxInputVarsValue,
|
||||
'class.attcode with invalid format' => "$sClass.$sAttCode",
|
||||
)
|
||||
]
|
||||
);
|
||||
$aColumns[$sClass][$sAttCode]['checked'] = 'false';
|
||||
}
|
||||
@@ -417,20 +416,20 @@ class AjaxRenderController
|
||||
}
|
||||
|
||||
// Filter the list to removed linked set since we are not able to display them here
|
||||
$sIdName = isset($extraParams["id_for_select"])?$extraParams["id_for_select"]:"";
|
||||
$aOrderBy = array();
|
||||
$sIdName = isset($extraParams["id_for_select"]) ? $extraParams["id_for_select"] : "";
|
||||
$aOrderBy = [];
|
||||
$iSortIndex = 0;
|
||||
|
||||
$aColumnsLoad = array();
|
||||
$aColumnsLoad = [];
|
||||
foreach ($aClassAliases as $sAlias => $sClassName) {
|
||||
$aColumnsLoad[$sAlias] = array();
|
||||
$aColumnsLoad[$sAlias] = [];
|
||||
if (!isset($aColumns[$sAlias])) {
|
||||
continue;
|
||||
}
|
||||
// It's better to use default class order than asc first column when none specified by the request
|
||||
if($bForceSort && count(MetaModel::GetOrderByDefault($sClassName)) > 0){
|
||||
// It's better to use default class order than asc first column when none specified by the request
|
||||
if ($bForceSort && count(MetaModel::GetOrderByDefault($sClassName)) > 0) {
|
||||
$iSortCol = -1;
|
||||
|
||||
|
||||
$aDefaultOrder = MetaModel::GetOrderByDefault($sClassName);
|
||||
foreach ($aDefaultOrder as $sAttCode => $bOrder) {
|
||||
$aOrderBy[$sAlias.'.'.$sAttCode] = $bOrder;
|
||||
@@ -502,8 +501,8 @@ class AjaxRenderController
|
||||
$iPageSize = utils::ReadParam('page_size', 10, false, utils::ENUM_SANITIZATION_FILTER_INTEGER);
|
||||
$sTableId = utils::ReadParam('table_id', null, false, 'raw_data');
|
||||
$bSaveAsDefaults = (utils::ReadParam('defaults', 'true') == 'true');
|
||||
$aClassAliases = utils::ReadParam('class_aliases', array(), false, 'raw_data');
|
||||
$aColumns = utils::ReadParam('columns', array(), false, 'raw_data');
|
||||
$aClassAliases = utils::ReadParam('class_aliases', [], false, 'raw_data');
|
||||
$aColumns = utils::ReadParam('columns', [], false, 'raw_data');
|
||||
|
||||
foreach ($aColumns as $sAlias => $aList) {
|
||||
foreach ($aList as $sAttCode => $aData) {
|
||||
@@ -538,7 +537,7 @@ class AjaxRenderController
|
||||
public static function DatatableResetSettings(): bool
|
||||
{
|
||||
$sTableId = utils::ReadParam('table_id', null, false, 'raw_data');
|
||||
$aClassAliases = utils::ReadParam('class_aliases', array(), false, 'raw_data');
|
||||
$aClassAliases = utils::ReadParam('class_aliases', [], false, 'raw_data');
|
||||
$bResetAll = (utils::ReadParam('defaults', 'true') == 'true');
|
||||
|
||||
$oSettings = new DataTableSettings($aClassAliases, $sTableId);
|
||||
@@ -578,7 +577,7 @@ class AjaxRenderController
|
||||
// Security filtering
|
||||
$aFields = $oGroupByExp->ListRequiredFields();
|
||||
foreach ($aFields as $sFieldAlias) {
|
||||
$aMatches = array();
|
||||
$aMatches = [];
|
||||
if (preg_match('/^([^.]+)\\.([^.]+)$/', $sFieldAlias, $aMatches)) {
|
||||
$sFieldClass = $oFilter->GetClassName($aMatches[1]);
|
||||
$oAttDef = MetaModel::GetAttributeDef($sFieldClass, $aMatches[2]);
|
||||
@@ -610,10 +609,10 @@ class AjaxRenderController
|
||||
if (isset($aExtraParams['order_direction']) && isset($aExtraParams['order_by'])) {
|
||||
switch ($aExtraParams['order_by']) {
|
||||
case 'attribute':
|
||||
$aOrderBy = array('grouped_by_1' => ($aExtraParams['order_direction'] === 'asc'));
|
||||
$aOrderBy = ['grouped_by_1' => ($aExtraParams['order_direction'] === 'asc')];
|
||||
break;
|
||||
case 'function':
|
||||
$aOrderBy = array($sFctVar => ($aExtraParams['order_direction'] === 'asc'));
|
||||
$aOrderBy = [$sFctVar => ($aExtraParams['order_direction'] === 'asc')];
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -625,9 +624,9 @@ class AjaxRenderController
|
||||
|
||||
$aRes = CMDBSource::QueryToArray($sSql);
|
||||
|
||||
$aGroupBy = array();
|
||||
$aLabels = array();
|
||||
$aValues = array();
|
||||
$aGroupBy = [];
|
||||
$aLabels = [];
|
||||
$aValues = [];
|
||||
$iTotalCount = 0;
|
||||
foreach ($aRes as $iRow => $aRow) {
|
||||
$sValue = $aRow['grouped_by_1'];
|
||||
@@ -638,7 +637,7 @@ class AjaxRenderController
|
||||
$iTotalCount += $aRow['_itop_count_'];
|
||||
}
|
||||
|
||||
$aResult = array();
|
||||
$aResult = [];
|
||||
$oAppContext = new ApplicationContext();
|
||||
$sParams = $oAppContext->GetForLink(true);
|
||||
foreach ($aGroupBy as $iRow => $iCount) {
|
||||
@@ -649,14 +648,14 @@ class AjaxRenderController
|
||||
if (isset($aExtraParams['query_params'])) {
|
||||
$aQueryParams = $aExtraParams['query_params'];
|
||||
} else {
|
||||
$aQueryParams = array();
|
||||
$aQueryParams = [];
|
||||
}
|
||||
$sFilter = rawurlencode($oSubsetSearch->serialize(false, $aQueryParams));
|
||||
|
||||
$aResult[] = array(
|
||||
$aResult[] = [
|
||||
'group' => $aLabels[$iRow],
|
||||
'value' => "<a href=\"".utils::GetAbsoluteUrlAppRoot()."pages/UI.php?operation=search&dosearch=1$sParams&filter=$sFilter\">$iCount</a>",
|
||||
); // TO DO: add the context information
|
||||
]; // TO DO: add the context information
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -696,7 +695,7 @@ class AjaxRenderController
|
||||
$aExtraParams = utils::ReadParam('extra_params', '', false, 'raw_data');
|
||||
$oFilter = DBObjectSearch::FromOQL($sFilter);
|
||||
$oFilter->SetShowObsoleteData(utils::ShowObsoleteData());
|
||||
$aQueryParams = array();
|
||||
$aQueryParams = [];
|
||||
if (isset($aExtraParams['query_params'])) {
|
||||
$aQueryParams = $aExtraParams['query_params'];
|
||||
}
|
||||
@@ -810,7 +809,8 @@ class AjaxRenderController
|
||||
foreach ($aLicenses as $oLicense) {
|
||||
$oPage->add('<li><b>'.$oLicense->product.'</b>, © '.$oLicense->author.' is licensed under the <b>'.$oLicense->license_type.' license</b>. (<a id="toggle_'.$index.'" class="CollapsibleLabel" style="cursor:pointer;">Details</a>)');
|
||||
$oPage->add('<div id="license_'.$index.'" class="license_text ibo-is-html-content" style="display:none;overflow:auto;max-height:10em;font-size:small;border:1px #696969 solid;margin-bottom:1em; margin-top:0.5em;padding:0.5em;">'.$oLicense->text.'</div>');
|
||||
$oPage->add_ready_script(<<<JS
|
||||
$oPage->add_ready_script(
|
||||
<<<JS
|
||||
$("#toggle_$index").on('click', function() {
|
||||
$(this).toggleClass('open');
|
||||
$("#license_$index").slideToggle("normal");
|
||||
@@ -845,7 +845,7 @@ EOF
|
||||
);
|
||||
$sVersionString = Dict::Format('UI:iTopVersion:Short', ITOP_APPLICATION, ITOP_VERSION);
|
||||
$oPage->add('<div id="about_box"><div class="ibo-about-box--top-part">');
|
||||
$oPage->add('<div><a href="http://www.combodo.com" title="www.combodo.com" target="_blank"><img src="' . utils::GetAbsoluteUrlAppRoot() . 'images/logos/logo-combodo-dark.svg?t='.utils::GetCacheBusterTimestamp().'"/></a></div>');
|
||||
$oPage->add('<div><a href="http://www.combodo.com" title="www.combodo.com" target="_blank"><img src="'.utils::GetAbsoluteUrlAppRoot().'images/logos/logo-combodo-dark.svg?t='.utils::GetCacheBusterTimestamp().'"/></a></div>');
|
||||
$oPage->add('<div>'.$sVersionString.'</div>');
|
||||
$oPage->add("</div>");
|
||||
self::DisplayAboutLicenses($oPage);
|
||||
@@ -885,7 +885,7 @@ EOF
|
||||
|
||||
// Get the datamodel directory
|
||||
$oFilter = DBObjectSearch::FromOQL('SELECT ModuleInstallation WHERE name="datamodel"');
|
||||
$oSet = new DBObjectSet($oFilter, array('installed' => false)); // Most recent first
|
||||
$oSet = new DBObjectSet($oFilter, ['installed' => false]); // Most recent first
|
||||
$oLastInstall = $oSet->Fetch();
|
||||
$sLastInstallDate = $oLastInstall->Get('installed');
|
||||
$aDataModelInfo = json_decode($oLastInstall->Get('comment'), true);
|
||||
@@ -894,7 +894,7 @@ EOF
|
||||
require_once(APPROOT.'setup/runtimeenv.class.inc.php');
|
||||
$sCurrEnv = utils::GetCurrentEnvironment();
|
||||
$oRuntimeEnv = new RunTimeEnvironment($sCurrEnv);
|
||||
$aSearchDirs = array(APPROOT.$sDataModelSourceDir);
|
||||
$aSearchDirs = [APPROOT.$sDataModelSourceDir];
|
||||
if (file_exists(APPROOT.'extensions')) {
|
||||
$aSearchDirs[] = APPROOT.'extensions';
|
||||
}
|
||||
@@ -904,22 +904,22 @@ EOF
|
||||
}
|
||||
$aAvailableModules = $oRuntimeEnv->AnalyzeInstallation(MetaModel::GetConfig(), $aSearchDirs);
|
||||
|
||||
$aItopSettings = array('cron_max_execution_time', 'timezone');
|
||||
$aPHPSettings = array('memory_limit', 'max_execution_time', 'upload_max_filesize', 'post_max_size');
|
||||
$aMySQLSettings = array('max_allowed_packet', 'key_buffer_size', 'query_cache_size');
|
||||
$aMySQLStatuses = array('Key_read_requests', 'Key_reads');
|
||||
$aItopSettings = ['cron_max_execution_time', 'timezone'];
|
||||
$aPHPSettings = ['memory_limit', 'max_execution_time', 'upload_max_filesize', 'post_max_size'];
|
||||
$aMySQLSettings = ['max_allowed_packet', 'key_buffer_size', 'query_cache_size'];
|
||||
$aMySQLStatuses = ['Key_read_requests', 'Key_reads'];
|
||||
|
||||
if (extension_loaded('suhosin')) {
|
||||
$aPHPSettings[] = 'suhosin.post.max_vars';
|
||||
$aPHPSettings[] = 'suhosin.get.max_value_length';
|
||||
}
|
||||
|
||||
$aMySQLVars = array();
|
||||
$aMySQLVars = [];
|
||||
foreach (CMDBSource::QueryToArray('SHOW VARIABLES') as $aRow) {
|
||||
$aMySQLVars[$aRow['Variable_name']] = $aRow['Value'];
|
||||
}
|
||||
|
||||
$aMySQLStats = array();
|
||||
$aMySQLStats = [];
|
||||
foreach (CMDBSource::QueryToArray('SHOW GLOBAL STATUS') as $aRow) {
|
||||
$aMySQLStats[$aRow['Variable_name']] = $aRow['Value'];
|
||||
}
|
||||
@@ -927,7 +927,7 @@ EOF
|
||||
// Display
|
||||
//
|
||||
$oPage->add('<div id="about_box"><div class="ibo-about-box--top-part">');
|
||||
$oPage->add('<div><a href="http://www.combodo.com" title="www.combodo.com" target="_blank"><img src="' . utils::GetAbsoluteUrlAppRoot() . 'images/logos/logo-combodo-dark.svg?t='.utils::GetCacheBusterTimestamp().'"/></a></div>');
|
||||
$oPage->add('<div><a href="http://www.combodo.com" title="www.combodo.com" target="_blank"><img src="'.utils::GetAbsoluteUrlAppRoot().'images/logos/logo-combodo-dark.svg?t='.utils::GetCacheBusterTimestamp().'"/></a></div>');
|
||||
$oPage->add('<div>'.$sVersionString.'<br/>'.'MySQL: '.$sMySQLVersion.'<br/>'.'PHP: '.$sPHPVersion.'<br/></div>');
|
||||
$oPage->add("</div>");
|
||||
|
||||
@@ -964,7 +964,6 @@ EOF
|
||||
$oPage->add("</div>");
|
||||
$oPage->add('</fieldset>');
|
||||
|
||||
|
||||
// MUST NOT be localized, as the information given here will be sent to the support
|
||||
$oPage->add("<a id=\"collapse_support_details\" class=\"CollapsibleLabel\" href=\"#\">".Dict::S('UI:About:Support')."</a></br>\n");
|
||||
$oPage->add("<div id=\"support_details\">");
|
||||
@@ -1027,5 +1026,4 @@ EOF
|
||||
$oPage->add("</div>");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -122,8 +123,7 @@ class ActivityPanelController extends AbstractController
|
||||
|
||||
// Invoke extensions after the update of the object from the activity form
|
||||
/** @var \iApplicationUIExtension $oExtensionInstance */
|
||||
foreach(MetaModel::EnumPlugins('iApplicationUIExtension') as $oExtensionInstance)
|
||||
{
|
||||
foreach (MetaModel::EnumPlugins('iApplicationUIExtension') as $oExtensionInstance) {
|
||||
$oExtensionInstance->OnFormSubmit($oObject);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -68,7 +69,7 @@ class ObjectController extends AbstractController
|
||||
$bCheckSubClass = utils::ReadParam('checkSubclass', true);
|
||||
$oAppContext = new ApplicationContext();
|
||||
$oRouter = Router::GetInstance();
|
||||
|
||||
|
||||
if ($this->IsHandlingXmlHttpRequest()) {
|
||||
$oPage = new AjaxPage('');
|
||||
} else {
|
||||
@@ -77,9 +78,7 @@ class ObjectController extends AbstractController
|
||||
$this->AddRequiredForModificationJsFilesToPage($oPage);
|
||||
}
|
||||
|
||||
|
||||
if (empty($sClass))
|
||||
{
|
||||
if (empty($sClass)) {
|
||||
throw new ApplicationException(Dict::Format('UI:Error:1ParametersMissing', 'class'));
|
||||
}
|
||||
if (!is_subclass_of($sClass, cmdbAbstractObject::class)) {
|
||||
@@ -87,43 +86,36 @@ class ObjectController extends AbstractController
|
||||
}
|
||||
// If the specified class has subclasses, ask the user an instance of which class to create
|
||||
$aSubClasses = MetaModel::EnumChildClasses($sClass, ENUM_CHILD_CLASSES_ALL); // Including the specified class itself
|
||||
$aPossibleClasses = array();
|
||||
$aPossibleClasses = [];
|
||||
$sRealClass = '';
|
||||
if ($bCheckSubClass)
|
||||
{
|
||||
foreach($aSubClasses as $sCandidateClass)
|
||||
{
|
||||
if (!MetaModel::IsAbstract($sCandidateClass) && (UserRights::IsActionAllowed($sCandidateClass, UR_ACTION_MODIFY) == UR_ALLOWED_YES))
|
||||
{
|
||||
if ($bCheckSubClass) {
|
||||
foreach ($aSubClasses as $sCandidateClass) {
|
||||
if (!MetaModel::IsAbstract($sCandidateClass) && (UserRights::IsActionAllowed($sCandidateClass, UR_ACTION_MODIFY) == UR_ALLOWED_YES)) {
|
||||
$aPossibleClasses[$sCandidateClass] = MetaModel::GetName($sCandidateClass);
|
||||
}
|
||||
}
|
||||
// Only one of the subclasses can be instantiated...
|
||||
if (count($aPossibleClasses) === 1)
|
||||
{
|
||||
if (count($aPossibleClasses) === 1) {
|
||||
$aKeys = array_keys($aPossibleClasses);
|
||||
$sRealClass = $aKeys[0];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$sRealClass = $sClass;
|
||||
}
|
||||
|
||||
if (!empty($sRealClass))
|
||||
{
|
||||
if (!empty($sRealClass)) {
|
||||
// Set all the default values in an object and clone this "default" object
|
||||
$oObjToClone = MetaModel::NewObject($sRealClass);
|
||||
// 1st - set context values
|
||||
$oAppContext->InitObjectFromContext($oObjToClone);
|
||||
// 2nd - set values from the page argument 'default'
|
||||
$oObjToClone->UpdateObjectFromArg('default');
|
||||
$aPrefillFormParam = array(
|
||||
$aPrefillFormParam = [
|
||||
'user' => Session::Get('auth_user'),
|
||||
'context' => $oAppContext->GetAsHash(),
|
||||
'default' => utils::ReadParam('default', array(), '', 'raw_data'),
|
||||
'default' => utils::ReadParam('default', [], '', 'raw_data'),
|
||||
'origin' => 'console',
|
||||
);
|
||||
];
|
||||
// 3rd - prefill API
|
||||
$oObjToClone->PrefillForm('creation_from_0', $aPrefillFormParam);
|
||||
|
||||
@@ -134,18 +126,18 @@ class ObjectController extends AbstractController
|
||||
$sHeaderTitle = Dict::Format('UI:CreationTitle_Class', $sClassLabel);
|
||||
// Note: some code has been duplicated to the case 'apply_new' when a data integrity issue has been found
|
||||
|
||||
$aFormExtraParams = array('wizard_container' => 1, 'keep_source_object' => true);
|
||||
|
||||
$aFormExtraParams = ['wizard_container' => 1, 'keep_source_object' => true];
|
||||
|
||||
// - Update flags with parameters set in URL
|
||||
FormHelper::UpdateFlagsFromContext($oObjToClone, $aFormExtraParams);
|
||||
|
||||
|
||||
if ($this->IsHandlingXmlHttpRequest()) {
|
||||
$aFormExtraParams['js_handlers'] = [];
|
||||
$aFormExtraParams['noRelations'] = true;
|
||||
$aFormExtraParams['hide_transitions'] = true;
|
||||
// Add a random prefix to avoid ID collision for form elements
|
||||
$aFormExtraParams['formPrefix'] = utils::Sanitize(uniqid('', true), '', utils::ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER).'_';
|
||||
// We display this form in a modal, once we submit (in ajax) we probably want to only close the modal
|
||||
// We display this form in a modal, once we submit (in ajax) we probably want to only close the modal
|
||||
$aFormExtraParams['js_handlers']['form_on_submit'] =
|
||||
<<<JS
|
||||
event.preventDefault();
|
||||
@@ -176,10 +168,10 @@ JS;
|
||||
// Remove blob edition from creation form @see N°5863 to allow blob edition in modal context
|
||||
FormHelper::DisableAttributeBlobInputs($sRealClass, $aFormExtraParams);
|
||||
|
||||
if(FormHelper::HasMandatoryAttributeBlobInputs($oObjToClone)){
|
||||
if (FormHelper::HasMandatoryAttributeBlobInputs($oObjToClone)) {
|
||||
$oPage->AddUiBlock(FormHelper::GetAlertForMandatoryAttributeBlobInputsInModal(FormHelper::ENUM_MANDATORY_BLOB_MODE_CREATE));
|
||||
}
|
||||
|
||||
|
||||
$aFormExtraParams['js_handlers']['cancel_button_on_click'] =
|
||||
<<<JS
|
||||
function() {
|
||||
@@ -191,7 +183,7 @@ JS;
|
||||
$oPage->SetContentLayout(PageContentFactory::MakeForObjectDetails($oObjToClone, cmdbAbstractObject::ENUM_DISPLAY_MODE_CREATE));
|
||||
}
|
||||
|
||||
cmdbAbstractObject::DisplayCreationForm($oPage, $sRealClass, $oObjToClone, array(), $aFormExtraParams);
|
||||
cmdbAbstractObject::DisplayCreationForm($oPage, $sRealClass, $oObjToClone, [], $aFormExtraParams);
|
||||
} else {
|
||||
if ($this->IsHandlingXmlHttpRequest()) {
|
||||
$oClassForm = cmdbAbstractObject::DisplayFormBlockSelectClassToCreate($sClass, MetaModel::GetName($sClass), $oAppContext, $aPossibleClasses, ['state' => $sStateCode]);
|
||||
@@ -209,9 +201,8 @@ JS;
|
||||
JS
|
||||
);
|
||||
$oPage->AddUiBlock($oClassForm);
|
||||
}
|
||||
else{
|
||||
cmdbAbstractObject::DisplaySelectClassToCreate($sClass, $oPage, $oAppContext, $aPossibleClasses,['state' => $sStateCode]);
|
||||
} else {
|
||||
cmdbAbstractObject::DisplaySelectClassToCreate($sClass, $oPage, $oAppContext, $aPossibleClasses, ['state' => $sStateCode]);
|
||||
}
|
||||
}
|
||||
return $oPage;
|
||||
@@ -233,8 +224,7 @@ JS
|
||||
$sFormTitle = utils::ReadPostedParam('form_title', null, utils::ENUM_SANITIZATION_FILTER_STRING);
|
||||
|
||||
// Check parameters
|
||||
if (utils::IsNullOrEmptyString($sClass) || utils::IsNullOrEmptyString($sId))
|
||||
{
|
||||
if (utils::IsNullOrEmptyString($sClass) || utils::IsNullOrEmptyString($sId)) {
|
||||
throw new ApplicationException(Dict::Format('UI:Error:2ParametersMissing', 'class', 'id'));
|
||||
}
|
||||
|
||||
@@ -248,11 +238,11 @@ JS
|
||||
// - Is allowed to edit it?
|
||||
$oSet = CMDBObjectSet::FromObject($oObj);
|
||||
if (UserRights::IsActionAllowed($sClass, UR_ACTION_MODIFY, $oSet) == UR_ALLOWED_NO) {
|
||||
throw new SecurityException('User not allowed to modify this object', array('class' => $sClass, 'id' => $sId));
|
||||
throw new SecurityException('User not allowed to modify this object', ['class' => $sClass, 'id' => $sId]);
|
||||
}
|
||||
|
||||
// Prepare web page (should more likely be some kind of response object like for Symfony)
|
||||
$aFormExtraParams = array('wizard_container' => 1);
|
||||
$aFormExtraParams = ['wizard_container' => 1];
|
||||
FormHelper::UpdateFlagsFromContext($oObj, $aFormExtraParams);
|
||||
|
||||
// Allow form title customization
|
||||
@@ -265,7 +255,7 @@ JS
|
||||
$aFormExtraParams['js_handlers'] = [];
|
||||
$aFormExtraParams['noRelations'] = true;
|
||||
$aFormExtraParams['hide_transitions'] = true;
|
||||
// We display this form in a modal, once we submit (in ajax) we probably want to only close the modal
|
||||
// We display this form in a modal, once we submit (in ajax) we probably want to only close the modal
|
||||
$aFormExtraParams['js_handlers']['form_on_submit'] =
|
||||
<<<JS
|
||||
event.preventDefault();
|
||||
@@ -293,7 +283,6 @@ JS
|
||||
}
|
||||
JS;
|
||||
|
||||
|
||||
$aFormExtraParams['js_handlers']['cancel_button_on_click'] =
|
||||
<<<JS
|
||||
function() {
|
||||
@@ -304,12 +293,12 @@ JS;
|
||||
// Remove blob edition from creation form @see N°5863 to allow blob edition in modal context
|
||||
FormHelper::DisableAttributeBlobInputs($sClass, $aFormExtraParams);
|
||||
|
||||
if(FormHelper::HasMandatoryAttributeBlobInputs($oObj)){
|
||||
if (FormHelper::HasMandatoryAttributeBlobInputs($oObj)) {
|
||||
$sMandatoryBlobAttCode = FormHelper::GetMandatoryAttributeBlobInputs($oObj);
|
||||
$sAlertFormMandatoryAttMessageMode = FormHelper::ENUM_MANDATORY_BLOB_MODE_MODIFY_EMPTY;
|
||||
$oMandatoryBlobAttCodeValue = $oObj->Get($sMandatoryBlobAttCode);
|
||||
// If the current value of the mandatory attribute is not empty, display a different message
|
||||
if($oMandatoryBlobAttCodeValue instanceof \ormDocument && !$oMandatoryBlobAttCodeValue->IsEmpty()){
|
||||
if ($oMandatoryBlobAttCodeValue instanceof \ormDocument && !$oMandatoryBlobAttCodeValue->IsEmpty()) {
|
||||
$sAlertFormMandatoryAttMessageMode = FormHelper::ENUM_MANDATORY_BLOB_MODE_MODIFY_FILLED;
|
||||
}
|
||||
$oPage->AddUiBlock(FormHelper::GetAlertForMandatoryAttributeBlobInputsInModal($sAlertFormMandatoryAttMessageMode));
|
||||
@@ -329,7 +318,7 @@ JS;
|
||||
|
||||
return $oPage;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return iTopWebPage|JsonPage Object edit form in its webpage
|
||||
* @throws \ApplicationException
|
||||
@@ -350,29 +339,27 @@ JS;
|
||||
$oPage->DisableBreadCrumb();
|
||||
$this->AddRequiredForModificationJsFilesToPage($oPage);
|
||||
}
|
||||
|
||||
|
||||
$sClass = utils::ReadPostedParam('class', '', 'class');
|
||||
$sClassLabel = MetaModel::GetName($sClass);
|
||||
$sFormPrefix = utils::ReadPostedParam('formPrefix', '', utils::ENUM_SANITIZATION_FILTER_STRING);
|
||||
$sTransactionId = utils::ReadPostedParam('transaction_id', '', 'transaction_id');
|
||||
$aErrors = array();
|
||||
$aWarnings = array();
|
||||
if ( empty($sClass) )
|
||||
{
|
||||
IssueLog::Trace(__CLASS__.'::'.__METHOD__.' Object not created (empty class)', $sClass, array(
|
||||
$aErrors = [];
|
||||
$aWarnings = [];
|
||||
if (empty($sClass)) {
|
||||
IssueLog::Trace(__CLASS__.'::'.__METHOD__.' Object not created (empty class)', $sClass, [
|
||||
'$sTransactionId' => $sTransactionId,
|
||||
'$sUser' => UserRights::GetUser(),
|
||||
'HTTP_REFERER' => @$_SERVER['HTTP_REFERER'],
|
||||
'REQUEST_URI' => @$_SERVER['REQUEST_URI'],
|
||||
));
|
||||
]);
|
||||
|
||||
throw new ApplicationException(Dict::Format('UI:Error:1ParametersMissing', 'class'));
|
||||
}
|
||||
if (!utils::IsTransactionValid($sTransactionId, false))
|
||||
{
|
||||
if (!utils::IsTransactionValid($sTransactionId, false)) {
|
||||
$sUser = UserRights::GetUser();
|
||||
IssueLog::Error(__CLASS__.'::'.__METHOD__." : invalid transaction_id ! data: user='$sUser', class='$sClass'");
|
||||
|
||||
|
||||
if ($this->IsHandlingXmlHttpRequest()) {
|
||||
$aResult['data'] = ['error_message' => Dict::S('UI:Error:ObjectAlreadyCreated')];
|
||||
} else {
|
||||
@@ -382,25 +369,20 @@ JS;
|
||||
$oPage->AddUiBlock($oErrorAlert);
|
||||
}
|
||||
|
||||
IssueLog::Trace(__CLASS__.'::'.__METHOD__.' Object not created (invalid transaction_id)', $sClass, array(
|
||||
IssueLog::Trace(__CLASS__.'::'.__METHOD__.' Object not created (invalid transaction_id)', $sClass, [
|
||||
'$sTransactionId' => $sTransactionId,
|
||||
'$sUser' => UserRights::GetUser(),
|
||||
'HTTP_REFERER' => @$_SERVER['HTTP_REFERER'],
|
||||
'REQUEST_URI' => @$_SERVER['REQUEST_URI'],
|
||||
));
|
||||
}
|
||||
else
|
||||
{
|
||||
]);
|
||||
} else {
|
||||
$oObj = MetaModel::NewObject($sClass);
|
||||
if (MetaModel::HasLifecycle($sClass))
|
||||
{
|
||||
if (MetaModel::HasLifecycle($sClass)) {
|
||||
$sStateAttCode = MetaModel::GetStateAttributeCode($sClass);
|
||||
$sTargetState = utils::ReadPostedParam('obj_state', '');
|
||||
if ($sTargetState != '')
|
||||
{
|
||||
if ($sTargetState != '') {
|
||||
$sOrigState = utils::ReadPostedParam('obj_state_orig', '');
|
||||
if ($sTargetState != $sOrigState)
|
||||
{
|
||||
if ($sTargetState != $sOrigState) {
|
||||
$aWarnings[] = Dict::S('UI:StateChanged');
|
||||
}
|
||||
$oObj->Set($sStateAttCode, $sTargetState);
|
||||
@@ -408,24 +390,21 @@ JS;
|
||||
}
|
||||
$aErrors = $oObj->UpdateObjectFromPostedForm($sFormPrefix);
|
||||
}
|
||||
if (isset($oObj) && is_object($oObj))
|
||||
{
|
||||
if (isset($oObj) && is_object($oObj)) {
|
||||
$sClass = get_class($oObj);
|
||||
$sClassLabel = MetaModel::GetName($sClass);
|
||||
|
||||
try
|
||||
{
|
||||
if (!empty($aErrors) || !empty($aWarnings))
|
||||
{
|
||||
IssueLog::Trace(__CLASS__.'::'.__METHOD__.' Object not created (see $aErrors)', $sClass, array(
|
||||
try {
|
||||
if (!empty($aErrors) || !empty($aWarnings)) {
|
||||
IssueLog::Trace(__CLASS__.'::'.__METHOD__.' Object not created (see $aErrors)', $sClass, [
|
||||
'$sTransactionId' => $sTransactionId,
|
||||
'$aErrors' => $aErrors,
|
||||
'$sUser' => UserRights::GetUser(),
|
||||
'HTTP_REFERER' => @$_SERVER['HTTP_REFERER'],
|
||||
'REQUEST_URI' => @$_SERVER['REQUEST_URI'],
|
||||
));
|
||||
]);
|
||||
|
||||
throw new CoreCannotSaveObjectException(array('id' => $oObj->GetKey(), 'class' => $sClass, 'issues' => $aErrors));
|
||||
throw new CoreCannotSaveObjectException(['id' => $oObj->GetKey(), 'class' => $sClass, 'issues' => $aErrors]);
|
||||
}
|
||||
|
||||
// Transactions are now handled in DBInsert
|
||||
@@ -438,15 +417,14 @@ JS;
|
||||
$oObj->CheckChangedExtKeysValues();
|
||||
$oObj->DBInsertNoReload();
|
||||
|
||||
|
||||
IssueLog::Trace(__CLASS__.'::'.__METHOD__.' Object created', $sClass, array(
|
||||
IssueLog::Trace(__CLASS__.'::'.__METHOD__.' Object created', $sClass, [
|
||||
'$id' => $oObj->GetKey(),
|
||||
'$sTransactionId' => $sTransactionId,
|
||||
'$aErrors' => $aErrors,
|
||||
'$sUser' => UserRights::GetUser(),
|
||||
'HTTP_REFERER' => @$_SERVER['HTTP_REFERER'],
|
||||
'REQUEST_URI' => @$_SERVER['REQUEST_URI'],
|
||||
));
|
||||
]);
|
||||
|
||||
utils::RemoveTransaction($sTransactionId);
|
||||
$oPage->set_title(Dict::S('UI:PageTitle:ObjectCreated'));
|
||||
@@ -462,8 +440,7 @@ JS;
|
||||
$oPage->add("<h1>$sMessage</h1>");
|
||||
try {
|
||||
ApplyNextAction($oPage, $oObj, $sNextAction);
|
||||
}
|
||||
catch (ApplicationException $e) {
|
||||
} catch (ApplicationException $e) {
|
||||
$sMessage = $e->getMessage();
|
||||
$sSeverity = 'info';
|
||||
ReloadAndDisplay($oPage, $oObj, 'create', $sMessage, $sSeverity);
|
||||
@@ -477,8 +454,7 @@ JS;
|
||||
ReloadAndDisplay($oPage, $oObj, 'create', $sMessage, 'ok');
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (CoreCannotSaveObjectException $e) {
|
||||
} catch (CoreCannotSaveObjectException $e) {
|
||||
// Found issues, explain and give the user a second chance
|
||||
//
|
||||
$aIssues = $e->getIssues();
|
||||
@@ -517,7 +493,8 @@ JS;
|
||||
* @throws \DictExceptionMissingString
|
||||
* @throws \MySQLException
|
||||
*/
|
||||
public function OperationApplyModify(){
|
||||
public function OperationApplyModify()
|
||||
{
|
||||
$bPrintable = utils::ReadParam('printable', '0') === '1';
|
||||
$aResult = [];
|
||||
if ($this->IsHandlingXmlHttpRequest()) {
|
||||
@@ -534,86 +511,79 @@ JS;
|
||||
$sClassLabel = MetaModel::GetName($sClass);
|
||||
$id = utils::ReadPostedParam('id', '');
|
||||
$sTransactionId = utils::ReadPostedParam('transaction_id', '', 'transaction_id');
|
||||
if ( empty($sClass) || empty($id))
|
||||
{
|
||||
IssueLog::Trace(__CLASS__.'::'.__METHOD__.' Object not updated (empty class or id)', $sClass, array(
|
||||
if (empty($sClass) || empty($id)) {
|
||||
IssueLog::Trace(__CLASS__.'::'.__METHOD__.' Object not updated (empty class or id)', $sClass, [
|
||||
'$id' => $id,
|
||||
'$sTransactionId' => $sTransactionId,
|
||||
'$sUser' => UserRights::GetUser(),
|
||||
'HTTP_REFERER' => @$_SERVER['HTTP_REFERER'],
|
||||
'REQUEST_URI' => @$_SERVER['REQUEST_URI'],
|
||||
));
|
||||
]);
|
||||
// TODO 3.1 Do not crash with an exception in ajax
|
||||
throw new ApplicationException(Dict::Format('UI:Error:2ParametersMissing', 'class', 'id'));
|
||||
}
|
||||
$bDisplayDetails = true;
|
||||
$oObj = MetaModel::GetObject($sClass, $id, false);
|
||||
if ($oObj === null)
|
||||
{
|
||||
if ($oObj === null) {
|
||||
$bDisplayDetails = false;
|
||||
|
||||
if ($this->IsHandlingXmlHttpRequest()) {
|
||||
$aResult['data'] = ['error_message' => Dict::S('UI:ObjectDoesNotExist')];
|
||||
} else {
|
||||
$oPage->set_title(Dict::S('UI:ErrorPageTitle'));
|
||||
|
||||
|
||||
$oErrorAlert = AlertUIBlockFactory::MakeForFailure(Dict::S('UI:ObjectDoesNotExist'));
|
||||
$oErrorAlert->SetIsClosable(false)
|
||||
->SetIsCollapsible(false);
|
||||
$oPage->AddUiBlock($oErrorAlert);
|
||||
|
||||
}
|
||||
|
||||
IssueLog::Trace(__CLASS__.'::'.__METHOD__.' Object not updated (id not found)', $sClass, array(
|
||||
|
||||
IssueLog::Trace(__CLASS__.'::'.__METHOD__.' Object not updated (id not found)', $sClass, [
|
||||
'$id' => $id,
|
||||
'$sTransactionId' => $sTransactionId,
|
||||
'$sUser' => UserRights::GetUser(),
|
||||
'HTTP_REFERER' => @$_SERVER['HTTP_REFERER'],
|
||||
'REQUEST_URI' => @$_SERVER['REQUEST_URI'],
|
||||
));
|
||||
}
|
||||
elseif (!utils::IsTransactionValid($sTransactionId, false))
|
||||
{
|
||||
]);
|
||||
} elseif (!utils::IsTransactionValid($sTransactionId, false)) {
|
||||
//TODO: since $bDisplayDetails= true, there will be an redirection, thus, the content generated here is ignored, only the $sMessage and $sSeverity are used after the redirection
|
||||
$sUser = UserRights::GetUser();
|
||||
IssueLog::Error(__CLASS__.'::'.__METHOD__." : invalid transaction_id ! data: user='$sUser', class='$sClass'");
|
||||
|
||||
|
||||
if ($this->IsHandlingXmlHttpRequest()) {
|
||||
$aResult['data'] = ['error_message' => Dict::S('UI:Error:ObjectAlreadyUpdated')];
|
||||
} else {
|
||||
$oPage->set_title(Dict::Format('UI:ModificationPageTitle_Object_Class', $oObj->GetRawName(), $sClassLabel)); // Set title will take care of the encoding
|
||||
$oPage->p("<strong>".Dict::S('UI:Error:ObjectAlreadyUpdated')."</strong>\n");
|
||||
}
|
||||
|
||||
|
||||
$sMessage = Dict::Format('UI:Error:ObjectAlreadyUpdated', MetaModel::GetName(get_class($oObj)), $oObj->GetName());
|
||||
$sSeverity = 'error';
|
||||
|
||||
IssueLog::Trace(__CLASS__.'::'.__METHOD__.' Object not updated (invalid transaction_id)', $sClass, array(
|
||||
IssueLog::Trace(__CLASS__.'::'.__METHOD__.' Object not updated (invalid transaction_id)', $sClass, [
|
||||
'$id' => $id,
|
||||
'$sTransactionId' => $sTransactionId,
|
||||
'$sUser' => UserRights::GetUser(),
|
||||
'HTTP_REFERER' => @$_SERVER['HTTP_REFERER'],
|
||||
'REQUEST_URI' => @$_SERVER['REQUEST_URI'],
|
||||
));
|
||||
}
|
||||
else
|
||||
{
|
||||
]);
|
||||
} else {
|
||||
$aErrors = $oObj->UpdateObjectFromPostedForm();
|
||||
$sMessage = '';
|
||||
$sSeverity = 'ok';
|
||||
|
||||
if (!$oObj->IsModified() && empty($aErrors))
|
||||
{
|
||||
if (!$oObj->IsModified() && empty($aErrors)) {
|
||||
if ($this->IsHandlingXmlHttpRequest()) {
|
||||
$aResult['data'] = ['error_message' => Dict::Format('UI:Class_Object_NotUpdated', MetaModel::GetName(get_class($oObj)), $oObj->GetName())];
|
||||
} else {
|
||||
$oPage->set_title(Dict::Format('UI:ModificationPageTitle_Object_Class', $oObj->GetRawName(), $sClassLabel)); // Set title will take care of the encoding
|
||||
}
|
||||
|
||||
|
||||
$sMessage = Dict::Format('UI:Class_Object_NotUpdated', MetaModel::GetName(get_class($oObj)), $oObj->GetName());
|
||||
$sSeverity = 'info';
|
||||
|
||||
IssueLog::Trace(__CLASS__.'::'.__METHOD__.' Object not updated (see either $aErrors or IsModified)', $sClass, array(
|
||||
IssueLog::Trace(__CLASS__.'::'.__METHOD__.' Object not updated (see either $aErrors or IsModified)', $sClass, [
|
||||
'$id' => $id,
|
||||
'$sTransactionId' => $sTransactionId,
|
||||
'$aErrors' => $aErrors,
|
||||
@@ -621,11 +591,9 @@ JS;
|
||||
'$sUser' => UserRights::GetUser(),
|
||||
'HTTP_REFERER' => @$_SERVER['HTTP_REFERER'],
|
||||
'REQUEST_URI' => @$_SERVER['REQUEST_URI'],
|
||||
));
|
||||
}
|
||||
else
|
||||
{
|
||||
IssueLog::Trace(__CLASS__.'::'.__METHOD__.' Object updated', $sClass, array(
|
||||
]);
|
||||
} else {
|
||||
IssueLog::Trace(__CLASS__.'::'.__METHOD__.' Object updated', $sClass, [
|
||||
'$id' => $id,
|
||||
'$sTransactionId' => $sTransactionId,
|
||||
'$aErrors' => $aErrors,
|
||||
@@ -633,11 +601,11 @@ JS;
|
||||
'$sUser' => UserRights::GetUser(),
|
||||
'HTTP_REFERER' => @$_SERVER['HTTP_REFERER'],
|
||||
'REQUEST_URI' => @$_SERVER['REQUEST_URI'],
|
||||
));
|
||||
]);
|
||||
|
||||
try {
|
||||
if (!empty($aErrors)) {
|
||||
throw new CoreCannotSaveObjectException(array('id' => $oObj->GetKey(), 'class' => $sClass, 'issues' => $aErrors));
|
||||
throw new CoreCannotSaveObjectException(['id' => $oObj->GetKey(), 'class' => $sClass, 'issues' => $aErrors]);
|
||||
}
|
||||
|
||||
$oObj->CheckChangedExtKeysValues();
|
||||
@@ -655,9 +623,7 @@ JS;
|
||||
if ($this->IsHandlingXmlHttpRequest()) {
|
||||
$aResult['success'] = true;
|
||||
}
|
||||
}
|
||||
catch (CoreCannotSaveObjectException $e)
|
||||
{
|
||||
} catch (CoreCannotSaveObjectException $e) {
|
||||
// Found issues, explain and give the user a second chance
|
||||
//
|
||||
$bDisplayDetails = false;
|
||||
@@ -666,13 +632,13 @@ JS;
|
||||
$aResult['data'] = ['error_message' => $e->getHtmlMessage()];
|
||||
} else {
|
||||
$oPage->AddHeaderMessage($e->getHtmlMessage(), 'message_error');
|
||||
$oObj->DisplayModifyForm($oPage,
|
||||
array('wizard_container' => true)); // wizard_container: display the wizard border and the title
|
||||
$oObj->DisplayModifyForm(
|
||||
$oPage,
|
||||
['wizard_container' => true]
|
||||
); // wizard_container: display the wizard border and the title
|
||||
}
|
||||
|
||||
}
|
||||
catch (DeleteException $e)
|
||||
{
|
||||
|
||||
} catch (DeleteException $e) {
|
||||
if ($this->IsHandlingXmlHttpRequest()) {
|
||||
$aResult['data'] = ['error_message' => Dict::Format('UI:Class_Object_NotUpdated', MetaModel::GetName(get_class($oObj)), $oObj->GetName())];
|
||||
} else {
|
||||
@@ -680,8 +646,15 @@ JS;
|
||||
// - 1) Don't be afraid nothing was modified
|
||||
$sMessage = Dict::Format('UI:Class_Object_NotUpdated', MetaModel::GetName(get_class($oObj)), $oObj->GetName());
|
||||
$sSeverity = 'info';
|
||||
cmdbAbstractObject::SetSessionMessage(get_class($oObj), $oObj->GetKey(), 'UI:Class_Object_NotUpdated', $sMessage,
|
||||
$sSeverity, 0, true /* must not exist */);
|
||||
cmdbAbstractObject::SetSessionMessage(
|
||||
get_class($oObj),
|
||||
$oObj->GetKey(),
|
||||
'UI:Class_Object_NotUpdated',
|
||||
$sMessage,
|
||||
$sSeverity,
|
||||
0,
|
||||
true /* must not exist */
|
||||
);
|
||||
// - 2) Ok, there was some trouble indeed
|
||||
$sMessage = $e->getMessage();
|
||||
$sSeverity = 'error';
|
||||
@@ -702,8 +675,7 @@ JS;
|
||||
if (!empty($sNextAction)) {
|
||||
try {
|
||||
ApplyNextAction($oPage, $oObj, $sNextAction);
|
||||
}
|
||||
catch (ApplicationException $e) {
|
||||
} catch (ApplicationException $e) {
|
||||
$sMessage = $e->getMessage();
|
||||
$sSeverity = 'info';
|
||||
ReloadAndDisplay($oPage, $oObj, 'update', $sMessage, $sSeverity);
|
||||
@@ -736,28 +708,25 @@ JS;
|
||||
return $oPage;
|
||||
}
|
||||
|
||||
public function OperationSummary() {
|
||||
public function OperationSummary()
|
||||
{
|
||||
$oPage = new AjaxPage('');
|
||||
|
||||
$sClass = utils::ReadParam('obj_class', '', false, utils::ENUM_SANITIZATION_FILTER_CLASS);
|
||||
$sObjectKey = utils::ReadParam('obj_key', 0, false);
|
||||
|
||||
|
||||
// - Check if we are allowed to see/make summary for this class
|
||||
if(SummaryCardService::IsAllowedForClass($sClass)){
|
||||
if (is_numeric($sObjectKey))
|
||||
{
|
||||
if (SummaryCardService::IsAllowedForClass($sClass)) {
|
||||
if (is_numeric($sObjectKey)) {
|
||||
$oObj = MetaModel::GetObject($sClass, $sObjectKey, false /* MustBeFound */);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$oObj = MetaModel::GetObjectByName($sClass, $sObjectKey, false /* MustBeFound */);
|
||||
}
|
||||
|
||||
if($oObj !== null) {
|
||||
|
||||
if ($oObj !== null) {
|
||||
$oPage->AddUiBlock(new ObjectSummary($oObj));
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$oPage->AddUiBlock(
|
||||
AlertUIBlockFactory::MakeForFailure(Dict::S('UI:Error:ActionNotAllowed'))
|
||||
->SetIsCollapsible(false)
|
||||
@@ -817,7 +786,7 @@ JS;
|
||||
// Retrieve this reference object (for OQL)
|
||||
$sThisObjectData = utils::ReadPostedParam('this_object_data', null, utils::ENUM_SANITIZATION_FILTER_RAW_DATA);
|
||||
$oThisObj = null;
|
||||
if($sThisObjectData !== null) {
|
||||
if ($sThisObjectData !== null) {
|
||||
$oThisObj = ObjectRepository::GetObjectFromWizardHelperData($sThisObjectData);
|
||||
}
|
||||
|
||||
@@ -830,7 +799,7 @@ JS;
|
||||
// Data post processor
|
||||
// Note: Data post processor allow you to perform actions on search result (compute object result statistics, add others information...).
|
||||
if ($aResult !== null && $aDataProcessor !== null) {
|
||||
$aResult = call_user_func(array($aDataProcessor['class_name'], 'Execute'), $aResult, $aDataProcessor['settings']);
|
||||
$aResult = call_user_func([$aDataProcessor['class_name'], 'Execute'], $aResult, $aDataProcessor['settings']);
|
||||
}
|
||||
|
||||
return $oPage->SetData([
|
||||
@@ -862,7 +831,7 @@ JS;
|
||||
throw new ApplicationException('Invalid marker "'.$sMarker.'"');
|
||||
}
|
||||
|
||||
$aMatches = array();
|
||||
$aMatches = [];
|
||||
// Retrieve mentioned class from marker
|
||||
$sMentionedClass = $aMentionsAllowedClasses[$sMarker];
|
||||
if (MetaModel::IsValidClass($sMentionedClass) === false) {
|
||||
@@ -881,8 +850,8 @@ JS;
|
||||
|
||||
$aTriggerMentionedSearches = [];
|
||||
|
||||
$aTriggerSetParams = array('class_list' => MetaModel::EnumParentClasses($sHostClass, ENUM_PARENT_CLASSES_ALL));
|
||||
$oTriggerSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT TriggerOnObjectMention AS t WHERE t.target_class IN (:class_list)"), array(), $aTriggerSetParams);
|
||||
$aTriggerSetParams = ['class_list' => MetaModel::EnumParentClasses($sHostClass, ENUM_PARENT_CLASSES_ALL)];
|
||||
$oTriggerSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT TriggerOnObjectMention AS t WHERE t.target_class IN (:class_list)"), [], $aTriggerSetParams);
|
||||
/** @var \TriggerOnObjectMention $oTrigger */
|
||||
while ($oTrigger = $oTriggerSet->Fetch()) {
|
||||
$sTriggerMentionedOQL = $oTrigger->Get('mentioned_filter');
|
||||
@@ -914,7 +883,6 @@ JS;
|
||||
|
||||
$sObjectImageAttCode = MetaModel::GetImageAttributeCode($sSearchMainClassName);
|
||||
|
||||
|
||||
// Optimize fields to load
|
||||
$aObjectAttCodesToLoad = [];
|
||||
if (MetaModel::IsValidAttCode($sSearchMainClassName, $sObjectImageAttCode)) {
|
||||
@@ -948,8 +916,7 @@ JS;
|
||||
try {
|
||||
$oObject = MetaModel::GetObject($sObjectClass, $sObjectKey);
|
||||
$aObjectData = ObjectRepository::ConvertObjectToArray($oObject, $sObjectClass);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
$bSuccess = false;
|
||||
}
|
||||
|
||||
@@ -958,4 +925,4 @@ JS;
|
||||
'success' => $bSuccess,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -45,7 +46,7 @@ class LinkSetController extends AbstractController
|
||||
if (!$this->IsHandlingXmlHttpRequest()) {
|
||||
throw new CoreException('LinksetController can only be called in ajax.');
|
||||
}
|
||||
|
||||
|
||||
$oPage = new JsonPage();
|
||||
$sErrorMessage = null;
|
||||
$bOperationSuccess = false;
|
||||
@@ -63,8 +64,7 @@ class LinkSetController extends AbstractController
|
||||
if (!$bOperationSuccess) {
|
||||
$sErrorMessage = json_encode($oDeletionPlan->GetIssues());
|
||||
}
|
||||
}
|
||||
catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
$sErrorMessage = $e->getMessage();
|
||||
}
|
||||
} else {
|
||||
@@ -89,7 +89,7 @@ class LinkSetController extends AbstractController
|
||||
if (!$this->IsHandlingXmlHttpRequest()) {
|
||||
throw new CoreException('LinksetController can only be called in ajax.');
|
||||
}
|
||||
|
||||
|
||||
$oPage = new JsonPage();
|
||||
$sErrorMessage = null;
|
||||
$bOperationSuccess = false;
|
||||
@@ -107,8 +107,7 @@ class LinkSetController extends AbstractController
|
||||
$oLinkedObject->Set($sExternalKeyAttCode, null);
|
||||
$oLinkedObject->DBWrite();
|
||||
$bOperationSuccess = true;
|
||||
}
|
||||
catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
$sErrorMessage = $e->getMessage();
|
||||
}
|
||||
} else {
|
||||
@@ -149,7 +148,7 @@ class LinkSetController extends AbstractController
|
||||
$sRealClass = '';
|
||||
|
||||
$aSubClasses = MetaModel::EnumChildClasses($sProposedRealClass, ENUM_CHILD_CLASSES_ALL); // Including the specified class itself
|
||||
$aPossibleClasses = array();
|
||||
$aPossibleClasses = [];
|
||||
foreach ($aSubClasses as $sCandidateClass) {
|
||||
if (!MetaModel::IsAbstract($sCandidateClass) && (UserRights::IsActionAllowed($sCandidateClass, UR_ACTION_MODIFY) == UR_ALLOWED_YES)) {
|
||||
if ($sCandidateClass == $sProposedRealClass) {
|
||||
@@ -167,13 +166,13 @@ class LinkSetController extends AbstractController
|
||||
if ($sRealClass != '') {
|
||||
$oLinksetDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||
$sExtKeyToMe = $oLinksetDef->GetExtKeyToMe();
|
||||
$aFieldFlags = array($sExtKeyToMe => OPT_ATT_READONLY);
|
||||
$aFieldFlags = [$sExtKeyToMe => OPT_ATT_READONLY];
|
||||
$oObj = DBObject::MakeDefaultInstance($sRealClass);
|
||||
|
||||
$oSourceObj = MetaModel::GetObject($sClass, $sId);
|
||||
|
||||
$oObj->Set($sExtKeyToMe, $sId);
|
||||
$aPrefillParam = array('source_obj' => $oSourceObj);
|
||||
$aPrefillParam = ['source_obj' => $oSourceObj];
|
||||
$oObj->PrefillForm('creation_from_editinplace', $aPrefillParam);
|
||||
// We display this form in a modal, once we submit (in ajax) we probably want to only close the modal
|
||||
$sFormOnSubmitJsCode =
|
||||
@@ -203,7 +202,6 @@ class LinkSetController extends AbstractController
|
||||
}
|
||||
JS;
|
||||
|
||||
|
||||
$aExtraParams = [
|
||||
'noRelations' => true,
|
||||
'hide_transitions' => true,
|
||||
@@ -228,20 +226,18 @@ JS
|
||||
|
||||
// Remove blob edition from creation form @see N°5863 to allow blob edition in modal context
|
||||
FormHelper::DisableAttributeBlobInputs($sRealClass, $aExtraParams);
|
||||
|
||||
if(FormHelper::HasMandatoryAttributeBlobInputs($oObj)){
|
||||
$oPage->AddUiBlock(FormHelper::GetAlertForMandatoryAttributeBlobInputsInModal(FormHelper::ENUM_MANDATORY_BLOB_MODE_CREATE));
|
||||
}
|
||||
|
||||
cmdbAbstractObject::DisplayCreationForm($oPage, $sRealClass, $oObj, array(), $aExtraParams);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (FormHelper::HasMandatoryAttributeBlobInputs($oObj)) {
|
||||
$oPage->AddUiBlock(FormHelper::GetAlertForMandatoryAttributeBlobInputsInModal(FormHelper::ENUM_MANDATORY_BLOB_MODE_CREATE));
|
||||
}
|
||||
|
||||
cmdbAbstractObject::DisplayCreationForm($oPage, $sRealClass, $oObj, [], $aExtraParams);
|
||||
} else {
|
||||
// - We'll let the user select a class if multiple classes are available
|
||||
$oClassForm = FormUIBlockFactory::MakeStandard();
|
||||
|
||||
|
||||
// - When the user submit, redo the same request but with a real class
|
||||
|
||||
|
||||
$sCurrentParameters = json_encode([
|
||||
'att_code' => $sAttCode,
|
||||
'host_class' => $sClass,
|
||||
@@ -295,8 +291,7 @@ JS
|
||||
}
|
||||
$aObjectData = ObjectRepository::ConvertObjectToArray($oObject, $sObjectClass);
|
||||
$aObjectData['link_keys'] = [$sObjectKey];
|
||||
}
|
||||
catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
$bSuccess = false;
|
||||
}
|
||||
|
||||
@@ -305,4 +300,4 @@ JS
|
||||
'success' => $bSuccess,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,6 @@ use UserRights;
|
||||
use utils;
|
||||
use appUserPreferences;
|
||||
|
||||
|
||||
/**
|
||||
* Class iTopNewsroomController
|
||||
*
|
||||
@@ -64,7 +63,7 @@ class iTopNewsroomController extends Controller
|
||||
$oBulkActionsBlock = PanelUIBlockFactory::MakeForInformation(Dict::S('UI:Newsroom:iTopNotification:ViewAllPage:Title'));
|
||||
$oBulkActionsBlock->AddSubTitleBlock(new Html(Dict::S('UI:Newsroom:iTopNotification:ViewAllPage:SubTitle')));
|
||||
$sPictureUrl = UserRights::GetUserPictureAbsUrl();
|
||||
$oBulkActionsBlock->SetIcon($sPictureUrl,Panel::ENUM_ICON_COVER_METHOD_CONTAIN, true);
|
||||
$oBulkActionsBlock->SetIcon($sPictureUrl, Panel::ENUM_ICON_COVER_METHOD_CONTAIN, true);
|
||||
|
||||
$oNotificationsCenterButton = ButtonUIBlockFactory::MakeIconLink(
|
||||
'fas fa-cogs',
|
||||
@@ -90,7 +89,7 @@ class iTopNewsroomController extends Controller
|
||||
$oMarkAllAsReadButton->SetIconClass('far fa-envelope-open')
|
||||
->AddCSSClass('ibo-notifications--view-all--read-action')
|
||||
->SetOnClickJsCode(
|
||||
<<<JS
|
||||
<<<JS
|
||||
let oSelf = this;
|
||||
let oNotificationToMarkAsRead = $('.ibo-notifications--view-all--container [data-role="ibo-object-summary"].ibo-notifications--view-all--item--unread');
|
||||
let aNotificationIds = [];
|
||||
@@ -119,8 +118,8 @@ $.ajax({
|
||||
}
|
||||
});
|
||||
JS
|
||||
);
|
||||
|
||||
);
|
||||
|
||||
// Make button to mark all as unread
|
||||
$oMarkAllAsUnreadButton = ButtonUIBlockFactory::MakeForSecondaryAction(
|
||||
Dict::S('UI:Newsroom:iTopNotification:ViewAllPage:Action:MarkAllAsUnread:Label'),
|
||||
@@ -130,7 +129,7 @@ JS
|
||||
$oMarkAllAsUnreadButton->SetIconClass('far fa-envelope')
|
||||
->AddCSSClass('ibo-notifications--view-all--unread-action')
|
||||
->SetOnClickJsCode(
|
||||
<<<JS
|
||||
<<<JS
|
||||
let oSelf = this;
|
||||
let oNotificationToMarkAsUnread = $('.ibo-notifications--view-all--container [data-role="ibo-object-summary"].ibo-notifications--view-all--item--read');
|
||||
let aNotificationIds = [];
|
||||
@@ -160,7 +159,7 @@ $.ajax({
|
||||
}
|
||||
});
|
||||
JS
|
||||
);
|
||||
);
|
||||
|
||||
// Make button to delete all
|
||||
$oDeleteAllButton = ButtonUIBlockFactory::MakeForDestructiveAction(
|
||||
@@ -174,7 +173,7 @@ JS
|
||||
$oDeleteAllButton->SetIconClass('fas fa-trash-alt')
|
||||
->AddCSSClass('ibo-notifications--view-all--delete-action')
|
||||
->SetOnClickJsCode(
|
||||
<<<JS
|
||||
<<<JS
|
||||
let oSelf = this;
|
||||
let oNotificationToDelete = $('.ibo-notifications--view-all--container [data-role="ibo-object-summary"]');
|
||||
let aNotificationIds = [];
|
||||
@@ -213,13 +212,13 @@ CombodoModal.OpenConfirmationModal({
|
||||
}, []);
|
||||
|
||||
JS
|
||||
);
|
||||
);
|
||||
// Add "all" buttons to their container
|
||||
$oAllModeButtonsContainer->AddSubBlock($oMarkAllAsReadButton);
|
||||
$oAllModeButtonsContainer->AddSubBlock($oMarkAllAsUnreadButton);
|
||||
$oAllModeButtonsContainer->AddSubBlock($oDeleteAllButton);
|
||||
$oToolbar->AddSubBlock($oAllModeButtonsContainer);
|
||||
|
||||
|
||||
$oSelectedModelButtonsContainer = new UIContentBlock('ibo-notifications--view-all--selected-mode-buttons', ['ibo-is-hidden', 'ibo-notifications--view-all--bulk-buttons', 'ibo-notifications--view-all--selected-mode-buttons']);
|
||||
// Make button mark all selected as read
|
||||
$oMarkSelectedAsReadButton = ButtonUIBlockFactory::MakeForSecondaryAction(
|
||||
@@ -230,7 +229,7 @@ JS
|
||||
$oMarkSelectedAsReadButton->SetIconClass('far fa-envelope-open')
|
||||
->AddCSSClass('ibo-notifications--view-all--read-action')
|
||||
->SetOnClickJsCode(
|
||||
<<<JS
|
||||
<<<JS
|
||||
let oSelf = this;
|
||||
let oNotificationToMarkAsRead = $('.ibo-notifications--view-all--container [data-role="ibo-object-summary"].ibo-notifications--view-all--item--unread.ibo-is-selected');
|
||||
let aNotificationIds = [];
|
||||
@@ -255,7 +254,7 @@ $.ajax({
|
||||
}
|
||||
});
|
||||
JS
|
||||
);
|
||||
);
|
||||
|
||||
// Make button mark all selected as unread
|
||||
$oMarkSelectedAsUnreadButton = ButtonUIBlockFactory::MakeForSecondaryAction(
|
||||
@@ -266,7 +265,7 @@ JS
|
||||
$oMarkSelectedAsUnreadButton->SetIconClass('far fa-envelope')
|
||||
->AddCSSClass('ibo-notifications--view-all--unread-action')
|
||||
->SetOnClickJsCode(
|
||||
<<<JS
|
||||
<<<JS
|
||||
let oSelf = this;
|
||||
let oNotificationToMarkAsUnread = $('.ibo-notifications--view-all--container [data-role="ibo-object-summary"].ibo-notifications--view-all--item--read.ibo-is-selected');
|
||||
let aNotificationIds = [];
|
||||
@@ -291,7 +290,7 @@ $.ajax({
|
||||
}
|
||||
});
|
||||
JS
|
||||
);
|
||||
);
|
||||
|
||||
// Make button delete all selected
|
||||
$oDeleteSelectedButton = ButtonUIBlockFactory::MakeForDestructiveAction(
|
||||
@@ -305,7 +304,7 @@ JS
|
||||
$oDeleteSelectedButton->SetIconClass('fas fa-trash-alt')
|
||||
->AddCSSClass('ibo-notifications--view-all--delete-action')
|
||||
->SetOnClickJsCode(
|
||||
<<<JS
|
||||
<<<JS
|
||||
let oSelf = this;
|
||||
let oNotificationToDelete = $('.ibo-notifications--view-all--container [data-role="ibo-object-summary"].ibo-is-selected');
|
||||
let aNotificationIds = [];
|
||||
@@ -343,34 +342,34 @@ CombodoModal.OpenConfirmationModal({
|
||||
do_not_show_again_pref_key: 'notifications-center.delete-all-confirmation-modal.do-not-show-again',
|
||||
}, []);
|
||||
JS
|
||||
);
|
||||
);
|
||||
|
||||
// Add "selected" buttons to their container
|
||||
$oSelectedModelButtonsContainer->AddSubBlock($oMarkSelectedAsReadButton);
|
||||
$oSelectedModelButtonsContainer->AddSubBlock($oMarkSelectedAsUnreadButton);
|
||||
$oSelectedModelButtonsContainer->AddSubBlock($oDeleteSelectedButton);
|
||||
|
||||
|
||||
$oToolbar->AddSubBlock($oSelectedModelButtonsContainer);
|
||||
|
||||
|
||||
// Make toggler to switch between "all" and "selected" mode
|
||||
$oTogglerContentBlock = new UIContentBlock('ibo-notifications--view-all--toggler', ['ibo-notifications--view-all--toggler']);
|
||||
$oToggler = new Toggler();
|
||||
$oInputWithLabel = InputUIBlockFactory::MakeInputWithLabel('slider', Dict::S('UI:Newsroom:iTopNotification:SelectMode:Label'), $oToggler);
|
||||
$oTogglerContentBlock->AddSubBlock($oInputWithLabel);
|
||||
$oToolbar->AddSubBlock($oTogglerContentBlock);
|
||||
|
||||
|
||||
$oBulkActionsBlock->AddSubBlock($oToolbar);
|
||||
$oPage->AddUiBlock($oBulkActionsBlock);
|
||||
|
||||
|
||||
// Search for all notifications for the current user
|
||||
$oSearch = DBObjectSearch::FromOQL('SELECT EventNotificationNewsroom');
|
||||
$oSearch->AddCondition('contact_id', UserRights::GetContactId(), '=');
|
||||
$oSet = new DBObjectSet($oSearch, array('read' => true, 'date' => false), array());
|
||||
|
||||
$oSet = new DBObjectSet($oSearch, ['read' => true, 'date' => false], []);
|
||||
|
||||
// Add main content block
|
||||
$oMainContentBlock = new UIContentBlock(null, ['ibo-notifications--view-all--container']);
|
||||
$oPage->AddUiBlock($oMainContentBlock);
|
||||
|
||||
|
||||
while ($oEvent = $oSet->Fetch()) {
|
||||
$iEventId = $oEvent->GetKey();
|
||||
// Prepare object summary block
|
||||
@@ -383,10 +382,9 @@ JS
|
||||
$oImage = $oEvent->Get('icon');
|
||||
if (!$oImage->IsEmpty()) {
|
||||
$sIconUrl = $oImage->GetDisplayURL(get_class($oEvent), $iEventId, 'icon');
|
||||
$oEventBlock->SetIcon($sIconUrl, Panel::ENUM_ICON_COVER_METHOD_COVER,true);
|
||||
$oEventBlock->SetIcon($sIconUrl, Panel::ENUM_ICON_COVER_METHOD_COVER, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Common actions
|
||||
$sDeleteUrl = Router::GetInstance()->GenerateUrl(self::ROUTE_NAMESPACE.'.delete_event', ['notification_id' => $oEvent->GetKey(), 'token' => $sCSRFToken]);
|
||||
$oDeleteButton = ButtonUIBlockFactory::MakeForAlternativeDestructiveAction(
|
||||
@@ -417,12 +415,13 @@ JS
|
||||
->SetIconClass('fas fa-trash-alt')
|
||||
->SetTooltip(Dict::S('UI:Newsroom:iTopNotification:ViewAllPage:Action:Delete:Label'));
|
||||
|
||||
$oViewButton = ButtonUIBlockFactory::MakeIconLink('fas fa-external-link-alt',
|
||||
$oViewButton = ButtonUIBlockFactory::MakeIconLink(
|
||||
'fas fa-external-link-alt',
|
||||
Dict::S('UI:Newsroom:iTopNotification:ViewAllPage:Action:ViewObject:Label'),
|
||||
Router::GetInstance()->GenerateUrl(self::ROUTE_NAMESPACE.'.view_event', ['event_id' => $iEventId]),
|
||||
'_blank'
|
||||
);
|
||||
|
||||
|
||||
// Mark as read action
|
||||
$oMarkAsReadButton = ButtonUIBlockFactory::MakeForAlternativeSecondaryAction(
|
||||
'',
|
||||
@@ -454,7 +453,7 @@ JS
|
||||
});
|
||||
JS
|
||||
);
|
||||
|
||||
|
||||
$oMarkAsUnreadButton = ButtonUIBlockFactory::MakeForAlternativeSecondaryAction(
|
||||
'',
|
||||
'UI:Newsroom:iTopNotification:ViewAllPage:Action:MarkAsUnread:Label',
|
||||
@@ -483,7 +482,7 @@ JS
|
||||
});
|
||||
JS
|
||||
);
|
||||
|
||||
|
||||
// Add actions to the object summary block and remove old button
|
||||
$oOldButtonId = $oEventBlock->GetActions()->GetId();
|
||||
$oEventBlock->RemoveSubBlock($oOldButtonId);
|
||||
@@ -494,25 +493,23 @@ JS
|
||||
$oActionsBlock->AddSubBlock($oViewButton);
|
||||
$oActionsBlock->AddSubBlock($oDeleteButton);
|
||||
$oEventBlock->SetActions($oActionsBlock);
|
||||
|
||||
|
||||
|
||||
$oMainContentBlock->AddSubBlock($oEventBlock);
|
||||
}
|
||||
|
||||
|
||||
// Add empty content block
|
||||
$oEmptyContentBlock = new UIContentBlock('ibo-notifications--view-all--empty', ['ibo-notifications--view-all--empty', 'ibo-svg-illustration--container']);
|
||||
$oEmptyContentBlock->AddSubBlock(new Html(file_get_contents(APPROOT.'/images/illustrations/undraw_social_serenity.svg')));
|
||||
$oEmptyContentBlock->AddSubBlock(TitleUIBlockFactory::MakeNeutral(Dict::S('UI:Newsroom:iTopNotification:ViewAllPage:Empty:Title')));
|
||||
$oPage->AddUiBlock($oEmptyContentBlock);
|
||||
|
||||
|
||||
// Hide empty content block if there are notifications
|
||||
if($oSet->Count() === 0){
|
||||
if ($oSet->Count() === 0) {
|
||||
$oMainContentBlock->AddCSSClass('ibo-is-hidden');
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$oEmptyContentBlock->AddCSSClass('ibo-is-hidden');
|
||||
}
|
||||
|
||||
|
||||
return $oPage;
|
||||
}
|
||||
|
||||
@@ -534,7 +531,7 @@ JS
|
||||
|
||||
if (utils::IsNotNullOrEmptyString($iContactId)) {
|
||||
$oSearch = DBObjectSearch::FromOQL('SELECT EventNotificationNewsroom WHERE contact_id = :contact_id AND read = "no"');
|
||||
$oSet = new DBObjectSet($oSearch, array(), array('contact_id' => $iContactId));
|
||||
$oSet = new DBObjectSet($oSearch, [], ['contact_id' => $iContactId]);
|
||||
|
||||
while ($oMessage = $oSet->Fetch()) {
|
||||
$sTitle = $oMessage->Get('title');
|
||||
@@ -549,7 +546,7 @@ HTML;
|
||||
$sIcon = $oMessage->Get('icon') !== null ?
|
||||
$oMessage->Get('icon')->GetDisplayURL('EventNotificationNewsroom', $oMessage->GetKey(), 'icon') :
|
||||
Branding::GetCompactMainLogoAbsoluteUrl();
|
||||
$aMessages[] = array(
|
||||
$aMessages[] = [
|
||||
'id' => $oMessage->GetKey(),
|
||||
'text' => $sText,
|
||||
'url' => Router::GetInstance()->GenerateUrl(self::ROUTE_NAMESPACE.'.view_event', ['event_id' => $oMessage->GetKey()]),
|
||||
@@ -557,7 +554,7 @@ HTML;
|
||||
'start_date' => $oMessage->Get('date'),
|
||||
'priority' => $oMessage->Get('priority'),
|
||||
'image' => $sIcon,
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -582,10 +579,9 @@ HTML;
|
||||
$iCount = 0;
|
||||
$iContactId = UserRights::GetContactId();
|
||||
|
||||
|
||||
if (utils::IsNotNullOrEmptyString($iContactId)) {
|
||||
$oSearch = DBObjectSearch::FromOQL('SELECT EventNotificationNewsroom WHERE contact_id = :contact_id AND read = "no"');
|
||||
$oSet = new DBObjectSet($oSearch, array(), array('contact_id' => $iContactId));
|
||||
$oSet = new DBObjectSet($oSearch, [], ['contact_id' => $iContactId]);
|
||||
|
||||
while ($oEvent = $oSet->Fetch()) {
|
||||
$oEvent->Set('read', 'yes');
|
||||
@@ -622,8 +618,7 @@ HTML;
|
||||
$sUrl = $oEvent->Get('url');
|
||||
header("Location: $sUrl");
|
||||
}
|
||||
}
|
||||
catch (ArchivedObjectException|CoreException $e) {
|
||||
} catch (ArchivedObjectException|CoreException $e) {
|
||||
$this->DisplayPageNotFound();
|
||||
}
|
||||
}
|
||||
@@ -729,14 +724,14 @@ HTML;
|
||||
protected function PerformAction(string $sAction, array $aNotificationIds): array
|
||||
{
|
||||
$sCSRFToken = utils::ReadParam('token', '', false, 'raw_data');
|
||||
if(utils::IsTransactionValid($sCSRFToken, false) === false){
|
||||
if (utils::IsTransactionValid($sCSRFToken, false) === false) {
|
||||
throw new SecurityException('Invalid CSRF token');
|
||||
}
|
||||
|
||||
$sActionAsCamelCase = utils::ToCamelCase($sAction);
|
||||
$aReturnData = [
|
||||
'status' => 'error',
|
||||
'message' => 'Invalid notification(s)'
|
||||
'message' => 'Invalid notification(s)',
|
||||
];
|
||||
|
||||
// Check action type
|
||||
@@ -757,7 +752,7 @@ HTML;
|
||||
|
||||
// No notification found
|
||||
$iCount = $oSet->Count();
|
||||
if($iCount === 0) {
|
||||
if ($iCount === 0) {
|
||||
$aReturnData['message'] = Dict::S("UI:Newsroom:iTopNotification:ViewAllPage:Action:$sActionAsCamelCase:NoEvent:Message");
|
||||
return $aReturnData;
|
||||
}
|
||||
@@ -787,4 +782,4 @@ HTML;
|
||||
|
||||
return $aReturnData;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -19,7 +20,8 @@ use utils;
|
||||
* @internal
|
||||
* @since 3.2.0 N°5472 creation
|
||||
*/
|
||||
class ActionController extends AbstractController {
|
||||
class ActionController extends AbstractController
|
||||
{
|
||||
public const ROUTE_NAMESPACE = 'notifications.action';
|
||||
|
||||
/**
|
||||
@@ -30,7 +32,7 @@ class ActionController extends AbstractController {
|
||||
public function OperationLastExecutionsTab()
|
||||
{
|
||||
$sActionId = utils::ReadParam('action_id', null, false);
|
||||
$sCannotLoadActionErrorMessage = __METHOD__ . ': invalid action_id parameter';
|
||||
$sCannotLoadActionErrorMessage = __METHOD__.': invalid action_id parameter';
|
||||
if (utils::IsNullOrEmptyString($sActionId)) {
|
||||
throw new CoreUnexpectedValue($sCannotLoadActionErrorMessage);
|
||||
}
|
||||
@@ -45,4 +47,4 @@ class ActionController extends AbstractController {
|
||||
|
||||
return $oPage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
namespace Combodo\iTop\Controller\Notifications;
|
||||
|
||||
use ActionNotification;
|
||||
@@ -24,7 +25,6 @@ use utils;
|
||||
use UserRights;
|
||||
use appUserPreferences;
|
||||
|
||||
|
||||
/**
|
||||
* Class NotificationsCenterController
|
||||
*
|
||||
@@ -36,11 +36,12 @@ class NotificationsCenterController extends Controller
|
||||
{
|
||||
public const ROUTE_NAMESPACE = 'notificationscenter';
|
||||
|
||||
public function CheckPostedCSRF(){
|
||||
public function CheckPostedCSRF()
|
||||
{
|
||||
$sToken = utils::ReadParam('token', '', true, 'raw_data');
|
||||
return utils::IsTransactionValid($sToken, false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Displays a table containing all ActionNotifications that current user is likely to receive and allows to unsubscribe from them.
|
||||
*
|
||||
@@ -60,12 +61,12 @@ class NotificationsCenterController extends Controller
|
||||
{
|
||||
$oPage = new iTopWebPage(Dict::S('UI:NotificationsCenter:Page:Title'));
|
||||
// Create a panel that will contain the table
|
||||
$oNotificationsPanel = new Panel(Dict::S('UI:NotificationsCenter:Panel:Title'), array(), 'grey', 'ibo-notifications-center');
|
||||
$oNotificationsPanel = new Panel(Dict::S('UI:NotificationsCenter:Panel:Title'), [], 'grey', 'ibo-notifications-center');
|
||||
$oNotificationsPanel->AddCSSClass('ibo-datatable-panel');
|
||||
|
||||
$oNotificationsPanel->AddSubTitleBlock(new Html(Dict::S('UI:NotificationsCenter:Panel:SubTitle')));
|
||||
$sPictureUrl = UserRights::GetUserPictureAbsUrl();
|
||||
$oNotificationsPanel->SetIcon($sPictureUrl,Panel::ENUM_ICON_COVER_METHOD_CONTAIN, true);
|
||||
$oNotificationsPanel->SetIcon($sPictureUrl, Panel::ENUM_ICON_COVER_METHOD_CONTAIN, true);
|
||||
|
||||
$oAllNewsPageButton = ButtonUIBlockFactory::MakeIconLink(
|
||||
'fas fa-bell',
|
||||
@@ -75,10 +76,10 @@ class NotificationsCenterController extends Controller
|
||||
$oNotificationsPanel->SetToolBlocks([$oAllNewsPageButton]);
|
||||
|
||||
$oNotificationsCenterTableColumns = [
|
||||
'trigger' => array('label' => MetaModel::GetName('Trigger')),
|
||||
'trigger_class' => array('label' => MetaModel::GetAttributeDef('Trigger', 'finalclass')->GetLabel()),
|
||||
'complement' => array('label' => MetaModel::GetAttributeDef('Trigger', 'complement')->GetLabel()),
|
||||
'channels' => array('label' => Dict::S('UI:NotificationsCenter:Panel:Table:Channels')),
|
||||
'trigger' => ['label' => MetaModel::GetName('Trigger')],
|
||||
'trigger_class' => ['label' => MetaModel::GetAttributeDef('Trigger', 'finalclass')->GetLabel()],
|
||||
'complement' => ['label' => MetaModel::GetAttributeDef('Trigger', 'complement')->GetLabel()],
|
||||
'channels' => ['label' => Dict::S('UI:NotificationsCenter:Panel:Table:Channels')],
|
||||
];
|
||||
|
||||
// Get all subscribed/unsubscribed actions notifications for the current user
|
||||
@@ -153,13 +154,13 @@ class NotificationsCenterController extends Controller
|
||||
$aSetValues[] = $aChannel['value'];
|
||||
$aChannels[$sNotificationClass]['mixed'] = true;
|
||||
$aChannels[$sNotificationClass]['mixed_value'] = Dict::Format('UI:NotificationsCenter:Channel:OutOf:Text', $aChannel['total_subscribed'], $aChannel['total']);
|
||||
} else if ($aChannel['subscribed'] === true) {
|
||||
} elseif ($aChannel['subscribed'] === true) {
|
||||
$aSetValues[] = $aChannel['value'];
|
||||
}
|
||||
|
||||
|
||||
// Explode status array into a readable string
|
||||
$aChannels[$sNotificationClass]['additional_field'] = implode(', ', array_map(function($iCount, $sStatus) use($sNotificationClass) {
|
||||
return $iCount.' '. MetaModel::GetStateLabel($sNotificationClass, $sStatus);
|
||||
$aChannels[$sNotificationClass]['additional_field'] = implode(', ', array_map(function ($iCount, $sStatus) use ($sNotificationClass) {
|
||||
return $iCount.' '.MetaModel::GetStateLabel($sNotificationClass, $sStatus);
|
||||
}, $aChannel['status'], array_keys($aChannel['status'])));
|
||||
}
|
||||
// Create a input set for the channels
|
||||
@@ -206,8 +207,7 @@ $.ajax({
|
||||
JS
|
||||
);
|
||||
// Set the minimum number of channels to 1 if the subscription policy is {@see SubscriptionPolicy::ForceAtLeastOneChannel}
|
||||
if($sTriggerSubscriptionPolicy === SubscriptionPolicy::ForceAtLeastOneChannel->value)
|
||||
{
|
||||
if ($sTriggerSubscriptionPolicy === SubscriptionPolicy::ForceAtLeastOneChannel->value) {
|
||||
$oChannelSet->SetMinItems(1);
|
||||
}
|
||||
$oChannelSet->SetOnItemRemoveJs(
|
||||
@@ -284,13 +284,13 @@ JS
|
||||
* @return \JsonPage
|
||||
* @throws \Exception
|
||||
*/
|
||||
function OperationUnsubscribeFromChannel(): \JsonPage
|
||||
public function OperationUnsubscribeFromChannel(): \JsonPage
|
||||
{
|
||||
// Get the CSRF token from the request and check if it's valid
|
||||
if (!$this->CheckPostedCSRF()) {
|
||||
throw new \Exception('Invalid token');
|
||||
}
|
||||
|
||||
|
||||
// Get the channel from the request
|
||||
$sChannel = utils::ReadParam('channel', '', true, 'raw_data');
|
||||
$aChannel = explode('|', $sChannel);
|
||||
@@ -310,14 +310,14 @@ JS
|
||||
if ($oTrigger->Get('subscription_policy') === SubscriptionPolicy::ForceAllChannels->value) {
|
||||
throw new \Exception('You are not allowed to unsubscribe from this channel');
|
||||
}
|
||||
|
||||
|
||||
// Check if we are subscribed to at least 1 channel
|
||||
$oSubscribedActionsNotificationsSet = NotificationsRepository::GetInstance()->SearchSubscriptionsByTriggerContactSubscriptionAndFinalclass($iTriggerId, \UserRights::GetContactId(), '1', $sFinalclass);
|
||||
if ($oSubscribedActionsNotificationsSet->Count() === 0) {
|
||||
throw new \Exception('You are not subscribed to any channel');
|
||||
}
|
||||
// Check the trigger subscription policy and if we are subscribed to at least 1 channel if necessary
|
||||
if($oTrigger->Get('subscription_policy') === SubscriptionPolicy::ForceAtLeastOneChannel->value) {
|
||||
if ($oTrigger->Get('subscription_policy') === SubscriptionPolicy::ForceAtLeastOneChannel->value) {
|
||||
$oTotalSubscribedActionsNotificationsSet = NotificationsRepository::GetInstance()->SearchSubscriptionsByTriggerContactAndSubscription($iTriggerId, \UserRights::GetContactId(), '1');
|
||||
if (($oTotalSubscribedActionsNotificationsSet->Count() - $oSubscribedActionsNotificationsSet->Count()) === 0) {
|
||||
throw new \Exception('You can\'t unsubscribe from this channel, you must be subscribed to at least one channel');
|
||||
@@ -332,8 +332,7 @@ JS
|
||||
'status' => 'success',
|
||||
'message' => Dict::S('UI:NotificationsCenter:Unsubscribe:Success'),
|
||||
];
|
||||
}
|
||||
catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
// Return an error message if an exception is thrown
|
||||
$aReturnData = [
|
||||
'status' => 'error',
|
||||
@@ -350,17 +349,17 @@ JS
|
||||
* @return \JsonPage
|
||||
* @throws \Exception
|
||||
*/
|
||||
function OperationSubscribeToChannel(): \JsonPage
|
||||
public function OperationSubscribeToChannel(): \JsonPage
|
||||
{
|
||||
// Get the CSRF token from the request and check if it's valid
|
||||
if (!$this->CheckPostedCSRF()) {
|
||||
throw new \Exception('Invalid token');
|
||||
}
|
||||
|
||||
|
||||
// Get the channel from the request
|
||||
$sChannel = utils::ReadParam('channel', '', true, 'raw_data');
|
||||
$aChannel = explode('|', $sChannel);
|
||||
|
||||
|
||||
$oPage = new \JsonPage();
|
||||
$aReturnData = [];
|
||||
try {
|
||||
@@ -385,8 +384,7 @@ JS
|
||||
'status' => 'success',
|
||||
'message' => Dict::S('UI:NotificationsCenter:Subscribe:Success'),
|
||||
];
|
||||
}
|
||||
catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
// Return an error message if an exception is thrown
|
||||
$aReturnData = [
|
||||
'status' => 'error',
|
||||
@@ -398,4 +396,4 @@ JS
|
||||
|
||||
return $oPage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,4 +13,4 @@ class OAuthLandingController extends Controller
|
||||
$this->AddLinkedScript(utils::GetAbsoluteUrlAppRoot().'js/ajax_hook.js');
|
||||
$this->DisplayPage([], null, static::ENUM_PAGE_TYPE_BASIC_HTML);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -38,12 +39,12 @@ class PreferencesController extends AbstractController
|
||||
$sUserPicturesFolder = 'images/user-pictures/';
|
||||
$sImageAbsPath = utils::RealPath(APPROOT.$sUserPicturesFolder.$sImageFilename, APPROOT.$sUserPicturesFolder);
|
||||
$sImageAbsUrl = utils::GetAbsoluteUrlAppRoot().$sUserPicturesFolder.$sImageFilename;
|
||||
|
||||
|
||||
// Check if we're still in the right folder
|
||||
if($sImageAbsPath === false){
|
||||
if ($sImageAbsPath === false) {
|
||||
throw new CoreUnexpectedValue('Error while updating user image, invalid image path "'.$sUserPicturesFolder.$sImageFilename.'"');
|
||||
}
|
||||
|
||||
|
||||
// Check file can be read
|
||||
$sImageData = file_get_contents($sImageAbsPath);
|
||||
if (false === $sImageData) {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -77,4 +78,4 @@ class TemporaryObjectController extends AbstractController
|
||||
'success' => $bResult,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
namespace Combodo\iTop\Controller;
|
||||
|
||||
use Combodo\iTop\Application\WebPage\JsonPage;
|
||||
@@ -13,7 +14,7 @@ use utils;
|
||||
class WelcomePopupController extends AbstractController
|
||||
{
|
||||
/** @inheritDoc */
|
||||
const ROUTE_NAMESPACE = "welcome_popup";
|
||||
public const ROUTE_NAMESPACE = "welcome_popup";
|
||||
|
||||
/**
|
||||
* Acknowledge a specific message for the current user
|
||||
@@ -30,8 +31,7 @@ class WelcomePopupController extends AbstractController
|
||||
$oService->AcknowledgeMessage($sMessageUUID);
|
||||
|
||||
$aResult = ['success' => true];
|
||||
}
|
||||
catch (Exception $oException) {
|
||||
} catch (Exception $oException) {
|
||||
$aResult = [
|
||||
'success' => false,
|
||||
'error_message' => $oException->getMessage(),
|
||||
@@ -42,4 +42,3 @@ class WelcomePopupController extends AbstractController
|
||||
return $oPage;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
|
||||
Reference in New Issue
Block a user