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:
1429
pages/UI.php
1429
pages/UI.php
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
@@ -38,7 +39,7 @@ $oP->LinkScriptFromAppRoot("js/wizardhelper.js");
|
||||
$oP->LinkScriptFromAppRoot("js/wizard.utils.js");
|
||||
$oP->LinkScriptFromAppRoot("js/extkeywidget.js");
|
||||
$oP->LinkScriptFromAppRoot("js/jquery.blockUI.js");
|
||||
|
||||
|
||||
// From now on the context is limited to the the selected organization ??
|
||||
|
||||
// Now render the content of the page
|
||||
@@ -50,11 +51,9 @@ $sOperation = utils::ReadParam('operation', '');
|
||||
|
||||
$oP->SetBreadCrumbEntry('ui-tool-universalsearch', Dict::S('Menu:UniversalSearchMenu'), Dict::S('Menu:UniversalSearchMenu+'), '', 'fas fa-search', iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES);
|
||||
|
||||
|
||||
|
||||
//$sSearchHeaderForceDropdown
|
||||
$sSearchHeaderForceDropdown = '<select id="select_class" name="baseClass" onChange="this.form.submit();">';
|
||||
$aClassLabels = array();
|
||||
$aClassLabels = [];
|
||||
foreach (MetaModel::GetClasses('bizmodel, grant_by_profile') as $sCurrentClass) {
|
||||
if ((MetaModel::HasCategory($sCurrentClass, 'grant_by_profile') && UserRights::IsActionAllowed($sCurrentClass, UR_ACTION_BULK_MODIFY))
|
||||
|| (MetaModel::HasCategory($sCurrentClass, 'bizmodel') && UserRights::IsActionAllowed($sCurrentClass, UR_ACTION_BULK_READ))) {
|
||||
@@ -62,8 +61,7 @@ foreach (MetaModel::GetClasses('bizmodel, grant_by_profile') as $sCurrentClass)
|
||||
}
|
||||
}
|
||||
asort($aClassLabels);
|
||||
foreach($aClassLabels as $sCurrentClass => $sLabel)
|
||||
{
|
||||
foreach ($aClassLabels as $sCurrentClass => $sLabel) {
|
||||
$sDescription = MetaModel::GetClassDescription($sCurrentClass);
|
||||
$sSelected = ($sCurrentClass == $sBaseClass) ? " SELECTED" : "";
|
||||
$sSearchHeaderForceDropdown .= "<option value=\"$sCurrentClass\" title=\"$sDescription\"$sSelected>$sLabel</option>";
|
||||
@@ -71,35 +69,24 @@ foreach($aClassLabels as $sCurrentClass => $sLabel)
|
||||
$sSearchHeaderForceDropdown .= "</select>\n";
|
||||
//end of $sSearchHeaderForceDropdown
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
if ($sOperation == 'search_form')
|
||||
{
|
||||
$sOQL = "SELECT $sClass $sOQLClause";
|
||||
$oFilter = DBObjectSearch::FromOQL($sOQL);
|
||||
}
|
||||
else
|
||||
{
|
||||
try {
|
||||
if ($sOperation == 'search_form') {
|
||||
$sOQL = "SELECT $sClass $sOQLClause";
|
||||
$oFilter = DBObjectSearch::FromOQL($sOQL);
|
||||
} else {
|
||||
// Second part: advanced search form:
|
||||
if (!empty($sFilter))
|
||||
{
|
||||
if (!empty($sFilter)) {
|
||||
$oFilter = DBSearch::unserialize($sFilter);
|
||||
}
|
||||
else if (!empty($sClass))
|
||||
{
|
||||
} elseif (!empty($sClass)) {
|
||||
$oFilter = new DBObjectSearch($sClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (CoreException $e)
|
||||
{
|
||||
} catch (CoreException $e) {
|
||||
$oFilter = new DBObjectSearch($sClass);
|
||||
$oP->P("<b>".Dict::Format('UI:UniversalSearch:Error', $e->getHtmlDesc())."</b>");
|
||||
}
|
||||
|
||||
if ($oFilter != null)
|
||||
{
|
||||
if ($oFilter != null) {
|
||||
$oSet = new CMDBObjectSet($oFilter);
|
||||
$oBlock = new DisplayBlock($oFilter, 'search', false);
|
||||
$aExtraParams = $oAppContext->GetAsHash();
|
||||
@@ -111,7 +98,7 @@ if ($oFilter != null)
|
||||
$aExtraParams['submit_on_load'] = false;
|
||||
$oBlock->Display($oP, 0, $aExtraParams);
|
||||
|
||||
// Search results
|
||||
// Search results
|
||||
$oResultBlock = new DisplayBlock($oFilter, 'list', false);
|
||||
$oResultBlock->Display($oP, 1);
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -34,14 +35,10 @@ require_once(APPROOT.'/application/ui.linkswidget.class.inc.php');
|
||||
function IsIdField($sClassName, $sFieldCode)
|
||||
{
|
||||
$bResult = false;
|
||||
if (!empty($sFieldCode))
|
||||
{
|
||||
if ($sFieldCode == 'id')
|
||||
{
|
||||
if (!empty($sFieldCode)) {
|
||||
if ($sFieldCode == 'id') {
|
||||
$bResult = true;
|
||||
}
|
||||
else if (strpos($sFieldCode, '->') === false)
|
||||
{
|
||||
} elseif (strpos($sFieldCode, '->') === false) {
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClassName, $sFieldCode);
|
||||
$bResult = $oAttDef->IsExternalKey();
|
||||
}
|
||||
@@ -61,26 +58,22 @@ function IsIdField($sClassName, $sFieldCode)
|
||||
*/
|
||||
function GetMappingsForExtKey($sAttCode, AttributeDefinition $oExtKeyAttDef, $bAdvanced)
|
||||
{
|
||||
$aResult = array();
|
||||
$aResult = [];
|
||||
$sTargetClass = $oExtKeyAttDef->GetTargetClass();
|
||||
foreach(MetaModel::ListAttributeDefs($sTargetClass) as $sTargetAttCode => $oTargetAttDef)
|
||||
{
|
||||
if (MetaModel::IsReconcKey($sTargetClass, $sTargetAttCode))
|
||||
{
|
||||
foreach (MetaModel::ListAttributeDefs($sTargetClass) as $sTargetAttCode => $oTargetAttDef) {
|
||||
if (MetaModel::IsReconcKey($sTargetClass, $sTargetAttCode)) {
|
||||
$bExtKey = $oTargetAttDef->IsExternalKey();
|
||||
$sSuffix = '';
|
||||
if ($bExtKey)
|
||||
{
|
||||
if ($bExtKey) {
|
||||
$sSuffix = '->id';
|
||||
}
|
||||
if ($bAdvanced || !$bExtKey)
|
||||
{
|
||||
if ($bAdvanced || !$bExtKey) {
|
||||
// When not in advanced mode do not allow to use reconciliation keys (on external keys) if they are themselves external keys !
|
||||
$aResult[$sAttCode.'->'.$sTargetAttCode] = $oExtKeyAttDef->GetLabel().'->'.$oTargetAttDef->GetLabel().$sSuffix;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $aResult;
|
||||
return $aResult;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -102,15 +95,15 @@ function GetMappingsForExtKey($sAttCode, AttributeDefinition $oExtKeyAttDef, $bA
|
||||
*/
|
||||
function GetMappingForField($sClassName, $sFieldName, $iFieldIndex, $bAdvancedMode, $sDefaultChoice)
|
||||
{
|
||||
$aChoices = array('' => Dict::S('UI:CSVImport:MappingSelectOne'));
|
||||
$aChoices = ['' => Dict::S('UI:CSVImport:MappingSelectOne')];
|
||||
$aChoices[':none:'] = Dict::S('UI:CSVImport:MappingNotApplicable');
|
||||
$sFieldCode = ''; // Code of the attribute, if there is a match
|
||||
$aMatches = array();
|
||||
$aMatches = [];
|
||||
if (preg_match('/^(.+)\*$/', $sFieldName, $aMatches)) {
|
||||
// Remove any trailing "star" character.
|
||||
// A star character at the end can be used to indicate a mandatory field
|
||||
$sFieldName = $aMatches[1];
|
||||
} else if (preg_match('/^(.+)\*->(.+)$/', $sFieldName, $aMatches)) {
|
||||
} elseif (preg_match('/^(.+)\*->(.+)$/', $sFieldName, $aMatches)) {
|
||||
// Remove any trailing "star" character before the arrow (->)
|
||||
// A star character at the end can be used to indicate a mandatory field
|
||||
$sFieldName = $aMatches[1].'->'.$aMatches[2];
|
||||
@@ -135,7 +128,7 @@ function GetMappingForField($sClassName, $sFieldName, $iFieldIndex, $bAdvancedMo
|
||||
// Note: Could not use "MetaModel::GetFriendlyNameAttributeCode($sTargetClass) === $sTargetAttCode" as it would return empty because the friendlyname is composite.
|
||||
if (MetaModel::IsReconcKey($sTargetClass, $sTargetAttCode) || ($oTargetAttDef instanceof AttributeFriendlyName)) {
|
||||
$bExtKey = $oTargetAttDef->IsExternalKey();
|
||||
$aSignatures = array();
|
||||
$aSignatures = [];
|
||||
$aSignatures[] = $oAttDef->GetLabel().'->'.$oTargetAttDef->GetLabel();
|
||||
$aSignatures[] = $sAttCode.'->'.$sTargetAttCode;
|
||||
if ($bExtKey) {
|
||||
@@ -154,8 +147,7 @@ function GetMappingForField($sClassName, $sFieldName, $iFieldIndex, $bAdvancedMo
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (
|
||||
} elseif (
|
||||
($oAttDef->IsWritable() && (!$oAttDef->IsLinkset() || ($bAdvancedMode && $oAttDef->IsIndirect())))
|
||||
|| ($oAttDef instanceof AttributeFriendlyName)
|
||||
) {
|
||||
@@ -171,18 +163,17 @@ function GetMappingForField($sClassName, $sFieldName, $iFieldIndex, $bAdvancedMo
|
||||
$bIsIdField = IsIdField($sClassName, $sFieldCode);
|
||||
foreach ($aChoices as $sAttCode => $sLabel) {
|
||||
$bSelected = false;
|
||||
if ($bIsIdField && (!$bAdvancedMode)) // When not in advanced mode, ID are mapped to n/a
|
||||
{
|
||||
if ($bIsIdField && (!$bAdvancedMode)) { // When not in advanced mode, ID are mapped to n/a
|
||||
if ($sAttCode == ':none:') {
|
||||
$bSelected = true;
|
||||
}
|
||||
} else if (empty($sFieldCode) && (strpos($sFieldName, '->') !== false)) {
|
||||
} elseif (empty($sFieldCode) && (strpos($sFieldName, '->') !== false)) {
|
||||
if ($sAttCode == ':none:') {
|
||||
$bSelected = true;
|
||||
}
|
||||
} else if (is_null($sDefaultChoice) && ($sFieldCode == $sAttCode)) {
|
||||
} elseif (is_null($sDefaultChoice) && ($sFieldCode == $sAttCode)) {
|
||||
$bSelected = true;
|
||||
} else if (!is_null($sDefaultChoice) && ($sDefaultChoice == $sAttCode)) {
|
||||
} elseif (!is_null($sDefaultChoice) && ($sDefaultChoice == $sAttCode)) {
|
||||
$bSelected = true;
|
||||
}
|
||||
$oOption = SelectOptionUIBlockFactory::MakeForSelectOption($sAttCode, $sLabel, $bSelected);
|
||||
@@ -192,19 +183,16 @@ function GetMappingForField($sClassName, $sFieldName, $iFieldIndex, $bAdvancedMo
|
||||
return $oSelect;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
try {
|
||||
require_once(APPROOT.'/application/startup.inc.php');
|
||||
|
||||
require_once(APPROOT.'/application/loginwebpage.class.inc.php');
|
||||
IssueLog::Trace('----- Request: '.utils::GetRequestUri(), LogChannels::WEB_REQUEST);
|
||||
LoginWebPage::DoLogin(); // Check user rights and prompt if needed
|
||||
|
||||
|
||||
$sOperation = utils::ReadParam('operation', '');
|
||||
|
||||
switch($sOperation)
|
||||
{
|
||||
switch ($sOperation) {
|
||||
case 'parser_preview':
|
||||
$oPage = new AjaxPage("");
|
||||
$oPage->SetContentType('text/html');
|
||||
@@ -245,7 +233,7 @@ try
|
||||
$aColumns[] = '';
|
||||
|
||||
// first line as header
|
||||
if($bFirstLineAsHeader){
|
||||
if ($bFirstLineAsHeader) {
|
||||
foreach ($aRow as $sCell) {
|
||||
$aColumns[] = ["label" => utils::EscapeHtml($sCell)];
|
||||
}
|
||||
@@ -254,7 +242,7 @@ try
|
||||
|
||||
// default headers
|
||||
for ($iDataColumnNumber = 0 ; $iDataColumnNumber < count($aRow) ; $iDataColumnNumber++) {
|
||||
$aColumns[] = ["label" => Dict::Format('UI:CSVImport:Column', $iDataColumnNumber+1)];
|
||||
$aColumns[] = ["label" => Dict::Format('UI:CSVImport:Column', $iDataColumnNumber + 1)];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -289,8 +277,8 @@ try
|
||||
|
||||
$sInitFieldMapping = utils::ReadParam('init_field_mapping', '', false, 'raw_data');
|
||||
$sInitSearchField = utils::ReadParam('init_search_field', '', false, 'raw_data');
|
||||
$aInitFieldMapping = empty($sInitFieldMapping) ? array() : json_decode($sInitFieldMapping, true);
|
||||
$aInitSearchField = empty($sInitSearchField) ? array() : json_decode($sInitSearchField, true);
|
||||
$aInitFieldMapping = empty($sInitFieldMapping) ? [] : json_decode($sInitFieldMapping, true);
|
||||
$aInitSearchField = empty($sInitSearchField) ? [] : json_decode($sInitSearchField, true);
|
||||
|
||||
$oCSVParser = new CSVParser($sData, $sSeparator, $sTextQualifier, MetaModel::GetConfig()->Get('max_execution_time_per_loop'));
|
||||
$aData = $oCSVParser->ToArray($iLinesToSkip, null, 3 /* Max: 1 header line + 2 lines of sample data */);
|
||||
@@ -349,7 +337,7 @@ try
|
||||
// Propose a reconciliation scheme
|
||||
//
|
||||
$aReconciliationKeys = MetaModel::GetReconcKeys($sClassName);
|
||||
$aMoreReconciliationKeys = array(); // Store: key => void to automatically remove duplicates
|
||||
$aMoreReconciliationKeys = []; // Store: key => void to automatically remove duplicates
|
||||
foreach ($aReconciliationKeys as $sAttCode) {
|
||||
if (!MetaModel::IsValidAttCode($sClassName, $sAttCode)) {
|
||||
continue;
|
||||
@@ -371,7 +359,7 @@ try
|
||||
} else {
|
||||
// The reconciliation scheme is given (navigating back in the wizard)
|
||||
//
|
||||
$aDefaultKeys = array();
|
||||
$aDefaultKeys = [];
|
||||
foreach ($aInitSearchField as $iSearchField => $void) {
|
||||
$sAttCodeEx = $aInitFieldMapping[$iSearchField];
|
||||
$aDefaultKeys[] = $sAttCodeEx;
|
||||
@@ -380,7 +368,7 @@ try
|
||||
}
|
||||
|
||||
// Read only attributes (will be forced to "search")
|
||||
$aReadOnlyKeys = array();
|
||||
$aReadOnlyKeys = [];
|
||||
foreach (MetaModel::ListAttributeDefs($sClassName) as $sAttCode => $oAttDef) {
|
||||
if (!$oAttDef->IsWritable()) {
|
||||
$aReadOnlyKeys[] = $sAttCode;
|
||||
@@ -397,7 +385,7 @@ try
|
||||
EOF
|
||||
);
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case 'get_csv_template':
|
||||
$sClassName = utils::ReadParam('class_name');
|
||||
@@ -406,7 +394,7 @@ EOF
|
||||
$oSearch = new DBObjectSearch($sClassName);
|
||||
$oSearch->AddCondition('id', 0, '='); // Make sure we create an empty set
|
||||
$oSet = new CMDBObjectSet($oSearch);
|
||||
$sResult = cmdbAbstractObject::GetSetAsCSV($oSet, array('showMandatoryFields' => true));
|
||||
$sResult = cmdbAbstractObject::GetSetAsCSV($oSet, ['showMandatoryFields' => true]);
|
||||
|
||||
$sClassDisplayName = MetaModel::GetName($sClassName);
|
||||
$sDisposition = utils::ReadParam('disposition', 'inline');
|
||||
@@ -419,8 +407,8 @@ EOF
|
||||
require_once(APPROOT.'/application/excelexporter.class.inc.php');
|
||||
$writer = new XLSXWriter();
|
||||
$writer->setAuthor(UserRights::GetUserFriendlyName());
|
||||
$aHeaders = array(0 => explode(',', $sResult)); // comma is the default separator
|
||||
$writer->writeSheet($aHeaders, $sClassDisplayName, array());
|
||||
$aHeaders = [0 => explode(',', $sResult)]; // comma is the default separator
|
||||
$writer->writeSheet($aHeaders, $sClassDisplayName, []);
|
||||
$oPage->add($writer->writeToString());
|
||||
break;
|
||||
|
||||
@@ -446,9 +434,6 @@ EOF
|
||||
break;
|
||||
}
|
||||
$oPage->output();
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
} catch (Exception $e) {
|
||||
IssueLog::Error($e->getMessage());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
@@ -22,16 +23,13 @@ use Combodo\iTop\Application\WebPage\DownloadPage;
|
||||
require_once('../approot.inc.php');
|
||||
require_once(APPROOT.'application/utils.inc.php');
|
||||
|
||||
|
||||
if (array_key_exists('HTTP_IF_MODIFIED_SINCE', $_SERVER) && (strlen($_SERVER['HTTP_IF_MODIFIED_SINCE']) > 0))
|
||||
{
|
||||
if (array_key_exists('HTTP_IF_MODIFIED_SINCE', $_SERVER) && (strlen($_SERVER['HTTP_IF_MODIFIED_SINCE']) > 0)) {
|
||||
// The content is garanteed to be unmodified since the URL includes a signature based on the contents of the document
|
||||
header('Last-Modified: Mon, 1 January 2018 00:00:00 GMT', true, 304); // Any date in the past
|
||||
exit;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
try {
|
||||
require_once(APPROOT.'/application/application.inc.php');
|
||||
require_once(APPROOT.'/application/startup.inc.php');
|
||||
|
||||
@@ -48,19 +46,14 @@ try
|
||||
LoginWebPage::DoLoginEx('backoffice', false);
|
||||
$id = utils::ReadParam('id', '');
|
||||
$sField = utils::ReadParam('field', '');
|
||||
if ($sClass == 'Attachment')
|
||||
{
|
||||
if ($sClass == 'Attachment') {
|
||||
$iCacheSec = 31556926; // One year ahead: an attachment cannot change
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$iCacheSec = (int)utils::ReadParam('cache', 0);
|
||||
}
|
||||
if (!empty($sClass) && ($sClass != 'InlineImage') && !empty($id) && !empty($sField))
|
||||
{
|
||||
if (!empty($sClass) && ($sClass != 'InlineImage') && !empty($id) && !empty($sField)) {
|
||||
ormDocument::DownloadDocument($oPage, $sClass, $id, $sField, 'attachment');
|
||||
if ($iCacheSec > 0)
|
||||
{
|
||||
if ($iCacheSec > 0) {
|
||||
$oPage->set_cache($iCacheSec);
|
||||
// X-Frame http header : set in page constructor, but we need to allow frame integration for this specific page
|
||||
// so we're resetting its value ! (see N°3416)
|
||||
@@ -88,7 +81,7 @@ try
|
||||
$oPage->add_header("Last-Modified: Wed, 15 Jun 2016 13:21:15 GMT"); // An arbitrary date in the past is ok
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 'dict':
|
||||
$sSignature = Utils::ReadParam('s', ''); // Sanitization prevents / and ..
|
||||
$oPage->SetContentType('text/javascript');
|
||||
@@ -100,17 +93,14 @@ try
|
||||
|
||||
$oPage->add(file_get_contents(Utils::GetCachePath().$sSignature.'.js'));
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
$oPage->p("Invalid query.");
|
||||
$oPage->p("Invalid query.");
|
||||
}
|
||||
|
||||
$oPage->output();
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
} catch (Exception $e) {
|
||||
// note: transform to cope with XSS attacks
|
||||
echo utils::EscapeHtml($e->GetMessage());
|
||||
IssueLog::Error($e->getMessage()."\nDebug trace:\n".$e->getTraceAsString());
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -14,8 +15,7 @@ require_once('../approot.inc.php');
|
||||
require_once(APPROOT.'/application/startup.inc.php');
|
||||
IssueLog::Trace('----- Request: '.utils::GetRequestUri(), LogChannels::WEB_REQUEST);
|
||||
|
||||
try
|
||||
{
|
||||
try {
|
||||
$oKPI = new ExecutionKPI();
|
||||
$oKPI->ComputeAndReport('Data model loaded');
|
||||
$oKPI = new ExecutionKPI();
|
||||
@@ -23,8 +23,7 @@ try
|
||||
LoginWebPage::DoLogin();
|
||||
|
||||
$sParams = utils::ReadParam('params', '', false, 'raw_data');
|
||||
if (!$sParams)
|
||||
{
|
||||
if (!$sParams) {
|
||||
throw new AjaxSearchException("Invalid query (empty filter)", 400);
|
||||
}
|
||||
|
||||
@@ -36,61 +35,47 @@ try
|
||||
$aListParams = (array)json_decode($sListParams, true);
|
||||
|
||||
$aParams = json_decode($sParams, true);
|
||||
if (array_key_exists('hidden_criteria', $aListParams))
|
||||
{
|
||||
if (array_key_exists('hidden_criteria', $aListParams)) {
|
||||
$sHiddenCriteria = $aListParams['hidden_criteria'];
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$sHiddenCriteria = '';
|
||||
}
|
||||
$oFilter = CriterionParser::Parse($aParams['base_oql'], $aParams['criterion'], $sHiddenCriteria);
|
||||
$oDisplayBlock = new DisplayBlock($oFilter, 'list_search', false);
|
||||
|
||||
foreach($aListParams as $key => $value)
|
||||
{
|
||||
$aExtraParams[$key] = $value;
|
||||
}
|
||||
foreach ($aListParams as $key => $value) {
|
||||
$aExtraParams[$key] = $value;
|
||||
}
|
||||
|
||||
if (array_key_exists('table_inner_id', $aListParams))
|
||||
{
|
||||
$sListId = utils::Sanitize($aListParams['table_inner_id'], '', utils::ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER);
|
||||
}
|
||||
if (array_key_exists('table_inner_id', $aListParams)) {
|
||||
$sListId = utils::Sanitize($aListParams['table_inner_id'], '', utils::ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER);
|
||||
}
|
||||
|
||||
if (array_key_exists('json', $aListParams))
|
||||
{
|
||||
if (array_key_exists('json', $aListParams)) {
|
||||
$aJson = $aListParams['json'];
|
||||
$sJson = json_encode($aJson);
|
||||
$oWizardHelper = WizardHelper::FromJSON($sJson);
|
||||
$oObj = $oWizardHelper->GetTargetObject();
|
||||
if (array_key_exists('query_params', $aExtraParams))
|
||||
{
|
||||
if (array_key_exists('query_params', $aExtraParams)) {
|
||||
$aExtraParams['query_params']['this->object()'] = $oObj;
|
||||
}
|
||||
else
|
||||
{
|
||||
$aExtraParams['query_params'] = array('this->object()' => $oObj);
|
||||
} else {
|
||||
$aExtraParams['query_params'] = ['this->object()' => $oObj];
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($aExtraParams['update_history']))
|
||||
{
|
||||
if (!isset($aExtraParams['update_history'])) {
|
||||
$aExtraParams['update_history'] = true;
|
||||
}
|
||||
|
||||
$aExtraParams['display_limit'] = true;
|
||||
|
||||
if (isset($sListId))
|
||||
{
|
||||
if (isset($sListId)) {
|
||||
$oPage->AddUiBlock($oDisplayBlock->GetDisplay($oPage, $sListId, $aExtraParams));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$oDisplayBlock->RenderContent($oPage, $aExtraParams);
|
||||
}
|
||||
|
||||
if (isset($aListParams['debug']) || UserRights::IsAdministrator())
|
||||
{
|
||||
if (isset($aListParams['debug']) || UserRights::IsAdministrator()) {
|
||||
$oCollapsible = CollapsibleSectionUIBlockFactory::MakeStandard(Dict::S('UI:RunQuery:MoreInfo'));
|
||||
$oPage->AddSubBlock($oCollapsible);
|
||||
|
||||
@@ -123,4 +108,4 @@ try
|
||||
// note: transform to cope with XSS attacks
|
||||
echo '<html><head></head><body><div>'.utils::EscapeHtml($e->GetMessage()).'</div></body></html>';
|
||||
IssueLog::Error($e->getMessage()."\nDebug trace:\n".$e->getTraceAsString());
|
||||
}
|
||||
}
|
||||
|
||||
328
pages/audit.php
328
pages/audit.php
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -30,44 +31,34 @@ use Combodo\iTop\Application\WebPage\iTopWebPage;
|
||||
*/
|
||||
function FilterByContext(DBSearch &$oFilter, ApplicationContext $oAppContext)
|
||||
{
|
||||
$sObjClass = $oFilter->GetClass();
|
||||
$sObjClass = $oFilter->GetClass();
|
||||
$aContextParams = $oAppContext->GetNames();
|
||||
$aCallSpec = array($sObjClass, 'MapContextParam');
|
||||
if (is_callable($aCallSpec))
|
||||
{
|
||||
foreach($aContextParams as $sParamName)
|
||||
{
|
||||
$aCallSpec = [$sObjClass, 'MapContextParam'];
|
||||
if (is_callable($aCallSpec)) {
|
||||
foreach ($aContextParams as $sParamName) {
|
||||
$sValue = $oAppContext->GetCurrentValue($sParamName, null);
|
||||
if ($sValue != null)
|
||||
{
|
||||
if ($sValue != null) {
|
||||
$sAttCode = call_user_func($aCallSpec, $sParamName); // Returns null when there is no mapping for this parameter
|
||||
if ( ($sAttCode != null) && MetaModel::IsValidAttCode($sObjClass, $sAttCode))
|
||||
{
|
||||
if (($sAttCode != null) && MetaModel::IsValidAttCode($sObjClass, $sAttCode)) {
|
||||
// Check if the condition points to a hierarchical key
|
||||
$bConditionAdded = false;
|
||||
if ($sAttCode == 'id')
|
||||
{
|
||||
$bConditionAdded = false;
|
||||
if ($sAttCode == 'id') {
|
||||
// Filtering on the objects themselves
|
||||
$sHierarchicalKeyCode = MetaModel::IsHierarchicalClass($sObjClass);
|
||||
|
||||
if ($sHierarchicalKeyCode !== false)
|
||||
{
|
||||
|
||||
if ($sHierarchicalKeyCode !== false) {
|
||||
$oRootFilter = new DBObjectSearch($sObjClass);
|
||||
$oRootFilter->AddCondition($sAttCode, $sValue);
|
||||
$oFilter->AddCondition_PointingTo($oRootFilter, $sHierarchicalKeyCode, TREE_OPERATOR_BELOW); // Use the 'below' operator by default
|
||||
$bConditionAdded = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$oAttDef = MetaModel::GetAttributeDef($sObjClass, $sAttCode);
|
||||
$bConditionAdded = false;
|
||||
if ($oAttDef->IsExternalKey())
|
||||
{
|
||||
if ($oAttDef->IsExternalKey()) {
|
||||
$sHierarchicalKeyCode = MetaModel::IsHierarchicalClass($oAttDef->GetTargetClass());
|
||||
|
||||
if ($sHierarchicalKeyCode !== false)
|
||||
{
|
||||
|
||||
if ($sHierarchicalKeyCode !== false) {
|
||||
$oRootFilter = new DBObjectSearch($oAttDef->GetTargetClass());
|
||||
$oRootFilter->AddCondition('id', $sValue);
|
||||
$oHKFilter = new DBObjectSearch($oAttDef->GetTargetClass());
|
||||
@@ -77,8 +68,7 @@ function FilterByContext(DBSearch &$oFilter, ApplicationContext $oAppContext)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!$bConditionAdded)
|
||||
{
|
||||
if (!$bConditionAdded) {
|
||||
$oFilter->AddCondition($sAttCode, $sValue);
|
||||
}
|
||||
}
|
||||
@@ -105,37 +95,28 @@ function GetRuleResultFilter($iRuleId, $oDefinitionFilter, $oAppContext)
|
||||
$oRuleFilter->UpdateContextFromUser();
|
||||
FilterByContext($oRuleFilter, $oAppContext); // Not needed since this filter is a subset of the definition filter, but may speedup things
|
||||
|
||||
if ($oRule->Get('valid_flag') == 'false')
|
||||
{
|
||||
if ($oRule->Get('valid_flag') == 'false') {
|
||||
// The query returns directly the invalid elements
|
||||
$oFilter = $oRuleFilter->Intersect($oDefinitionFilter);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// The query returns only the valid elements, all the others are invalid
|
||||
// Warning : we're generating a `WHERE ID IN`... query, and this could be very slow if there are lots of id !
|
||||
$aValidRows = $oRuleFilter->ToDataArray(array('id'));
|
||||
$aValidIds = array();
|
||||
foreach($aValidRows as $aRow)
|
||||
{
|
||||
$aValidRows = $oRuleFilter->ToDataArray(['id']);
|
||||
$aValidIds = [];
|
||||
foreach ($aValidRows as $aRow) {
|
||||
$aValidIds[] = $aRow['id'];
|
||||
}
|
||||
/** @var \DBObjectSearch $oFilter */
|
||||
$oFilter = $oDefinitionFilter->DeepClone();
|
||||
if (count($aValidIds) > 0)
|
||||
{
|
||||
$aInDefSet = array();
|
||||
foreach($oDefinitionFilter->ToDataArray(array('id')) as $aRow)
|
||||
{
|
||||
if (count($aValidIds) > 0) {
|
||||
$aInDefSet = [];
|
||||
foreach ($oDefinitionFilter->ToDataArray(['id']) as $aRow) {
|
||||
$aInDefSet[] = $aRow['id'];
|
||||
}
|
||||
$aInvalids = array_diff($aInDefSet, $aValidIds);
|
||||
if (count($aInvalids) > 0)
|
||||
{
|
||||
if (count($aInvalids) > 0) {
|
||||
$oFilter->AddConditionForInOperatorUsingParam('id', $aInvalids, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$oFilter->AddCondition('id', 0, '=');
|
||||
}
|
||||
}
|
||||
@@ -143,8 +124,7 @@ function GetRuleResultFilter($iRuleId, $oDefinitionFilter, $oAppContext)
|
||||
return $oFilter;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
try {
|
||||
require_once('../approot.inc.php');
|
||||
require_once(APPROOT.'/application/application.inc.php');
|
||||
require_once(APPROOT.'/application/startup.inc.php');
|
||||
@@ -153,85 +133,77 @@ try
|
||||
$bSelectionAuditRulesByDefault = utils::GetConfig()->Get('audit.enable_selection_landing_page');
|
||||
$operation = utils::ReadParam('operation', $bSelectionAuditRulesByDefault ? 'selection' : 'audit');
|
||||
$oAppContext = new ApplicationContext();
|
||||
|
||||
|
||||
require_once(APPROOT.'/application/loginwebpage.class.inc.php');
|
||||
LoginWebPage::DoLogin(); // Check user rights and prompt if needed
|
||||
|
||||
|
||||
$oP = new iTopWebPage(Dict::S('UI:Audit:Title'));
|
||||
|
||||
switch($operation)
|
||||
{
|
||||
switch ($operation) {
|
||||
case 'csv':
|
||||
$oP->DisableBreadCrumb();
|
||||
// Big result sets cause long OQL that cannot be passed (serialized) as a GET parameter
|
||||
// Therefore we don't use the standard "search_oql" operation of UI.php to display the CSV
|
||||
$iCategory = utils::ReadParam('category', '');
|
||||
$iRuleIndex = utils::ReadParam('rule', 0);
|
||||
|
||||
$oAuditCategory = MetaModel::GetObject('AuditCategory', $iCategory);
|
||||
$oDefinitionFilter = DBObjectSearch::FromOQL($oAuditCategory->Get('definition_set'));
|
||||
$oDefinitionFilter->UpdateContextFromUser();
|
||||
FilterByContext($oDefinitionFilter, $oAppContext);
|
||||
$oDefinitionSet = new CMDBObjectSet($oDefinitionFilter);
|
||||
$oFilter = GetRuleResultFilter($iRuleIndex, $oDefinitionFilter, $oAppContext);
|
||||
$oErrorObjectSet = new CMDBObjectSet($oFilter);
|
||||
$oAuditRule = MetaModel::GetObject('AuditRule', $iRuleIndex);
|
||||
$sFileName = utils::ReadParam('filename', null, true, 'string');
|
||||
$bAdvanced = utils::ReadParam('advanced', false);
|
||||
$sAdvanced = $bAdvanced ? '&advanced=1' : '';
|
||||
|
||||
if ($sFileName != null)
|
||||
{
|
||||
$oP = new CSVPage("iTop - Export");
|
||||
$sCharset = MetaModel::GetConfig()->Get('csv_file_default_charset');
|
||||
$sCSVData = cmdbAbstractObject::GetSetAsCSV($oErrorObjectSet, array('localize_values' => true, 'fields_advanced' => $bAdvanced), $sCharset);
|
||||
if ($sCharset == 'UTF-8')
|
||||
{
|
||||
$sOutputData = UTF8_BOM.$sCSVData;
|
||||
}
|
||||
else
|
||||
{
|
||||
$sOutputData = $sCSVData;
|
||||
}
|
||||
if ($sFileName == '')
|
||||
{
|
||||
// Plain text => Firefox will NOT propose to download the file
|
||||
$oP->add_header("Content-type: text/plain; charset=$sCharset");
|
||||
}
|
||||
else
|
||||
{
|
||||
$sCSVName = basename($sFileName); // pseudo sanitization, just in case
|
||||
// Force the name of the downloaded file, since windows gives precedence to the extension over of the mime type
|
||||
$oP->add_header("Content-disposition: attachment; filename=\"$sCSVName\"");
|
||||
$oP->add_header("Content-type: text/csv; charset=$sCharset");
|
||||
}
|
||||
$oP->add($sOutputData);
|
||||
$oP->TrashUnexpectedOutput();
|
||||
$oP->output();
|
||||
exit;
|
||||
} else {
|
||||
$sTitle = Dict::S('UI:Audit:AuditErrors');
|
||||
$oP->SetBreadCrumbEntry('ui-tool-auditerrors', $sTitle, '', '', 'fas fa-stethoscope', iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES);
|
||||
$oP->DisableBreadCrumb();
|
||||
// Big result sets cause long OQL that cannot be passed (serialized) as a GET parameter
|
||||
// Therefore we don't use the standard "search_oql" operation of UI.php to display the CSV
|
||||
$iCategory = utils::ReadParam('category', '');
|
||||
$iRuleIndex = utils::ReadParam('rule', 0);
|
||||
|
||||
$oBackButton = ButtonUIBlockFactory::MakeIconLink('fas fa-chevron-left', Dict::S('UI:Audit:InteractiveAudit:Back'), "./audit.php?".$oAppContext->GetForLink());
|
||||
$oP->AddUiBlock($oBackButton);
|
||||
$oP->AddUiBlock(TitleUIBlockFactory::MakeForPage($sTitle.$oAuditRule->Get('description')));
|
||||
$oAuditCategory = MetaModel::GetObject('AuditCategory', $iCategory);
|
||||
$oDefinitionFilter = DBObjectSearch::FromOQL($oAuditCategory->Get('definition_set'));
|
||||
$oDefinitionFilter->UpdateContextFromUser();
|
||||
FilterByContext($oDefinitionFilter, $oAppContext);
|
||||
$oDefinitionSet = new CMDBObjectSet($oDefinitionFilter);
|
||||
$oFilter = GetRuleResultFilter($iRuleIndex, $oDefinitionFilter, $oAppContext);
|
||||
$oErrorObjectSet = new CMDBObjectSet($oFilter);
|
||||
$oAuditRule = MetaModel::GetObject('AuditRule', $iRuleIndex);
|
||||
$sFileName = utils::ReadParam('filename', null, true, 'string');
|
||||
$bAdvanced = utils::ReadParam('advanced', false);
|
||||
$sAdvanced = $bAdvanced ? '&advanced=1' : '';
|
||||
|
||||
$sBlockId = 'audit_errors';
|
||||
$oP->p("<div id=\"$sBlockId\">");
|
||||
$oBlock = DisplayBlock::FromObjectSet($oErrorObjectSet, 'csv', array('show_obsolete_data' => true));
|
||||
$oBlock->Display($oP, 1);
|
||||
$oP->p("</div>");
|
||||
// Adjust the size of the Textarea containing the CSV to fit almost all the remaining space
|
||||
$oP->add_ready_script(" $('#1>textarea').height(400);"); // adjust the size of the block
|
||||
$sExportUrl = utils::GetAbsoluteUrlAppRoot()."pages/audit.php?operation=csv&category=".$oAuditCategory->GetKey()."&rule=".$oAuditRule->GetKey();
|
||||
$oDownloadButton = ButtonUIBlockFactory::MakeForAlternativePrimaryAction('fas fa-chevron-left', Dict::S('UI:Audit:InteractiveAudit:Back'), "./audit.php?".$oAppContext->GetForLink());
|
||||
if ($sFileName != null) {
|
||||
$oP = new CSVPage("iTop - Export");
|
||||
$sCharset = MetaModel::GetConfig()->Get('csv_file_default_charset');
|
||||
$sCSVData = cmdbAbstractObject::GetSetAsCSV($oErrorObjectSet, ['localize_values' => true, 'fields_advanced' => $bAdvanced], $sCharset);
|
||||
if ($sCharset == 'UTF-8') {
|
||||
$sOutputData = UTF8_BOM.$sCSVData;
|
||||
} else {
|
||||
$sOutputData = $sCSVData;
|
||||
}
|
||||
if ($sFileName == '') {
|
||||
// Plain text => Firefox will NOT propose to download the file
|
||||
$oP->add_header("Content-type: text/plain; charset=$sCharset");
|
||||
} else {
|
||||
$sCSVName = basename($sFileName); // pseudo sanitization, just in case
|
||||
// Force the name of the downloaded file, since windows gives precedence to the extension over of the mime type
|
||||
$oP->add_header("Content-disposition: attachment; filename=\"$sCSVName\"");
|
||||
$oP->add_header("Content-type: text/csv; charset=$sCharset");
|
||||
}
|
||||
$oP->add($sOutputData);
|
||||
$oP->TrashUnexpectedOutput();
|
||||
$oP->output();
|
||||
exit;
|
||||
} else {
|
||||
$sTitle = Dict::S('UI:Audit:AuditErrors');
|
||||
$oP->SetBreadCrumbEntry('ui-tool-auditerrors', $sTitle, '', '', 'fas fa-stethoscope', iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES);
|
||||
|
||||
$oBackButton = ButtonUIBlockFactory::MakeIconLink('fas fa-chevron-left', Dict::S('UI:Audit:InteractiveAudit:Back'), "./audit.php?".$oAppContext->GetForLink());
|
||||
$oP->AddUiBlock($oBackButton);
|
||||
$oP->AddUiBlock(TitleUIBlockFactory::MakeForPage($sTitle.$oAuditRule->Get('description')));
|
||||
|
||||
$sBlockId = 'audit_errors';
|
||||
$oP->p("<div id=\"$sBlockId\">");
|
||||
$oBlock = DisplayBlock::FromObjectSet($oErrorObjectSet, 'csv', ['show_obsolete_data' => true]);
|
||||
$oBlock->Display($oP, 1);
|
||||
$oP->p("</div>");
|
||||
// Adjust the size of the Textarea containing the CSV to fit almost all the remaining space
|
||||
$oP->add_ready_script(" $('#1>textarea').height(400);"); // adjust the size of the block
|
||||
$sExportUrl = utils::GetAbsoluteUrlAppRoot()."pages/audit.php?operation=csv&category=".$oAuditCategory->GetKey()."&rule=".$oAuditRule->GetKey();
|
||||
$oDownloadButton = ButtonUIBlockFactory::MakeForAlternativePrimaryAction('fas fa-chevron-left', Dict::S('UI:Audit:InteractiveAudit:Back'), "./audit.php?".$oAppContext->GetForLink());
|
||||
|
||||
$oP->add_ready_script("$('a[href*=\"webservices/export.php?expression=\"]').attr('href', '".$sExportUrl."&filename=audit.csv".$sAdvanced."');");
|
||||
$oP->add_ready_script("$('#1 :checkbox').removeAttr('onclick').on('click', function() { var sAdvanced = ''; if (this.checked) sAdvanced = '&advanced=1'; window.location.href='$sExportUrl'+sAdvanced; } );");
|
||||
}
|
||||
break;
|
||||
|
||||
$oP->add_ready_script("$('a[href*=\"webservices/export.php?expression=\"]').attr('href', '".$sExportUrl."&filename=audit.csv".$sAdvanced."');");
|
||||
$oP->add_ready_script("$('#1 :checkbox').removeAttr('onclick').on('click', function() { var sAdvanced = ''; if (this.checked) sAdvanced = '&advanced=1'; window.location.href='$sExportUrl'+sAdvanced; } );");
|
||||
}
|
||||
break;
|
||||
|
||||
case 'errors':
|
||||
$sTitle = Dict::S('UI:Audit:AuditErrors');
|
||||
$iCategory = utils::ReadParam('category', '');
|
||||
@@ -253,7 +225,7 @@ try
|
||||
$oP->AddUiBlock(TitleUIBlockFactory::MakeForPage($sTitle.$oAuditRule->Get('description')));
|
||||
$sBlockId = 'audit_errors';
|
||||
$oP->p("<div id=\"$sBlockId\">");
|
||||
$oBlock = DisplayBlock::FromObjectSet($oErrorObjectSet, 'list', array('show_obsolete_data' => true));
|
||||
$oBlock = DisplayBlock::FromObjectSet($oErrorObjectSet, 'list', ['show_obsolete_data' => true]);
|
||||
$oBlock->Display($oP, 1);
|
||||
$oP->p("</div>");
|
||||
$sExportUrl = utils::GetAbsoluteUrlAppRoot()."pages/audit.php?operation=csv&category=".$oAuditCategory->GetKey()."&rule=".$oAuditRule->GetKey();
|
||||
@@ -299,13 +271,13 @@ try
|
||||
|
||||
// Fetch all audit domains with at least on linked category
|
||||
$oDomainSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT AuditDomain AS domain JOIN lnkAuditCategoryToAuditDomain AS lnk ON lnk.domain_id = domain.id"));
|
||||
$oDomainSet->SetOrderBy(array('name' => true));
|
||||
$oDomainSet->SetOrderBy(['name' => true]);
|
||||
$iDomainCnt = 0;
|
||||
/** @var AuditDomain $oAuditDomain */
|
||||
while($oAuditDomain = $oDomainSet->Fetch()) {
|
||||
while ($oAuditDomain = $oDomainSet->Fetch()) {
|
||||
$sDomainUrl = utils::GetAbsoluteUrlAppRoot()."pages/audit.php?operation=audit&domain=".$oAuditDomain->GetKey();
|
||||
$sIconUrl = utils::GetAbsoluteUrlAppRoot().'images/icons/icons8-puzzle.svg';
|
||||
/** @var \ormDocument $oImage */
|
||||
/** @var \ormDocument $oImage */
|
||||
$oImage = $oAuditDomain->Get('icon');
|
||||
if (!$oImage->IsEmpty()) {
|
||||
$sIconUrl = $oImage->GetDisplayURL(get_class($oAuditDomain), $oAuditDomain->GetKey(), 'icon');
|
||||
@@ -333,7 +305,7 @@ try
|
||||
$sBreadCrumbTooltip = Dict::S('UI:Audit:Interactive:All:BreadCrumb+');
|
||||
|
||||
if (!empty($sCategories)) { // Case with a set of categories
|
||||
$oCategoriesSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT AuditCategory WHERE id IN (:categories)", array('categories' => explode(',', $sCategories))));
|
||||
$oCategoriesSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT AuditCategory WHERE id IN (:categories)", ['categories' => explode(',', $sCategories)]));
|
||||
$sCategories = implode(", ", $oCategoriesSet->GetColumnAsArray('name'));
|
||||
$oCategoriesSet->Rewind();
|
||||
$sTitle = Dict::Format('UI:Audit:Interactive:Categories:Title', $sCategories);
|
||||
@@ -343,7 +315,7 @@ try
|
||||
|
||||
} elseif (!empty($sDomainKey)) { // Case with a single Domain
|
||||
$oAuditDomain = MetaModel::GetObject('AuditDomain', $sDomainKey);
|
||||
$oCategoriesSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT AuditCategory AS c JOIN lnkAuditCategoryToAuditDomain AS lnk ON lnk.category_id = c.id WHERE lnk.domain_id = :domain", array('domain' => $oAuditDomain->GetKey())));
|
||||
$oCategoriesSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT AuditCategory AS c JOIN lnkAuditCategoryToAuditDomain AS lnk ON lnk.category_id = c.id WHERE lnk.domain_id = :domain", ['domain' => $oAuditDomain->GetKey()]));
|
||||
$sDomainName = $oAuditDomain->GetName();
|
||||
$sTitle = Dict::Format('UI:Audit:Interactive:Domain:Title', $sDomainName);
|
||||
$sSubTitle = Dict::Format('UI:Audit:Interactive:Domain:SubTitle', $sDomainName);
|
||||
@@ -400,16 +372,16 @@ try
|
||||
// Add a button in the above toolbar
|
||||
$sAuditCategoryClass = get_class($oAuditCategory);
|
||||
if (UserRights::IsActionAllowed($sAuditCategoryClass, UR_ACTION_READ)) {
|
||||
$oToolbar->AddSubBlock(ButtonUIBlockFactory::MakeIconLink('fas fa-wrench fa-lg', Dict::S('UI:Audit:ViewRules'), ApplicationContext::MakeObjectUrl($sAuditCategoryClass, $oAuditCategory->GetKey()).'&#ObjectProperties=tab_ClassAuditCategoryAttributerules_list'),);
|
||||
$oToolbar->AddSubBlock(ButtonUIBlockFactory::MakeIconLink('fas fa-wrench fa-lg', Dict::S('UI:Audit:ViewRules'), ApplicationContext::MakeObjectUrl($sAuditCategoryClass, $oAuditCategory->GetKey()).'&#ObjectProperties=tab_ClassAuditCategoryAttributerules_list'), );
|
||||
}
|
||||
$aResults = array();
|
||||
$aResults = [];
|
||||
try {
|
||||
$iCount = 0;
|
||||
$oDefinitionFilter = DBObjectSearch::FromOQL($oAuditCategory->Get('definition_set'));
|
||||
$oDefinitionFilter->UpdateContextFromUser();
|
||||
FilterByContext($oDefinitionFilter, $oAppContext);
|
||||
|
||||
$aObjectsWithErrors = array();
|
||||
$aObjectsWithErrors = [];
|
||||
if (!empty($currentOrganization)) {
|
||||
if (MetaModel::IsValidFilterCode($oDefinitionFilter->GetClass(), 'org_id')) {
|
||||
$oDefinitionFilter->AddCondition('org_id', $currentOrganization, '=');
|
||||
@@ -421,7 +393,7 @@ try
|
||||
$oRulesFilter->AddCondition('category_id', $oAuditCategory->GetKey(), '=');
|
||||
$oRulesSet = new DBObjectSet($oRulesFilter);
|
||||
while ($oAuditRule = $oRulesSet->fetch()) {
|
||||
$aRow = array();
|
||||
$aRow = [];
|
||||
$aRow['description'] = $oAuditRule->GetName();
|
||||
if ($iCount == 0) {
|
||||
// nothing to check, really !
|
||||
@@ -431,16 +403,15 @@ try
|
||||
} else {
|
||||
try {
|
||||
$oFilter = GetRuleResultFilter($oAuditRule->GetKey(), $oDefinitionFilter, $oAppContext);
|
||||
$aErrors = $oFilter->SelectAttributeToArray('id');
|
||||
$aErrors = $oFilter->SelectAttributeToArray('id');
|
||||
$iErrorsCount = count($aErrors);
|
||||
foreach ($aErrors as $aErrorRow) {
|
||||
$aObjectsWithErrors[$aErrorRow['id']] = true;
|
||||
}
|
||||
$aRow['nb_errors'] = ($iErrorsCount == 0) ? '0' : "<a href=\"?operation=errors&category=".$oAuditCategory->GetKey()."&rule=".$oAuditRule->GetKey().$oAppContext->GetForLink(true)."\">$iErrorsCount</a> <a href=\"?operation=csv&category=".$oAuditCategory->GetKey()."&rule=".$oAuditRule->GetKey().$oAppContext->GetForLink(true)."\"><img src=\"" . utils::GetAbsoluteUrlAppRoot() . "images/icons/icons8-export-csv.svg\" class=\"ibo-audit--audit-line--csv-download\"></a>";
|
||||
$aRow['nb_errors'] = ($iErrorsCount == 0) ? '0' : "<a href=\"?operation=errors&category=".$oAuditCategory->GetKey()."&rule=".$oAuditRule->GetKey().$oAppContext->GetForLink(true)."\">$iErrorsCount</a> <a href=\"?operation=csv&category=".$oAuditCategory->GetKey()."&rule=".$oAuditRule->GetKey().$oAppContext->GetForLink(true)."\"><img src=\"".utils::GetAbsoluteUrlAppRoot()."images/icons/icons8-export-csv.svg\" class=\"ibo-audit--audit-line--csv-download\"></a>";
|
||||
$aRow['percent_ok'] = sprintf('%.2f', 100.0 * (($iCount - $iErrorsCount) / $iCount));
|
||||
$aRow['class'] = $oAuditCategory->GetReportColor($iCount, $iErrorsCount);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
$aRow['nb_errors'] = Dict::S('UI:Audit:OqlError');
|
||||
$aRow['percent_ok'] = Dict::S('UI:Audit:Error:ValueNA');
|
||||
$aRow['class'] = 'red';
|
||||
@@ -462,57 +433,50 @@ try
|
||||
$oWorkingBlock->SetCount((int)$oWorkingBlock->GetCount() + ($iCount - $iTotalErrors));
|
||||
$oAuditCategoryPanelBlock->SetSubTitle(Dict::Format('UI:Audit:AuditCategory:Subtitle', $iTotalErrors, $iCount, $sOverallPercentOk));
|
||||
|
||||
} catch (Exception $e) {
|
||||
$sMessage = Dict::Format('UI:Audit:ErrorIn_Category_Reason', $oAuditCategory->GetHyperlink(), utils::HtmlEntities($e->getMessage()));
|
||||
$oErrorAlert = AlertUIBlockFactory::MakeForFailure(Dict::S('UI:Audit:ErrorIn_Category'), $sMessage);
|
||||
$oErrorAlert->AddCSSClass('ibo-audit--error-alert');
|
||||
$oP->AddUiBlock($oErrorAlert);
|
||||
continue;
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
$sMessage = Dict::Format('UI:Audit:ErrorIn_Category_Reason', $oAuditCategory->GetHyperlink(), utils::HtmlEntities($e->getMessage()));
|
||||
$oErrorAlert = AlertUIBlockFactory::MakeForFailure(Dict::S('UI:Audit:ErrorIn_Category'), $sMessage);
|
||||
$oErrorAlert->AddCSSClass('ibo-audit--error-alert');
|
||||
$oP->AddUiBlock($oErrorAlert);
|
||||
continue;
|
||||
|
||||
$oAuditCategoryPanelBlock->SetColorFromColorSemantic($sClass);
|
||||
$oAuditCategoryPanelBlock->AddCSSClass('ibo-audit--audit-category--panel');
|
||||
$aData = [];
|
||||
foreach ($aResults as $aRow) {
|
||||
$aData[] = [
|
||||
'audit_rule' => $aRow['description'],
|
||||
'nb_err' => $aRow['nb_errors'],
|
||||
'percentage_ok' => $aRow['percent_ok'],
|
||||
'@class' => 'ibo-is-'.$aRow['class'].'',
|
||||
];
|
||||
}
|
||||
|
||||
$aAttribs = [
|
||||
'audit_rule' => ['label' => Dict::S('UI:Audit:HeaderAuditRule'), 'description' => Dict::S('UI:Audit:HeaderAuditRule')],
|
||||
'nb_err' => ['label' => Dict::S('UI:Audit:HeaderNbErrors'), 'description' => Dict::S('UI:Audit:HeaderNbErrors')],
|
||||
'percentage_ok' => ['label' => Dict::S('UI:Audit:PercentageOk'), 'description' => Dict::S('UI:Audit:PercentageOk')],
|
||||
];
|
||||
|
||||
$oAttachmentTableBlock = DataTableUIBlockFactory::MakeForStaticData('', $aAttribs, $aData, null, [], "", ['pageLength' => -1]);
|
||||
$oAuditCategoryPanelBlock->AddSubBlock($oAttachmentTableBlock);
|
||||
$aAuditCategoryPanels[] = $oAuditCategoryPanelBlock;
|
||||
}
|
||||
|
||||
$oAuditCategoryPanelBlock->SetColorFromColorSemantic($sClass);
|
||||
$oAuditCategoryPanelBlock->AddCSSClass('ibo-audit--audit-category--panel');
|
||||
$aData = [];
|
||||
foreach($aResults as $aRow)
|
||||
{
|
||||
$aData[] = array(
|
||||
'audit_rule' => $aRow['description'],
|
||||
'nb_err' => $aRow['nb_errors'],
|
||||
'percentage_ok' => $aRow['percent_ok'],
|
||||
'@class' => 'ibo-is-'.$aRow['class'].'',
|
||||
);
|
||||
foreach ($aAuditCategoryPanels as $oAuditCategoryPanel) {
|
||||
$oP->AddUiBlock($oAuditCategoryPanel);
|
||||
}
|
||||
|
||||
$aAttribs = array(
|
||||
'audit_rule' => array('label' => Dict::S('UI:Audit:HeaderAuditRule'), 'description' => Dict::S('UI:Audit:HeaderAuditRule')),
|
||||
'nb_err' => array('label' => Dict::S('UI:Audit:HeaderNbErrors'), 'description' => Dict::S('UI:Audit:HeaderNbErrors')),
|
||||
'percentage_ok' => array('label' => Dict::S('UI:Audit:PercentageOk'), 'description' => Dict::S('UI:Audit:PercentageOk')),
|
||||
);
|
||||
|
||||
$oAttachmentTableBlock = DataTableUIBlockFactory::MakeForStaticData('', $aAttribs, $aData, null, [], "", array('pageLength' => -1));
|
||||
$oAuditCategoryPanelBlock->AddSubBlock($oAttachmentTableBlock);
|
||||
$aAuditCategoryPanels[] = $oAuditCategoryPanelBlock;
|
||||
}
|
||||
foreach ($aAuditCategoryPanels as $oAuditCategoryPanel) {
|
||||
$oP->AddUiBlock($oAuditCategoryPanel);
|
||||
}
|
||||
}
|
||||
$oP->output();
|
||||
}
|
||||
catch(CoreException $e)
|
||||
{
|
||||
} catch (CoreException $e) {
|
||||
require_once(APPROOT.'/setup/setuppage.class.inc.php');
|
||||
$oP = new ErrorPage(Dict::S('UI:PageTitle:FatalError'));
|
||||
$oP->add("<h1>".Dict::S('UI:FatalErrorMessage')."</h1>\n");
|
||||
$oP->error(Dict::Format('UI:Error_Details', $e->getHtmlDesc()));
|
||||
$oP->add("<h1>".Dict::S('UI:FatalErrorMessage')."</h1>\n");
|
||||
$oP->error(Dict::Format('UI:Error_Details', $e->getHtmlDesc()));
|
||||
$oP->output();
|
||||
|
||||
if (MetaModel::IsLogEnabledIssue())
|
||||
{
|
||||
if (MetaModel::IsValidClass('EventIssue'))
|
||||
{
|
||||
if (MetaModel::IsLogEnabledIssue()) {
|
||||
if (MetaModel::IsValidClass('EventIssue')) {
|
||||
$oLog = new EventIssue();
|
||||
|
||||
$oLog->Set('message', $e->getMessage());
|
||||
@@ -529,19 +493,15 @@ catch(CoreException $e)
|
||||
|
||||
// For debugging only
|
||||
//throw $e;
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
} catch (Exception $e) {
|
||||
require_once(APPROOT.'/setup/setuppage.class.inc.php');
|
||||
$oP = new ErrorPage(Dict::S('UI:PageTitle:FatalError'));
|
||||
$oP->add("<h1>".Dict::S('UI:FatalErrorMessage')."</h1>\n");
|
||||
$oP->error(Dict::Format('UI:Error_Details', $e->getMessage()));
|
||||
$oP->add("<h1>".Dict::S('UI:FatalErrorMessage')."</h1>\n");
|
||||
$oP->error(Dict::Format('UI:Error_Details', $e->getMessage()));
|
||||
$oP->output();
|
||||
|
||||
if (MetaModel::IsLogEnabledIssue())
|
||||
{
|
||||
if (MetaModel::IsValidClass('EventIssue'))
|
||||
{
|
||||
if (MetaModel::IsLogEnabledIssue()) {
|
||||
if (MetaModel::IsValidClass('EventIssue')) {
|
||||
$oLog = new EventIssue();
|
||||
|
||||
$oLog->Set('message', $e->getMessage());
|
||||
@@ -549,7 +509,7 @@ catch(Exception $e)
|
||||
$oLog->Set('issue', 'PHP Exception');
|
||||
$oLog->Set('impact', 'Page could not be displayed');
|
||||
$oLog->Set('callstack', $e->getTrace());
|
||||
$oLog->Set('data', array());
|
||||
$oLog->Set('data', []);
|
||||
$oLog->DBInsertNoReload();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -87,8 +88,8 @@ try {
|
||||
$oSelectBlock = SelectUIBlockFactory::MakeForSelect($sName, 'select_'.$sName);
|
||||
$oOption = SelectOptionUIBlockFactory::MakeForSelectOption("", Dict::S('UI:CSVImport:ClassesSelectOne'), false);
|
||||
$oSelectBlock->AddSubBlock($oOption);
|
||||
$aValidClasses = array();
|
||||
$aClassCategories = array('bizmodel', 'addon/authentication');
|
||||
$aValidClasses = [];
|
||||
$aClassCategories = ['bizmodel', 'addon/authentication'];
|
||||
if ($bAdvanced) {
|
||||
$aClassCategories[] = 'grant_by_profile';
|
||||
}
|
||||
@@ -136,10 +137,9 @@ try {
|
||||
*/
|
||||
function CountCharsFromSet($sString, $aSet)
|
||||
{
|
||||
$aResult = array();
|
||||
$aResult = [];
|
||||
$aCount = count_chars($sString);
|
||||
foreach($aSet as $sChar)
|
||||
{
|
||||
foreach ($aSet as $sChar) {
|
||||
$aResult[$sChar] = isset($aCount[ord($sChar)]) ? $aCount[ord($sChar)] : 0;
|
||||
}
|
||||
return $aResult;
|
||||
@@ -155,35 +155,33 @@ try {
|
||||
{
|
||||
$iLine = 0;
|
||||
$iMaxLine = 20; // Process max 20 lines to guess the parameters
|
||||
foreach($aPossibleSeparators as $sSep)
|
||||
{
|
||||
foreach ($aPossibleSeparators as $sSep) {
|
||||
$aGuesses[$sSep]['total'] = $aGuesses[$sSep]['max'] = 0;
|
||||
$aGuesses[$sSep]['min'] = 999;
|
||||
}
|
||||
$aStats = array();
|
||||
while(($iLine < count($aCSVData)) && ($iLine < $iMaxLine) )
|
||||
{
|
||||
if (strlen($aCSVData[$iLine]) > 0)
|
||||
{
|
||||
$aStats = [];
|
||||
while (($iLine < count($aCSVData)) && ($iLine < $iMaxLine)) {
|
||||
if (strlen($aCSVData[$iLine]) > 0) {
|
||||
$aStats[$iLine] = CountCharsFromSet($aCSVData[$iLine], $aPossibleSeparators);
|
||||
}
|
||||
$iLine++;
|
||||
}
|
||||
$iLine = 1;
|
||||
foreach($aStats as $aLineStats)
|
||||
{
|
||||
foreach($aPossibleSeparators as $sSep)
|
||||
{
|
||||
foreach ($aStats as $aLineStats) {
|
||||
foreach ($aPossibleSeparators as $sSep) {
|
||||
$aGuesses[$sSep]['total'] += $aLineStats[$sSep];
|
||||
if ($aLineStats[$sSep] > $aGuesses[$sSep]['max']) $aGuesses[$sSep]['max'] = $aLineStats[$sSep];
|
||||
if ($aLineStats[$sSep] < $aGuesses[$sSep]['min']) $aGuesses[$sSep]['min'] = $aLineStats[$sSep];
|
||||
if ($aLineStats[$sSep] > $aGuesses[$sSep]['max']) {
|
||||
$aGuesses[$sSep]['max'] = $aLineStats[$sSep];
|
||||
}
|
||||
if ($aLineStats[$sSep] < $aGuesses[$sSep]['min']) {
|
||||
$aGuesses[$sSep]['min'] = $aLineStats[$sSep];
|
||||
}
|
||||
}
|
||||
$iLine++;
|
||||
}
|
||||
|
||||
$aScores = array();
|
||||
foreach($aGuesses as $sSep => $aData)
|
||||
{
|
||||
$aScores = [];
|
||||
foreach ($aGuesses as $sSep => $aData) {
|
||||
$aScores[$sSep] = $aData['total'] + $aData['max'] - $aData['min'];
|
||||
}
|
||||
arsort($aScores, SORT_NUMERIC); // Sort the array, higher scores first
|
||||
@@ -200,10 +198,10 @@ try {
|
||||
function GuessParameters($sCSVData)
|
||||
{
|
||||
$aData = explode("\n", $sCSVData);
|
||||
$sSeparator = GuessFromFrequency($aData, array("\t", ',', ';', '|')); // Guess the most frequent (and regular) character on each line
|
||||
$sQualifier = GuessFromFrequency($aData, array('"', "'")); // Guess the most frequent (and regular) character on each line
|
||||
$sSeparator = GuessFromFrequency($aData, ["\t", ',', ';', '|']); // Guess the most frequent (and regular) character on each line
|
||||
$sQualifier = GuessFromFrequency($aData, ['"', "'"]); // Guess the most frequent (and regular) character on each line
|
||||
|
||||
return array('separator' => $sSeparator, 'qualifier' => $sQualifier);
|
||||
return ['separator' => $sSeparator, 'qualifier' => $sQualifier];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -212,10 +210,10 @@ try {
|
||||
* @param string $sClass The class of objects to synchronize
|
||||
* @param integer $iCount The number of objects to synchronize
|
||||
*/
|
||||
function DisplaySynchroBanner(WebPage $oP, $sClass, $iCount)
|
||||
{
|
||||
$oP->AddSubBlock(AlertUIBlockFactory::MakeForInformation(MetaModel::GetClassIcon($sClass)." ".Dict::Format('UI:Title:BulkSynchro_nbItem_ofClass_class', $iCount, MetaModel::GetName($sClass))));
|
||||
}
|
||||
function DisplaySynchroBanner(WebPage $oP, $sClass, $iCount)
|
||||
{
|
||||
$oP->AddSubBlock(AlertUIBlockFactory::MakeForInformation(MetaModel::GetClassIcon($sClass)." ".Dict::Format('UI:Title:BulkSynchro_nbItem_ofClass_class', $iCount, MetaModel::GetName($sClass))));
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the CSV data, for real or as a simulation
|
||||
@@ -232,11 +230,11 @@ try {
|
||||
}
|
||||
|
||||
// CSRF transaction id verification
|
||||
if(!utils::IsTransactionValid(utils::ReadPostedParam('transaction_id', '', 'raw_data'))){
|
||||
if (!utils::IsTransactionValid(utils::ReadPostedParam('transaction_id', '', 'raw_data'))) {
|
||||
throw new CoreException(Dict::S('UI:Error:InvalidToken'));
|
||||
}
|
||||
|
||||
$aResult = array();
|
||||
$aResult = [];
|
||||
$sCSVData = utils::ReadParam('csvdata', '', false, 'raw_data');
|
||||
$sCSVDataTruncated = utils::ReadParam('csvdata_truncated', '', false, 'raw_data');
|
||||
$sSeparator = utils::ReadParam('separator', ',', false, 'raw_data');
|
||||
@@ -244,23 +242,41 @@ try {
|
||||
$bHeaderLine = (utils::ReadParam('header_line', '0') == 1);
|
||||
$iNbSkippedLines = utils::ReadParam('nb_skipped_lines', '0');
|
||||
$iBoxSkipLines = utils::ReadParam('box_skiplines', '0');
|
||||
$aFieldsMapping = utils::ReadParam('field', array(), false, 'raw_data');
|
||||
$aSearchFields = utils::ReadParam('search_field', array(), false, 'field_name');
|
||||
$aFieldsMapping = utils::ReadParam('field', [], false, 'raw_data');
|
||||
$aSearchFields = utils::ReadParam('search_field', [], false, 'field_name');
|
||||
$iCurrentStep = $bSimulate ? 4 : 5;
|
||||
$bAdvanced = utils::ReadParam('advanced', 0);
|
||||
$sEncoding = utils::ReadParam('encoding', 'UTF-8');
|
||||
$sSynchroScope = utils::ReadParam('synchro_scope', '', false, 'raw_data');
|
||||
$aSynchroUpdate = utils::ReadParam('synchro_update', array());
|
||||
$aSynchroUpdate = utils::ReadParam('synchro_update', []);
|
||||
$sDateTimeFormat = utils::ReadParam('date_time_format', 'default');
|
||||
$sCustomDateTimeFormat = utils::ReadParam('custom_date_time_format', (string)AttributeDateTime::GetFormat(), false, 'raw_data');
|
||||
|
||||
return CSVImportPageProcessor::ProcessData($iBoxSkipLines, $iNbSkippedLines, $sDateTimeFormat, $sCustomDateTimeFormat, $sClassName, $oPage, $aSynchroUpdate, $sCSVData, $sSeparator, $sTextQualifier, $bHeaderLine, $aResult, $aSearchFields, $aFieldsMapping, $bSimulate, $sCSVDataTruncated,
|
||||
$iCurrentStep, $sEncoding,
|
||||
$bAdvanced, $sSynchroScope);
|
||||
return CSVImportPageProcessor::ProcessData(
|
||||
$iBoxSkipLines,
|
||||
$iNbSkippedLines,
|
||||
$sDateTimeFormat,
|
||||
$sCustomDateTimeFormat,
|
||||
$sClassName,
|
||||
$oPage,
|
||||
$aSynchroUpdate,
|
||||
$sCSVData,
|
||||
$sSeparator,
|
||||
$sTextQualifier,
|
||||
$bHeaderLine,
|
||||
$aResult,
|
||||
$aSearchFields,
|
||||
$aFieldsMapping,
|
||||
$bSimulate,
|
||||
$sCSVDataTruncated,
|
||||
$iCurrentStep,
|
||||
$sEncoding,
|
||||
$bAdvanced,
|
||||
$sSynchroScope
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Perform the actual load of the CSV data and display the results
|
||||
* @param WebPage $oPage The web page to display the wizard
|
||||
@@ -306,14 +322,14 @@ try {
|
||||
$sCSVData = utils::ReadParam('csvdata', '', false, 'raw_data');
|
||||
$sCSVDataTruncated = utils::ReadParam('csvdata_truncated', '', false, 'raw_data');
|
||||
$sSeparator = utils::ReadParam('separator', ',', false, 'raw_data');
|
||||
if ($sSeparator == 'tab') $sSeparator = "\t";
|
||||
if ($sSeparator == 'other')
|
||||
{
|
||||
if ($sSeparator == 'tab') {
|
||||
$sSeparator = "\t";
|
||||
}
|
||||
if ($sSeparator == 'other') {
|
||||
$sSeparator = utils::ReadParam('other_separator', ',', false, 'raw_data');
|
||||
}
|
||||
$sTextQualifier = utils::ReadParam('text_qualifier', '"', false, 'raw_data');
|
||||
if ($sTextQualifier == 'other')
|
||||
{
|
||||
if ($sTextQualifier == 'other') {
|
||||
$sTextQualifier = utils::ReadParam('other_qualifier', '"', false, 'raw_data');
|
||||
}
|
||||
$bHeaderLine = (utils::ReadParam('header_line', '0') == 1);
|
||||
@@ -333,7 +349,7 @@ try {
|
||||
$oClassesSelect = SelectUIBlockFactory::MakeForSelect("class_name", "select_class_name");
|
||||
$oDefaultSelect = SelectOptionUIBlockFactory::MakeForSelectOption("$sClassName", MetaModel::GetName($sClassName), true);
|
||||
$oClassesSelect->AddSubBlock($oDefaultSelect);
|
||||
$aSynchroUpdate = utils::ReadParam('synchro_update', array());
|
||||
$aSynchroUpdate = utils::ReadParam('synchro_update', []);
|
||||
} else {
|
||||
$oClassesSelect = GetClassesSelectUIBlock('class_name', $sClassName, UR_ACTION_BULK_MODIFY, (bool)$bAdvanced);
|
||||
}
|
||||
@@ -381,7 +397,7 @@ try {
|
||||
$oForm->AddSubBlock(InputUIBlockFactory::MakeForHidden("synchro_scope", $sSynchroScope));
|
||||
$oForm->AddSubBlock(InputUIBlockFactory::MakeForHidden("date_time_format", $sDateTimeFormat));
|
||||
$oForm->AddSubBlock(InputUIBlockFactory::MakeForHidden("custom_date_time_format", $sCustomDateTimeFormat));
|
||||
$oForm->AddSubBlock(InputUIBlockFactory::MakeForHidden("transaction_id", utils::GetNewTransactionId(), "transaction_id")); // adding transaction_id field for next step (simulation)
|
||||
$oForm->AddSubBlock(InputUIBlockFactory::MakeForHidden("transaction_id", utils::GetNewTransactionId(), "transaction_id")); // adding transaction_id field for next step (simulation)
|
||||
|
||||
if (!empty($sSynchroScope)) {
|
||||
foreach ($aSynchroUpdate as $sKey => $value) {
|
||||
@@ -403,10 +419,9 @@ try {
|
||||
$('#advanced').on('click', function(ev) { DoReload(); } );
|
||||
EOF
|
||||
);
|
||||
if ($sClassName != '')
|
||||
{
|
||||
$aFieldsMapping = utils::ReadParam('field', array(), false, 'raw_data');
|
||||
$aSearchFields = utils::ReadParam('search_field', array(), false, 'field_name');
|
||||
if ($sClassName != '') {
|
||||
$aFieldsMapping = utils::ReadParam('field', [], false, 'raw_data');
|
||||
$aSearchFields = utils::ReadParam('search_field', [], false, 'field_name');
|
||||
$sFieldsMapping = addslashes(json_encode($aFieldsMapping));
|
||||
$sSearchFields = addslashes(json_encode($aSearchFields));
|
||||
|
||||
@@ -414,7 +429,7 @@ EOF
|
||||
}
|
||||
|
||||
$oPage->add_script(
|
||||
<<<EOF
|
||||
<<<EOF
|
||||
var aDefaultKeys = new Array();
|
||||
var aReadOnlyKeys = new Array();
|
||||
|
||||
@@ -633,7 +648,7 @@ EOF
|
||||
}
|
||||
}
|
||||
EOF
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -645,35 +660,29 @@ EOF
|
||||
{
|
||||
$sOperation = utils::ReadParam('operation', 'csv_data');
|
||||
$sCSVData = '';
|
||||
switch($sOperation)
|
||||
{
|
||||
switch ($sOperation) {
|
||||
case 'file_upload':
|
||||
$oDocument = utils::ReadPostedDocument('csvdata');
|
||||
if (!$oDocument->IsEmpty())
|
||||
{
|
||||
$sCSVData = $oDocument->GetData();
|
||||
}
|
||||
break;
|
||||
$oDocument = utils::ReadPostedDocument('csvdata');
|
||||
if (!$oDocument->IsEmpty()) {
|
||||
$sCSVData = $oDocument->GetData();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
$sCSVData = utils::ReadPostedParam('csvdata', '', 'raw_data');
|
||||
$sCSVData = utils::ReadPostedParam('csvdata', '', 'raw_data');
|
||||
}
|
||||
$sEncoding = utils::ReadParam('encoding', 'UTF-8');
|
||||
|
||||
// Compute a subset of the data set, now that we know the charset
|
||||
if ($sEncoding == 'UTF-8')
|
||||
{
|
||||
if ($sEncoding == 'UTF-8') {
|
||||
// Remove the BOM if any
|
||||
if (substr($sCSVData, 0, 3) == UTF8_BOM)
|
||||
{
|
||||
if (substr($sCSVData, 0, 3) == UTF8_BOM) {
|
||||
$sCSVData = substr($sCSVData, 3);
|
||||
}
|
||||
// Clean the input
|
||||
// Todo: warn the user if some characters are lost/substituted
|
||||
$sUTF8Data = iconv('UTF-8', 'UTF-8//IGNORE//TRANSLIT', $sCSVData);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$sUTF8Data = iconv($sEncoding, 'UTF-8//IGNORE//TRANSLIT', $sCSVData);
|
||||
}
|
||||
|
||||
@@ -682,16 +691,15 @@ EOF
|
||||
$iSkippedLines = utils::ReadParam('nb_skipped_lines', '');
|
||||
$bBoxSkipLines = utils::ReadParam('box_skiplines', 0);
|
||||
$sTextQualifier = utils::ReadParam('text_qualifier', '', false, 'raw_data');
|
||||
if ($sTextQualifier == '') // May be set to an empty value by the previous page
|
||||
{
|
||||
if ($sTextQualifier == '') { // May be set to an empty value by the previous page
|
||||
$sTextQualifier = $aGuesses['qualifier'];
|
||||
}
|
||||
$sOtherTextQualifier = in_array($sTextQualifier, array('"', "'")) ? '' : $sTextQualifier;
|
||||
$sOtherTextQualifier = in_array($sTextQualifier, ['"', "'"]) ? '' : $sTextQualifier;
|
||||
$bHeaderLine = utils::ReadParam('header_line', 0);
|
||||
$sClassName = utils::ReadParam('class_name', '', false, 'class');
|
||||
$bAdvanced = utils::ReadParam('advanced', 0);
|
||||
$aFieldsMapping = utils::ReadParam('field', array(), false, 'raw_data');
|
||||
$aSearchFields = utils::ReadParam('search_field', array(), false, 'field_name');
|
||||
$aFieldsMapping = utils::ReadParam('field', [], false, 'raw_data');
|
||||
$aSearchFields = utils::ReadParam('search_field', [], false, 'field_name');
|
||||
|
||||
// Create a truncated version of the data used for the fast preview
|
||||
// Take about 20 lines of data... knowing that some lines may contain carriage returns
|
||||
@@ -721,7 +729,7 @@ EOF
|
||||
$oSet = new DBObjectSet($oSearch);
|
||||
$iCount = $oSet->Count();
|
||||
DisplaySynchroBanner($oPage, $sClassName, $iCount);
|
||||
$aSynchroUpdate = utils::ReadParam('synchro_update', array());
|
||||
$aSynchroUpdate = utils::ReadParam('synchro_update', []);
|
||||
}
|
||||
$oPanel = TitleUIBlockFactory::MakeForPage(Dict::S('UI:Title:CSVImportStep2'));
|
||||
$oPage->AddSubBlock($oPanel);
|
||||
@@ -729,7 +737,6 @@ EOF
|
||||
$oForm = FormUIBlockFactory::MakeStandard('wizForm');
|
||||
$oPage->AddSubBlock($oForm);
|
||||
|
||||
|
||||
$oContainer = PanelUIBlockFactory::MakeNeutral('');
|
||||
$oForm->AddSubBlock($oContainer);
|
||||
|
||||
@@ -741,20 +748,19 @@ EOF
|
||||
$oFieldSetSeparator = FieldSetUIBlockFactory::MakeStandard(Dict::S('UI:CSVImport:SeparatorCharacter'));
|
||||
$oMulticolumn->AddColumn(ColumnUIBlockFactory::MakeForBlock($oFieldSetSeparator));
|
||||
|
||||
$aSep = array(
|
||||
$aSep = [
|
||||
';' => Dict::S('UI:CSVImport:SeparatorSemicolon+'),
|
||||
',' => Dict::S('UI:CSVImport:SeparatorComma+'),
|
||||
'tab' => Dict::S('UI:CSVImport:SeparatorTab+'),
|
||||
);
|
||||
];
|
||||
$sSeparator = utils::ReadParam('separator', '', false, 'raw_data');
|
||||
if ($sSeparator == '') // May be set to an empty value by the previous page
|
||||
{
|
||||
if ($sSeparator == '') { // May be set to an empty value by the previous page
|
||||
$sSeparator = $aGuesses['separator'];
|
||||
}
|
||||
if ($sSeparator == "\t") {
|
||||
$sSeparator = "tab";
|
||||
}
|
||||
$sOtherSeparator = in_array($sSeparator, array(',', ';', "\t")) ? '' : $sSeparator;
|
||||
$sOtherSeparator = in_array($sSeparator, [',', ';', "\t"]) ? '' : $sSeparator;
|
||||
$aSep['other'] = Dict::S('UI:CSVImport:SeparatorOther').' <input type="text" size="3" maxlength="1" name="other_separator" id="other_separator" value="'.utils::EscapeHtml($sOtherSeparator).'" onChange="DoPreview()"/>';
|
||||
|
||||
foreach ($aSep as $sVal => $sLabel) {
|
||||
@@ -772,10 +778,10 @@ EOF
|
||||
$oFieldSetTextQualifier = FieldSetUIBlockFactory::MakeStandard(Dict::S('UI:CSVImport:TextQualifierCharacter'));
|
||||
$oMulticolumn->AddColumn(ColumnUIBlockFactory::MakeForBlock($oFieldSetTextQualifier));
|
||||
|
||||
$aQualifiers = array(
|
||||
$aQualifiers = [
|
||||
'"' => Dict::S('UI:CSVImport:QualifierDoubleQuote+'),
|
||||
'\'' => Dict::S('UI:CSVImport:QualifierSimpleQuote+'),
|
||||
);
|
||||
];
|
||||
$aQualifiers['other'] = Dict::S('UI:CSVImport:QualifierOther').' <input type="text" size="3" maxlength="1" name="other_qualifier" value="'.utils::EscapeHtml($sOtherTextQualifier).'" onChange="DoPreview()/>';
|
||||
foreach ($aQualifiers as $sVal => $sLabel) {
|
||||
$oRadio = InputUIBlockFactory::MakeForInputWithLabel($sLabel, "text_qualifier", $sVal, $sLabel, "radio");
|
||||
@@ -798,8 +804,13 @@ EOF
|
||||
$oFieldSetCommentsAndHeader->AddSubBlock($oCheckBoxHeader);
|
||||
$oFieldSetCommentsAndHeader->AddSubBlock(new Html('</br>'));
|
||||
|
||||
$oCheckBoxSkip = InputUIBlockFactory::MakeForInputWithLabel(Dict::Format('UI:CSVImport:Skip_N_LinesAtTheBeginning', '<input type="text" size=2 name="nb_skipped_lines" id="nb_skipped_lines" onChange="DoPreview()" value="'.$iSkippedLines.'">'), "box_skiplines", "1", "box_skiplines",
|
||||
"checkbox");
|
||||
$oCheckBoxSkip = InputUIBlockFactory::MakeForInputWithLabel(
|
||||
Dict::Format('UI:CSVImport:Skip_N_LinesAtTheBeginning', '<input type="text" size=2 name="nb_skipped_lines" id="nb_skipped_lines" onChange="DoPreview()" value="'.$iSkippedLines.'">'),
|
||||
"box_skiplines",
|
||||
"1",
|
||||
"box_skiplines",
|
||||
"checkbox"
|
||||
);
|
||||
$oCheckBoxSkip->GetInput()->AddCSSClass('ibo-input-checkbox');
|
||||
$oCheckBoxSkip->GetInput()->SetIsChecked(($bBoxSkipLines == 1));
|
||||
$oCheckBoxSkip->SetBeforeInput(false);
|
||||
@@ -922,9 +933,9 @@ EOF
|
||||
);
|
||||
}
|
||||
EOF
|
||||
);
|
||||
);
|
||||
$oPage->add_ready_script(
|
||||
<<<EOF
|
||||
<<<EOF
|
||||
DoPreview();
|
||||
$('#custom_date_time_format').on('click', function() { $('#radio_date_time_custom').prop('checked', true); });
|
||||
EOF
|
||||
@@ -945,7 +956,7 @@ EOF
|
||||
$oSet = new DBObjectSet($oSearch);
|
||||
$iCount = $oSet->Count();
|
||||
DisplaySynchroBanner($oPage, $sClassName, $iCount);
|
||||
$aSynchroUpdate = utils::ReadParam('synchro_update', array());
|
||||
$aSynchroUpdate = utils::ReadParam('synchro_update', []);
|
||||
} else {
|
||||
$aSynchroUpdate = null;
|
||||
}
|
||||
@@ -980,8 +991,8 @@ EOF
|
||||
if ($sEncoding == '') {
|
||||
$sEncoding = MetaModel::GetConfig()->Get('csv_file_default_charset');
|
||||
}
|
||||
$aFieldsMapping = utils::ReadParam('field', array(), false, 'raw_data');
|
||||
$aSearchFields = utils::ReadParam('search_field', array(), false, 'field_name');
|
||||
$aFieldsMapping = utils::ReadParam('field', [], false, 'raw_data');
|
||||
$aSearchFields = utils::ReadParam('search_field', [], false, 'field_name');
|
||||
$aPossibleEncodings = utils::GetPossibleEncodings(MetaModel::GetConfig()->GetCSVImportCharsets());
|
||||
|
||||
foreach ($aPossibleEncodings as $sIconvCode => $sDisplayName) {
|
||||
@@ -1016,7 +1027,6 @@ EOF
|
||||
$oFormPaste = FormUIBlockFactory::MakeStandard();
|
||||
$oTabPaste->AddSubBlock($oFormPaste);
|
||||
|
||||
|
||||
$sCSVData = utils::ReadParam('csvdata', '', false, utils::ENUM_SANITIZATION_FILTER_STRING);
|
||||
$oTextarea = new TextArea('csvdata', $sCSVData, '', 120, 30);
|
||||
$oTextarea->AddCSSClasses(['ibo-input-text', 'ibo-is-code']);
|
||||
@@ -1086,25 +1096,28 @@ ajax_request = $.post(GetAbsoluteUrlAppRoot()+'pages/ajax.csvimport.php',
|
||||
);
|
||||
}
|
||||
EOF
|
||||
);
|
||||
);
|
||||
$oPage->add_ready_script(
|
||||
<<<EOF
|
||||
<<<EOF
|
||||
$('#select_template_class').change( function() {
|
||||
DisplayTemplate(this.value);
|
||||
});
|
||||
EOF
|
||||
);
|
||||
);
|
||||
|
||||
if (Utils::GetConfig()->Get('csv_import_history_display'))
|
||||
{
|
||||
if (Utils::GetConfig()->Get('csv_import_history_display')) {
|
||||
$oPage->SetCurrentTabContainer('tabs1');
|
||||
$oPage->AddAjaxTab('UI:History:BulkImports', utils::GetAbsoluteUrlAppRoot().'pages/csvimport.php?step=11', true /* bCache */,
|
||||
null, AjaxTab::ENUM_TAB_PLACEHOLDER_MISC);
|
||||
$oPage->AddAjaxTab(
|
||||
'UI:History:BulkImports',
|
||||
utils::GetAbsoluteUrlAppRoot().'pages/csvimport.php?step=11',
|
||||
true /* bCache */,
|
||||
null,
|
||||
AjaxTab::ENUM_TAB_PLACEHOLDER_MISC
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
switch($iStep)
|
||||
{
|
||||
switch ($iStep) {
|
||||
case 11:
|
||||
// Asynchronous tab
|
||||
$oPage = new AjaxPage('');
|
||||
@@ -1142,19 +1155,15 @@ EOF
|
||||
}
|
||||
|
||||
$oPage->output();
|
||||
}
|
||||
catch(CoreException $e)
|
||||
{
|
||||
} catch (CoreException $e) {
|
||||
require_once(APPROOT.'/setup/setuppage.class.inc.php');
|
||||
$oP = new ErrorPage(Dict::S('UI:PageTitle:FatalError'));
|
||||
$oP->add("<h1>".Dict::S('UI:FatalErrorMessage')."</h1>\n");
|
||||
$oP->error(Dict::Format('UI:Error_Details', $e->getHtmlDesc()));
|
||||
$oP->output();
|
||||
|
||||
if (MetaModel::IsLogEnabledIssue())
|
||||
{
|
||||
if (MetaModel::IsValidClass('EventIssue'))
|
||||
{
|
||||
if (MetaModel::IsLogEnabledIssue()) {
|
||||
if (MetaModel::IsValidClass('EventIssue')) {
|
||||
$oLog = new EventIssue();
|
||||
|
||||
$oLog->Set('message', $e->getMessage());
|
||||
@@ -1171,19 +1180,15 @@ catch(CoreException $e)
|
||||
|
||||
// For debugging only
|
||||
//throw $e;
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
} catch (Exception $e) {
|
||||
require_once(APPROOT.'/setup/setuppage.class.inc.php');
|
||||
$oP = new ErrorPage(Dict::S('UI:PageTitle:FatalError'));
|
||||
$oP->add("<h1>".Dict::S('UI:FatalErrorMessage')."</h1>\n");
|
||||
$oP->error(Dict::Format('UI:Error_Details', $e->getMessage()));
|
||||
$oP->output();
|
||||
|
||||
if (MetaModel::IsLogEnabledIssue())
|
||||
{
|
||||
if (MetaModel::IsValidClass('EventIssue'))
|
||||
{
|
||||
if (MetaModel::IsLogEnabledIssue()) {
|
||||
if (MetaModel::IsValidClass('EventIssue')) {
|
||||
$oLog = new EventIssue();
|
||||
|
||||
$oLog->Set('message', $e->getMessage());
|
||||
@@ -1191,7 +1196,7 @@ catch(Exception $e)
|
||||
$oLog->Set('issue', 'PHP Exception');
|
||||
$oLog->Set('impact', 'Page could not be displayed');
|
||||
$oLog->Set('callstack', $e->getTrace());
|
||||
$oLog->Set('data', array());
|
||||
$oLog->Set('data', []);
|
||||
$oLog->DBInsertNoReload();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
@@ -28,7 +29,6 @@ IssueLog::Trace('----- Request: '.utils::GetRequestUri(), LogChannels::WEB_REQUE
|
||||
|
||||
utils::InitTimeZone();
|
||||
|
||||
|
||||
/**
|
||||
* @param string $sPagePath full path (if symlink, it will be resolved)
|
||||
* @param array $aPossibleBasePaths list of possible base paths
|
||||
@@ -51,7 +51,6 @@ function CheckPageExists(string $sPagePath, array $aPossibleBasePaths)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
$sModule = utils::ReadParam('exec_module', '');
|
||||
if ($sModule == '') {
|
||||
echo "Missing argument 'exec_module'";
|
||||
@@ -70,7 +69,6 @@ $sEnvironment = utils::ReadParam('exec_env', utils::GetCurrentEnvironment());
|
||||
Session::WriteClose();
|
||||
$oKPI->ComputeAndReport("Session Start");
|
||||
|
||||
|
||||
$sEnvFullPath = APPROOT.'env-'.$sEnvironment;
|
||||
$sPageRelativePath = $sModule.'/'.$sPage;
|
||||
$sPageEnvFullPath = $sEnvFullPath.'/'.$sPageRelativePath;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
@@ -41,17 +42,14 @@ function GraphvizEscape($s)
|
||||
/**
|
||||
* Helper to generate a Graphviz code for displaying the life cycle of a class
|
||||
* @param string $sClass The class to display
|
||||
* @return string The Graph description in Graphviz/Dot syntax
|
||||
* @return string The Graph description in Graphviz/Dot syntax
|
||||
*/
|
||||
function GraphvizLifecycle($sClass)
|
||||
{
|
||||
$sDotFileContent = "";
|
||||
if (!MetaModel::HasLifecycle($sClass))
|
||||
{
|
||||
if (!MetaModel::HasLifecycle($sClass)) {
|
||||
//$oPage->p("no lifecycle for this class");
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$aStates = MetaModel::EnumStates($sClass);
|
||||
$aStimuli = MetaModel::EnumStimuli($sClass);
|
||||
$sDotFileContent .= "digraph finite_state_machine {
|
||||
@@ -60,18 +58,15 @@ function GraphvizLifecycle($sClass)
|
||||
node [ fontname=Verdana style=filled fillcolor=\"#ffffff\" ];
|
||||
edge [ fontname=Verdana ];
|
||||
";
|
||||
$aStatesLinks = array();
|
||||
foreach ($aStates as $sStateCode => $aStateDef)
|
||||
{
|
||||
$aStatesLinks[$sStateCode] = array('in' => 0, 'out' => 0);
|
||||
$aStatesLinks = [];
|
||||
foreach ($aStates as $sStateCode => $aStateDef) {
|
||||
$aStatesLinks[$sStateCode] = ['in' => 0, 'out' => 0];
|
||||
}
|
||||
|
||||
foreach ($aStates as $sStateCode => $aStateDef)
|
||||
{
|
||||
|
||||
foreach ($aStates as $sStateCode => $aStateDef) {
|
||||
$sStateLabel = MetaModel::GetStateLabel($sClass, $sStateCode);
|
||||
$sStateDescription = MetaModel::GetStateDescription($sClass, $sStateCode);
|
||||
foreach(MetaModel::EnumTransitions($sClass, $sStateCode) as $sStimulusCode => $aTransitionDef)
|
||||
{
|
||||
foreach (MetaModel::EnumTransitions($sClass, $sStateCode) as $sStimulusCode => $aTransitionDef) {
|
||||
$aStatesLinks[$sStateCode]['out']++;
|
||||
$aStatesLinks[$aTransitionDef['target_state']]['in']++;
|
||||
$sStimulusLabel = $aStimuli[$sStimulusCode]->GetLabel();
|
||||
@@ -79,19 +74,14 @@ function GraphvizLifecycle($sClass)
|
||||
$sDotFileContent .= "\t$sStateCode -> {$aTransitionDef['target_state']} [ label=\"".GraphvizEscape($sStimulusLabel)."\"];\n";
|
||||
}
|
||||
}
|
||||
foreach($aStates as $sStateCode => $aStateDef)
|
||||
{
|
||||
if (($aStatesLinks[$sStateCode]['out'] > 0) || ($aStatesLinks[$sStateCode]['in'] > 0))
|
||||
{
|
||||
foreach ($aStates as $sStateCode => $aStateDef) {
|
||||
if (($aStatesLinks[$sStateCode]['out'] > 0) || ($aStatesLinks[$sStateCode]['in'] > 0)) {
|
||||
// Show only reachable states
|
||||
$sStateLabel = str_replace(' ', '\n', MetaModel::GetStateLabel($sClass, $sStateCode));
|
||||
if ( ($aStatesLinks[$sStateCode]['in'] == 0) || ($aStatesLinks[$sStateCode]['out'] == 0))
|
||||
{
|
||||
if (($aStatesLinks[$sStateCode]['in'] == 0) || ($aStatesLinks[$sStateCode]['out'] == 0)) {
|
||||
// End or Start state, make it look different
|
||||
$sDotFileContent .= "\t$sStateCode [ shape=doublecircle,label=\"".GraphvizEscape($sStateLabel)."\"];\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$sDotFileContent .= "\t$sStateCode [ shape=circle,label=\"".GraphvizEscape($sStateLabel)."\"];\n";
|
||||
}
|
||||
}
|
||||
@@ -108,39 +98,33 @@ $sModuleDir = dirname($sDeclarationFile);
|
||||
|
||||
$sImageFilePath = $sModuleDir."/lifecycle/".$sClass.".png";
|
||||
$sDotExecutable = MetaModel::GetConfig()->Get('graphviz_path');
|
||||
if (file_exists($sDotExecutable))
|
||||
{
|
||||
if (file_exists($sDotExecutable)) {
|
||||
// create the file with Graphviz
|
||||
$sImageFilePath = APPROOT."data/lifecycle/".$sClass.".svg";
|
||||
if (!is_dir(APPROOT."data"))
|
||||
{
|
||||
if (!is_dir(APPROOT."data")) {
|
||||
@mkdir(APPROOT."data");
|
||||
}
|
||||
if (!is_dir(APPROOT."data/lifecycle"))
|
||||
{
|
||||
if (!is_dir(APPROOT."data/lifecycle")) {
|
||||
@mkdir(APPROOT."data/lifecycle");
|
||||
}
|
||||
$sDotDescription = GraphvizLifecycle($sClass);
|
||||
$sDotFilePath = APPROOT."data/lifecycle/{$sClass}.dot";
|
||||
|
||||
|
||||
$rFile = @fopen($sDotFilePath, "w");
|
||||
@fwrite($rFile, $sDotDescription);
|
||||
@fclose($rFile);
|
||||
$aOutput = array();
|
||||
$aOutput = [];
|
||||
$CommandLine = "\"$sDotExecutable\" -v -Tsvg < \"$sDotFilePath\" -o \"$sImageFilePath\" 2>&1";
|
||||
|
||||
|
||||
exec($CommandLine, $aOutput, $iRetCode);
|
||||
if ($iRetCode != 0)
|
||||
{
|
||||
if ($iRetCode != 0) {
|
||||
header('Content-type: text/html');
|
||||
echo "<p><b>Error:</b></p>";
|
||||
echo "<p>The command: <pre>$CommandLine</pre> returned $iRetCode</p>";
|
||||
echo "<p>The output of the command is:<pre>\n".implode("\n", $aOutput)."</pre></p>";
|
||||
echo "<hr>";
|
||||
echo "<p>Content of the '".basename($sDotFilePath)."' file:<pre>\n$sDotDescription</pre>";
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
header('Content-type: image/svg+xml');
|
||||
header('Content-Disposition: inline; filename="'.$sClass.'.svg"');
|
||||
readfile($sImageFilePath);
|
||||
@@ -148,9 +132,7 @@ if (file_exists($sDotExecutable))
|
||||
@unlink($sDotFilePath);
|
||||
// Image file is removed as well as there is no cache system yet
|
||||
@unlink($sImageFilePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
header('Content-type: image/png');
|
||||
header('Content-Disposition: inline; filename="'.$sClass.'.png"');
|
||||
readfile($sImageFilePath);
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<?php
|
||||
|
||||
header('Location: ../index.php');
|
||||
?>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
@@ -33,8 +34,7 @@ require_once(APPROOT.'/application/loginwebpage.class.inc.php');
|
||||
$bPortal = utils::ReadParam('portal', false);
|
||||
$sUrl = utils::GetAbsoluteUrlAppRoot();
|
||||
|
||||
if ($operation == 'do_logoff')
|
||||
{
|
||||
if ($operation == 'do_logoff') {
|
||||
// Reload the same dummy page to let the "calling" page execute its 'onunload' method before performing the actual logoff.
|
||||
// Note the redirection MUST NOT be made via an HTTP "header" since onunload is called only when the actual content of the DOM
|
||||
// is replaced by some other content. So the "bouncing" page must provide some content (in our case a script making the redirection).
|
||||
@@ -44,8 +44,7 @@ if ($operation == 'do_logoff')
|
||||
exit;
|
||||
}
|
||||
|
||||
if (Session::IsSet('auth_user'))
|
||||
{
|
||||
if (Session::IsSet('auth_user')) {
|
||||
$sAuthUser = Session::Get('auth_user');
|
||||
UserRights::Login($sAuthUser); // Set the user's language
|
||||
}
|
||||
@@ -53,15 +52,11 @@ if (Session::IsSet('auth_user'))
|
||||
LoginWebPage::ResetSession();
|
||||
|
||||
$bLoginDebug = MetaModel::GetConfig()->Get('login_debug');
|
||||
if ($bLoginDebug)
|
||||
{
|
||||
if ($bLoginDebug) {
|
||||
IssueLog::Info("---------------------------------");
|
||||
if (isset($sAuthUser))
|
||||
{
|
||||
if (isset($sAuthUser)) {
|
||||
IssueLog::Info("--> Logout user: [$sAuthUser]");
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
IssueLog::Info("--> Logout");
|
||||
}
|
||||
$sSessionLog = session_id().' '.utils::GetSessionLog();
|
||||
@@ -71,13 +66,10 @@ if ($bLoginDebug)
|
||||
$aPluginList = LoginWebPage::GetLoginPluginList('iLogoutExtension');
|
||||
|
||||
/** @var iLogoutExtension $oLogoutExtension */
|
||||
foreach ($aPluginList as $oLogoutExtension)
|
||||
{
|
||||
if ($bLoginDebug)
|
||||
{
|
||||
foreach ($aPluginList as $oLogoutExtension) {
|
||||
if ($bLoginDebug) {
|
||||
$sCurrSessionLog = session_id().' '.utils::GetSessionLog();
|
||||
if ($sCurrSessionLog != $sSessionLog)
|
||||
{
|
||||
if ($sCurrSessionLog != $sSessionLog) {
|
||||
$sSessionLog = $sCurrSessionLog;
|
||||
IssueLog::Info("SESSION: $sSessionLog");
|
||||
}
|
||||
@@ -87,11 +79,9 @@ foreach ($aPluginList as $oLogoutExtension)
|
||||
$oLogoutExtension->LogoutAction();
|
||||
}
|
||||
|
||||
if ($bLoginDebug)
|
||||
{
|
||||
if ($bLoginDebug) {
|
||||
$sCurrSessionLog = session_id().' '.utils::GetSessionLog();
|
||||
if ($sCurrSessionLog != $sSessionLog)
|
||||
{
|
||||
if ($sCurrSessionLog != $sSessionLog) {
|
||||
$sSessionLog = $sCurrSessionLog;
|
||||
IssueLog::Info("SESSION: $sSessionLog");
|
||||
}
|
||||
@@ -100,8 +90,8 @@ if ($bLoginDebug)
|
||||
|
||||
LoginWebPage::ResetSession(true);
|
||||
if ($bLoginDebug) {
|
||||
$sSessionLog = session_id().' '.utils::GetSessionLog();
|
||||
IssueLog::Info("SESSION: $sSessionLog");
|
||||
$sSessionLog = session_id().' '.utils::GetSessionLog();
|
||||
IssueLog::Info("SESSION: $sSessionLog");
|
||||
}
|
||||
|
||||
$oPage = LoginWebPage::NewLoginWebPage();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
@@ -17,7 +18,6 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
|
||||
use Combodo\iTop\Application\UI\Base\Component\CollapsibleSection\CollapsibleSection;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Html\HtmlFactory;
|
||||
use Combodo\iTop\Application\UI\Base\Layout\PageContent\PageContentFactory;
|
||||
@@ -49,8 +49,8 @@ function DisplayActionsTab(iTopWebPage &$oP, string $sClassToDisplay, array $aCl
|
||||
return;
|
||||
}
|
||||
|
||||
$aActionClasses = array();
|
||||
foreach(MetaModel::EnumChildClasses($sClassToDisplay, ENUM_CHILD_CLASSES_ALL, true) as $sActionClass) {
|
||||
$aActionClasses = [];
|
||||
foreach (MetaModel::EnumChildClasses($sClassToDisplay, ENUM_CHILD_CLASSES_ALL, true) as $sActionClass) {
|
||||
// Ignore abstract classes
|
||||
if (MetaModel::IsAbstract($sActionClass)) {
|
||||
continue;
|
||||
@@ -74,12 +74,11 @@ function DisplayActionsTab(iTopWebPage &$oP, string $sClassToDisplay, array $aCl
|
||||
$oP->SetCurrentTab('UI:NotificationsMenu:Actions:'.$sClassToDisplay);
|
||||
|
||||
$iBlock = 0;
|
||||
foreach($aActionClasses as $sActionClass)
|
||||
{
|
||||
foreach ($aActionClasses as $sActionClass) {
|
||||
$oFilter = new DBObjectSearch($sActionClass);
|
||||
$oFilter->AddCondition('finalclass', $sActionClass); // derived classes will be further processed
|
||||
|
||||
$aParams = array('panel_title' => MetaModel::GetName($sActionClass));
|
||||
$aParams = ['panel_title' => MetaModel::GetName($sActionClass)];
|
||||
|
||||
$sBlockId = 'block_'.utils::Sanitize($sClassToDisplay, '', utils::ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER).'_'.$iBlock;
|
||||
$oBlock = new DisplayBlock($oFilter, 'list', false, $aParams);
|
||||
@@ -91,8 +90,14 @@ function DisplayActionsTab(iTopWebPage &$oP, string $sClassToDisplay, array $aCl
|
||||
// Main program
|
||||
//
|
||||
$oP = new iTopWebPage(Dict::S('Menu:NotificationsMenu+'));
|
||||
$oP->SetBreadCrumbEntry('ui-tool-notifications', Dict::S('Menu:NotificationsMenu'), Dict::S('Menu:NotificationsMenu+'), '', 'fas fa-bell',
|
||||
iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES);
|
||||
$oP->SetBreadCrumbEntry(
|
||||
'ui-tool-notifications',
|
||||
Dict::S('Menu:NotificationsMenu'),
|
||||
Dict::S('Menu:NotificationsMenu+'),
|
||||
'',
|
||||
'fas fa-bell',
|
||||
iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES
|
||||
);
|
||||
|
||||
$oPageContentLayout = PageContentFactory::MakeStandardEmpty();
|
||||
$oP->SetContentLayout($oPageContentLayout);
|
||||
@@ -115,7 +120,7 @@ $oP->SetCurrentTabContainer('Tabs_0');
|
||||
$oP->SetCurrentTab('UI:NotificationsMenu:Triggers');
|
||||
|
||||
$oFilter = new DBObjectSearch('Trigger');
|
||||
$aParams = array('panel_title' => Dict::S('UI:NotificationsMenu:AvailableTriggers'));
|
||||
$aParams = ['panel_title' => Dict::S('UI:NotificationsMenu:AvailableTriggers')];
|
||||
$oBlock = new DisplayBlock($oFilter, 'list', false, $aParams);
|
||||
$oBlock->Display($oP, 'block_0', $aParams);
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<?php
|
||||
|
||||
|
||||
use Combodo\iTop\Controller\OAuth\OAuthLandingController;
|
||||
|
||||
require_once('../approot.inc.php');
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -143,19 +144,18 @@ JS
|
||||
// Notifications
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
$oNotificationsBlock = new Panel(Dict::S('UI:Preferences:Notifications'), array(), Panel::ENUM_COLOR_SCHEME_GREY, 'ibo-notifications');
|
||||
$oNotificationsBlock = new Panel(Dict::S('UI:Preferences:Notifications'), [], Panel::ENUM_COLOR_SCHEME_GREY, 'ibo-notifications');
|
||||
$sNotificationsCenterUrl = Router::GetInstance()->GenerateUrl(NotificationsCenterController::ROUTE_NAMESPACE.'.display_page', [], true);
|
||||
$oNotificationsBlock->AddSubBlock(new Html('<p>'.Dict::Format('UI:Preferences:Notifications+', $sNotificationsCenterUrl).'</p>'));
|
||||
$oContentLayout->AddMainBlock($oNotificationsBlock);
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Favorite Organizations
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
$oFavoriteOrganizationsBlock = new Panel(Dict::S('UI:FavoriteOrganizations'), array(), 'grey', 'ibo-favorite-organizations');
|
||||
$oFavoriteOrganizationsBlock = new Panel(Dict::S('UI:FavoriteOrganizations'), [], 'grey', 'ibo-favorite-organizations');
|
||||
$oFavoriteOrganizationsBlock->SetSubTitle(Dict::S('UI:FavoriteOrganizations+'));
|
||||
$oFavoriteOrganizationsBlock->AddCSSClass('ibo-datatable-panel');
|
||||
$oFavoriteOrganizationsForm = new Form();
|
||||
@@ -210,7 +210,7 @@ JS
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
$oShortcutsBlock = new BlockShortcuts(Dict::S('Menu:MyShortcuts'), array(), 'grey', 'ibo-shortcuts');
|
||||
$oShortcutsBlock = new BlockShortcuts(Dict::S('Menu:MyShortcuts'), [], 'grey', 'ibo-shortcuts');
|
||||
$oShortcutsBlock->AddCSSClass('ibo-datatable-panel');
|
||||
|
||||
$oShortcutsBlock->sIdShortcuts = 'shortcut_list';
|
||||
@@ -234,12 +234,22 @@ JS
|
||||
$oShortcutsToolBar = ToolbarUIBlockFactory::MakeForButton();
|
||||
$oShortcutsBlock->AddSubBlock($oShortcutsToolBar);
|
||||
// - Rename button
|
||||
$oShortcutsRenameButton = ButtonUIBlockFactory::MakeForSecondaryAction(Dict::S('UI:Button:Rename'), null, null, false,
|
||||
"shortcut_btn_rename");
|
||||
$oShortcutsRenameButton = ButtonUIBlockFactory::MakeForSecondaryAction(
|
||||
Dict::S('UI:Button:Rename'),
|
||||
null,
|
||||
null,
|
||||
false,
|
||||
"shortcut_btn_rename"
|
||||
);
|
||||
$oShortcutsToolBar->AddSubBlock($oShortcutsRenameButton);
|
||||
// - Delete button
|
||||
$oShortcutsDeleteButton = ButtonUIBlockFactory::MakeForSecondaryAction(Dict::S('UI:Button:Delete'), null, null, false,
|
||||
"shortcut_btn_delete");
|
||||
$oShortcutsDeleteButton = ButtonUIBlockFactory::MakeForSecondaryAction(
|
||||
Dict::S('UI:Button:Delete'),
|
||||
null,
|
||||
null,
|
||||
false,
|
||||
"shortcut_btn_delete"
|
||||
);
|
||||
$oShortcutsToolBar->AddSubBlock($oShortcutsDeleteButton);
|
||||
}
|
||||
$oContentLayout->AddMainBlock($oShortcutsBlock);
|
||||
@@ -253,26 +263,27 @@ JS
|
||||
$oUser = UserRights::GetUserObject();
|
||||
/** @var iNewsroomProvider[] $aProviders */
|
||||
$aProviders = InterfaceDiscovery::GetInstance()->FindItopClasses(iNewsroomProvider::class);
|
||||
foreach($aProviders as $cProvider)
|
||||
{
|
||||
foreach ($aProviders as $cProvider) {
|
||||
$oProvider = new $cProvider();
|
||||
if ($oProvider->IsApplicable($oUser))
|
||||
{
|
||||
if ($oProvider->IsApplicable($oUser)) {
|
||||
$iCountProviders++;
|
||||
}
|
||||
}
|
||||
|
||||
$bNewsroomEnabled = (MetaModel::GetConfig()->Get('newsroom_enabled') !== false);
|
||||
if ($bNewsroomEnabled && ($iCountProviders > 0))
|
||||
{
|
||||
$oNewsroomBlock = new Panel(Dict::S('UI:Newsroom:Preferences'), array(), 'grey', 'ibo-newsroom');
|
||||
if ($bNewsroomEnabled && ($iCountProviders > 0)) {
|
||||
$oNewsroomBlock = new Panel(Dict::S('UI:Newsroom:Preferences'), [], 'grey', 'ibo-newsroom');
|
||||
|
||||
$sNewsroomHtml = '';
|
||||
$sNewsroomHtml .= '<form method="post">';
|
||||
$iNewsroomDisplaySize = (int)appUserPreferences::GetPref('newsroom_display_size', 7);
|
||||
|
||||
if ($iNewsroomDisplaySize < 1) $iNewsroomDisplaySize = 1;
|
||||
if ($iNewsroomDisplaySize > 20) $iNewsroomDisplaySize = 20;
|
||||
if ($iNewsroomDisplaySize < 1) {
|
||||
$iNewsroomDisplaySize = 1;
|
||||
}
|
||||
if ($iNewsroomDisplaySize > 20) {
|
||||
$iNewsroomDisplaySize = 20;
|
||||
}
|
||||
$sInput = '<input min="1" max="20" id="newsroom_display_size" type="number" size="2" name="newsroom_display_size" value="'.$iNewsroomDisplaySize.'">';
|
||||
$sIcon = '<i id="newsroom_menu_icon" class="top-right-icon icon-additional-arrow fas fa-bell" style="top: 0;"></i>';
|
||||
$sNewsroomHtml .= Dict::Format('UI:Newsroom:DisplayAtMost_X_Messages', $sInput, $sIcon);
|
||||
@@ -281,22 +292,16 @@ JS
|
||||
* @var iNewsroomProvider[] $aProviders
|
||||
*/
|
||||
$sAppRootUrl = utils::GetAbsoluteUrlAppRoot();
|
||||
foreach($aProviders as $cProvider)
|
||||
{
|
||||
foreach ($aProviders as $cProvider) {
|
||||
$oProvider = new $cProvider();
|
||||
if ($oProvider->IsApplicable($oUser))
|
||||
{
|
||||
if ($oProvider->IsApplicable($oUser)) {
|
||||
$sUrl = $oProvider->GetPreferencesUrl();
|
||||
$sProviderClass = get_class($oProvider);
|
||||
$sPreferencesLink = '';
|
||||
if ($sUrl !== null)
|
||||
{
|
||||
if(substr($sUrl, 0, strlen($sAppRootUrl)) === $sAppRootUrl)
|
||||
{
|
||||
if ($sUrl !== null) {
|
||||
if (substr($sUrl, 0, strlen($sAppRootUrl)) === $sAppRootUrl) {
|
||||
$sTarget = ''; // Internal link, open in the same window
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$sTarget = ' target="_blank"'; // External link, open in new window
|
||||
}
|
||||
$sPreferencesLink = ' - <a class=".newsroom-configuration-link" href="'.$sUrl.'"'.$sTarget.'>'.Dict::S('UI:Newsroom:ConfigurationLink').'</a>';
|
||||
@@ -306,8 +311,10 @@ JS
|
||||
// Forbid disabling internal newsroom provider
|
||||
$sDisabledForHtml = $sProviderClass === iTopNewsroomProvider::class ? 'disabled' : '';
|
||||
|
||||
$sNewsroomHtml .= '<div><input type="checkbox" id="newsroom_provider_'.$sProviderClass.'" value="on" '.$sCheckedForHtml.' '.$sDisabledForHtml.' name="newsroom_provider_'.$sProviderClass.'"><label for="newsroom_provider_'.$sProviderClass.'">'.Dict::Format('UI:Newsroom:DisplayMessagesFor_Provider',
|
||||
$oProvider->GetLabel()).'</label> '.$sPreferencesLink.'</div>';
|
||||
$sNewsroomHtml .= '<div><input type="checkbox" id="newsroom_provider_'.$sProviderClass.'" value="on" '.$sCheckedForHtml.' '.$sDisabledForHtml.' name="newsroom_provider_'.$sProviderClass.'"><label for="newsroom_provider_'.$sProviderClass.'">'.Dict::Format(
|
||||
'UI:Newsroom:DisplayMessagesFor_Provider',
|
||||
$oProvider->GetLabel()
|
||||
).'</label> '.$sPreferencesLink.'</div>';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -317,7 +324,8 @@ JS
|
||||
|
||||
// - Reset button
|
||||
$oNewsroomResetCacheButton = ButtonUIBlockFactory::MakeForAlternativeDestructiveAction(Dict::S('UI:Newsroom:ResetCache'));
|
||||
$oNewsroomResetCacheButton->SetOnClickJsCode(<<<JS
|
||||
$oNewsroomResetCacheButton->SetOnClickJsCode(
|
||||
<<<JS
|
||||
$('#ibo-navigation-menu--notifications-menu').newsroom_menu('clearCache')
|
||||
CombodoToast.OpenSuccessToast(Dict.S('UI:Newsroom:ResetCache:Success:Message'));
|
||||
JS
|
||||
@@ -328,11 +336,14 @@ JS
|
||||
$oNewsroomCancelButton->SetOnClickJsCode("window.location.href = '$sURL'");
|
||||
$oNewsroomToolbar->AddSubBlock($oNewsroomCancelButton);
|
||||
// - Submit button
|
||||
$oNewsroomSubmitButton = ButtonUIBlockFactory::MakeForPrimaryAction(Dict::S('UI:Button:Apply'), 'operation',
|
||||
'apply_newsroom_preferences', true);
|
||||
$oNewsroomSubmitButton = ButtonUIBlockFactory::MakeForPrimaryAction(
|
||||
Dict::S('UI:Button:Apply'),
|
||||
'operation',
|
||||
'apply_newsroom_preferences',
|
||||
true
|
||||
);
|
||||
$oNewsroomToolbar->AddSubBlock($oNewsroomSubmitButton);
|
||||
|
||||
|
||||
$sNewsroomEndHtml = '</form>';
|
||||
$oNewsroomEndHtmlBlock = new Html($sNewsroomEndHtml);
|
||||
|
||||
@@ -350,7 +361,7 @@ JS
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Panel
|
||||
$oKeyboardShortcutBlock = new Panel(Dict::S('UI:Preferences:PersonalizeKeyboardShortcuts:Title'), array(), 'grey', 'ibo_keyboard_shortcuts');
|
||||
$oKeyboardShortcutBlock = new Panel(Dict::S('UI:Preferences:PersonalizeKeyboardShortcuts:Title'), [], 'grey', 'ibo_keyboard_shortcuts');
|
||||
// Form
|
||||
$oKeyboardShortcutForm = new Form('ibo-form-for-user-interface-preferences');
|
||||
$oKeyboardShortcutForm->AddSubBlock(InputUIBlockFactory::MakeForHidden('operation', 'apply_keyboard_shortcuts'))
|
||||
@@ -412,7 +423,6 @@ JS
|
||||
$oKeyboardShortcutSubmitButton = ButtonUIBlockFactory::MakeForPrimaryAction(Dict::S('UI:Button:Apply'), 'operation', 'apply_keyboard_shortcuts', true);
|
||||
$oKeyboardShortcutToolbar->AddSubBlock($oKeyboardShortcutSubmitButton);
|
||||
|
||||
|
||||
$oContentLayout->AddMainBlock($oKeyboardShortcutBlock);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -421,23 +431,20 @@ JS
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
$oUserPicturePlaceHolderBlock = new Panel(Dict::S('UI:Preferences:ChooseAPlaceholder'), array(), 'grey', 'ibo-user-picture-placeholder');
|
||||
$oUserPicturePlaceHolderBlock = new Panel(Dict::S('UI:Preferences:ChooseAPlaceholder'), [], 'grey', 'ibo-user-picture-placeholder');
|
||||
|
||||
$sUserPicturesFolderRelPath = 'images/user-pictures/';
|
||||
$sUserPicturesFolderAbsPath = APPROOT . $sUserPicturesFolderRelPath;
|
||||
$sUserPicturesFolderAbsUrl = utils::GetAbsoluteUrlAppRoot() . $sUserPicturesFolderRelPath;
|
||||
$sUserPicturesFolderAbsPath = APPROOT.$sUserPicturesFolderRelPath;
|
||||
$sUserPicturesFolderAbsUrl = utils::GetAbsoluteUrlAppRoot().$sUserPicturesFolderRelPath;
|
||||
$sUserDefaultPicture = appUserPreferences::GetPref('user_picture_placeholder', 'default-placeholder.png');
|
||||
$sUserPicturePlaceHolderHtml = '';
|
||||
$sUserPicturePlaceHolderHtml .= '<p>'.Dict::S('UI:Preferences:ChooseAPlaceholder+').'</p> <div class="ibo-preferences--user-preferences--picture-placeholder">';
|
||||
foreach (scandir($sUserPicturesFolderAbsPath) as $sUserPicture)
|
||||
{
|
||||
if ($sUserPicture === '.' || $sUserPicture === '..')
|
||||
{
|
||||
foreach (scandir($sUserPicturesFolderAbsPath) as $sUserPicture) {
|
||||
if ($sUserPicture === '.' || $sUserPicture === '..') {
|
||||
continue;
|
||||
}
|
||||
$sAdditionalClass = '';
|
||||
if ($sUserDefaultPicture === $sUserPicture)
|
||||
{
|
||||
if ($sUserDefaultPicture === $sUserPicture) {
|
||||
$sAdditionalClass = ' ibo-is-active';
|
||||
}
|
||||
$sUserPicturePlaceHolderHtml .= '<a class="ibo-preferences--user-preferences--picture-placeholder--image'.$sAdditionalClass.'" data-image-name="'.$sUserPicture.'" data-role="ibo-preferences--user-preferences--picture-placeholder--image" href="#"> <img src="'.$sUserPicturesFolderAbsUrl.$sUserPicture.'"/> </a>';
|
||||
@@ -473,7 +480,7 @@ $('[data-role="ibo-preferences--user-preferences--picture-placeholder--image"]')
|
||||
});
|
||||
});
|
||||
JS
|
||||
);
|
||||
);
|
||||
$sUserPicturePlaceHolderHtml .=
|
||||
<<<HTML
|
||||
</div>
|
||||
@@ -484,8 +491,7 @@ HTML
|
||||
$oContentLayout->AddMainBlock($oUserPicturePlaceHolderBlock);
|
||||
|
||||
/** @var iPreferencesExtension $oLoginExtensionInstance */
|
||||
foreach (MetaModel::EnumPlugins('iPreferencesExtension') as $oPreferencesExtensionInstance)
|
||||
{
|
||||
foreach (MetaModel::EnumPlugins('iPreferencesExtension') as $oPreferencesExtensionInstance) {
|
||||
$oPreferencesExtensionInstance->DisplayPreferences($oP);
|
||||
}
|
||||
|
||||
@@ -503,7 +509,7 @@ HTML
|
||||
function GetLanguageFieldBlock(): iUIBlock
|
||||
{
|
||||
$aAvailableLanguages = Dict::GetLanguages();
|
||||
$aSortedLanguages = array();
|
||||
$aSortedLanguages = [];
|
||||
foreach ($aAvailableLanguages as $sCode => $aLang) {
|
||||
if (MetaModel::GetConfig()->Get('demo_mode') && ($sCode !== Dict::GetUserLanguage())) {
|
||||
// Demo mode: only the current user language is listed in the available choices
|
||||
@@ -582,10 +588,12 @@ function GetTabsLayoutFieldBlock(): iUIBlock
|
||||
];
|
||||
$oSelect = SelectUIBlockFactory::MakeForSelectWithLabel('tab_layout', Dict::S('UI:Preferences:Tabs:Layout:Label'));
|
||||
foreach ($aOptionsValues as $sValue) {
|
||||
$oSelect->AddSubBlock(SelectOptionUIBlockFactory::MakeForSelectOption(
|
||||
$sValue,
|
||||
Dict::S('UI:Preferences:Tabs:Layout:'.ucfirst($sValue)),
|
||||
$sValue === $sCurrentValue)
|
||||
$oSelect->AddSubBlock(
|
||||
SelectOptionUIBlockFactory::MakeForSelectOption(
|
||||
$sValue,
|
||||
Dict::S('UI:Preferences:Tabs:Layout:'.ucfirst($sValue)),
|
||||
$sValue === $sCurrentValue
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -610,10 +618,12 @@ function GetTabsNavigationFieldBlock(): iUIBlock
|
||||
];
|
||||
$oSelect = SelectUIBlockFactory::MakeForSelectWithLabel('tab_scrollable', Dict::S('UI:Preferences:Tabs:Scrollable:Label'));
|
||||
foreach ($aOptionsValues as $sValue => $sDictEntrySuffix) {
|
||||
$oSelect->AddSubBlock(SelectOptionUIBlockFactory::MakeForSelectOption(
|
||||
$sValue,
|
||||
Dict::S('UI:Preferences:Tabs:Scrollable:'.$sDictEntrySuffix),
|
||||
$sValue === $sCurrentValueAsString)
|
||||
$oSelect->AddSubBlock(
|
||||
SelectOptionUIBlockFactory::MakeForSelectOption(
|
||||
$sValue,
|
||||
Dict::S('UI:Preferences:Tabs:Scrollable:'.$sDictEntrySuffix),
|
||||
$sValue === $sCurrentValueAsString
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -678,7 +688,6 @@ HTML;
|
||||
return new Html($sHtml);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return \Combodo\iTop\Application\UI\Base\iUIBlock
|
||||
* @throws \CoreException
|
||||
@@ -717,7 +726,7 @@ function GetToastsPositionFieldBlock(): iUIBlock
|
||||
$sPosition = appUserPreferences::GetPref('toasts_vertical_position', "bottom");
|
||||
|
||||
$oSelect = SelectUIBlockFactory::MakeForSelectWithLabel('toasts_vertical_position', Dict::S('UI:Preferences:General:Toasts'));
|
||||
|
||||
|
||||
$oSelect->AddSubBlock(SelectOptionUIBlockFactory::MakeForSelectOption("bottom", Dict::S('UI:Preferences:General:Toasts:Bottom'), $sPosition === "bottom"));
|
||||
$oSelect->AddSubBlock(SelectOptionUIBlockFactory::MakeForSelectOption("top", Dict::S('UI:Preferences:General:Toasts:Top'), $sPosition === "top"));
|
||||
|
||||
@@ -754,7 +763,7 @@ try {
|
||||
case 'apply':
|
||||
$oFilter = DBObjectSearch::FromOQL('SELECT Organization');
|
||||
$sSelectionMode = utils::ReadParam('selectionMode', '');
|
||||
$aExceptions = utils::ReadParam('storedSelection', array());
|
||||
$aExceptions = utils::ReadParam('storedSelection', []);
|
||||
if (($sSelectionMode == 'negative') && (count($aExceptions) == 0)) {
|
||||
// All Orgs selected
|
||||
appUserPreferences::SetPref('favorite_orgs', null);
|
||||
@@ -816,17 +825,17 @@ try {
|
||||
// - Obsolete data
|
||||
$bShowObsoleteData = (bool)utils::ReadParam('show_obsolete_data', 0);
|
||||
appUserPreferences::SetPref('show_obsolete_data', $bShowObsoleteData);
|
||||
|
||||
|
||||
// - Summary cards
|
||||
$bShowSummaryCards = (bool)utils::ReadParam('show_summary_cards', 0);
|
||||
appUserPreferences::SetPref('show_summary_cards', $bShowSummaryCards);
|
||||
|
||||
// - Toast notifications
|
||||
$sToastsVerticalPosition = utils::ReadParam('toasts_vertical_position', "bottom");
|
||||
if(utils::IsNotNullOrEmptyString($sToastsVerticalPosition) && in_array($sToastsVerticalPosition, ["bottom", "top"], true)) {
|
||||
if (utils::IsNotNullOrEmptyString($sToastsVerticalPosition) && in_array($sToastsVerticalPosition, ["bottom", "top"], true)) {
|
||||
appUserPreferences::SetPref('toasts_vertical_position', $sToastsVerticalPosition);
|
||||
}
|
||||
|
||||
|
||||
// Redirect to force a reload/display of the page in case language has been changed
|
||||
$oAppContext = new ApplicationContext();
|
||||
$sURL = utils::GetAbsoluteUrlAppRoot().'pages/preferences.php?'.$oAppContext->GetForLink();
|
||||
@@ -878,29 +887,25 @@ try {
|
||||
}
|
||||
}
|
||||
$bProvidersModified = false;
|
||||
foreach ($aProviders as $cProvider)
|
||||
{
|
||||
foreach ($aProviders as $cProvider) {
|
||||
// Forbid disabling internal newsroom provider
|
||||
if ($cProvider === iTopNewsroomProvider::class) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$oProvider = new $cProvider();
|
||||
if ($oProvider->IsApplicable($oUser))
|
||||
{
|
||||
if ($oProvider->IsApplicable($oUser)) {
|
||||
$sProviderClass = get_class($oProvider);
|
||||
$bProviderEnabled = (utils::ReadParam('newsroom_provider_'.$sProviderClass, 'off') == 'on');
|
||||
$bCurrentValue = appUserPreferences::GetPref('newsroom_provider_'.$sProviderClass, true);
|
||||
if ($bCurrentValue != $bProviderEnabled)
|
||||
{
|
||||
if ($bCurrentValue != $bProviderEnabled) {
|
||||
// Save the preference only if it differs from the current value
|
||||
$bProvidersModified = true;
|
||||
appUserPreferences::SetPref('newsroom_provider_'.$sProviderClass, $bProviderEnabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($bProvidersModified)
|
||||
{
|
||||
if ($bProvidersModified) {
|
||||
$oPage->add_ready_script(
|
||||
<<<JS
|
||||
$('#ibo-navigation-menu--notifications-menu').newsroom_menu("clearCache");
|
||||
@@ -913,26 +918,28 @@ JS
|
||||
|
||||
case 'display':
|
||||
default:
|
||||
$oPage->SetBreadCrumbEntry('ui-tool-preferences', Dict::S('UI:Preferences'), Dict::S('UI:Preferences'), '',
|
||||
'fas fa-user-cog', iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES);
|
||||
$oPage->SetBreadCrumbEntry(
|
||||
'ui-tool-preferences',
|
||||
Dict::S('UI:Preferences'),
|
||||
Dict::S('UI:Preferences'),
|
||||
'',
|
||||
'fas fa-user-cog',
|
||||
iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES
|
||||
);
|
||||
DisplayPreferences($oPage);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$oPage->output();
|
||||
}
|
||||
catch(CoreException $e)
|
||||
{
|
||||
} catch (CoreException $e) {
|
||||
require_once(APPROOT.'/setup/setuppage.class.inc.php');
|
||||
$oP = new ErrorPage(Dict::S('UI:PageTitle:FatalError'));
|
||||
$oP->add("<h1>".Dict::S('UI:FatalErrorMessage')."</h1>\n");
|
||||
$oP->error(Dict::Format('UI:Error_Details', $e->getHtmlDesc()));
|
||||
$oP->add("<h1>".Dict::S('UI:FatalErrorMessage')."</h1>\n");
|
||||
$oP->error(Dict::Format('UI:Error_Details', $e->getHtmlDesc()));
|
||||
$oP->output();
|
||||
|
||||
if (MetaModel::IsLogEnabledIssue())
|
||||
{
|
||||
if (MetaModel::IsValidClass('EventIssue'))
|
||||
{
|
||||
if (MetaModel::IsLogEnabledIssue()) {
|
||||
if (MetaModel::IsValidClass('EventIssue')) {
|
||||
$oLog = new EventIssue();
|
||||
|
||||
$oLog->Set('message', $e->getMessage());
|
||||
@@ -949,19 +956,15 @@ catch(CoreException $e)
|
||||
|
||||
// For debugging only
|
||||
//throw $e;
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
} catch (Exception $e) {
|
||||
require_once(APPROOT.'/setup/setuppage.class.inc.php');
|
||||
$oP = new ErrorPage(Dict::S('UI:PageTitle:FatalError'));
|
||||
$oP->add("<h1>".Dict::S('UI:FatalErrorMessage')."</h1>\n");
|
||||
$oP->error(Dict::Format('UI:Error_Details', $e->getMessage()));
|
||||
$oP->add("<h1>".Dict::S('UI:FatalErrorMessage')."</h1>\n");
|
||||
$oP->error(Dict::Format('UI:Error_Details', $e->getMessage()));
|
||||
$oP->output();
|
||||
|
||||
if (MetaModel::IsLogEnabledIssue())
|
||||
{
|
||||
if (MetaModel::IsValidClass('EventIssue'))
|
||||
{
|
||||
if (MetaModel::IsLogEnabledIssue()) {
|
||||
if (MetaModel::IsValidClass('EventIssue')) {
|
||||
$oLog = new EventIssue();
|
||||
|
||||
$oLog->Set('message', $e->getMessage());
|
||||
@@ -969,7 +972,7 @@ catch(Exception $e)
|
||||
$oLog->Set('issue', 'PHP Exception');
|
||||
$oLog->Set('impact', 'Page could not be displayed');
|
||||
$oLog->Set('callstack', $e->getTrace());
|
||||
$oLog->Set('data', array());
|
||||
$oLog->Set('data', []);
|
||||
$oLog->DBInsertNoReload();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -41,26 +42,26 @@ function ShowExamples($oP, $sExpression)
|
||||
{
|
||||
$bUsingExample = false;
|
||||
|
||||
$aExamples = array(
|
||||
'Pedagogic examples' => array(
|
||||
$aExamples = [
|
||||
'Pedagogic examples' => [
|
||||
"Person" => "SELECT Person",
|
||||
"Person having an 'A' in their name" => "SELECT Person AS B WHERE B.name LIKE '%A%'",
|
||||
"Organization having a name beginning by 'My'" => "SELECT Organization WHERE name REGEXP '^My .*$'",
|
||||
"Changes planned on new year's day" => "SELECT Change AS ch WHERE ch.start_date >= '2009-12-31' AND ch.end_date <= '2010-01-01'",
|
||||
"IPs in a range" => "SELECT DatacenterDevice AS dev WHERE INET_ATON(dev.managementip) > INET_ATON('10.22.32.224') AND INET_ATON(dev.managementip) < INET_ATON('10.22.32.255')",
|
||||
"Persons below a given root organization" => "SELECT Person AS P JOIN Organization AS Node ON P.org_id = Node.id JOIN Organization AS Root ON Node.parent_id BELOW Root.id WHERE Root.id=1",
|
||||
),
|
||||
'Usefull examples' => array(
|
||||
],
|
||||
'Usefull examples' => [
|
||||
"NW interfaces of equipment in production for customer 'Demo'" => "SELECT PhysicalInterface AS if JOIN DatacenterDevice AS dev ON if.connectableci_id = dev.id WHERE dev.status = 'production' AND dev.organization_name = 'Demo'",
|
||||
"My tickets" => "SELECT Ticket AS t WHERE t.agent_id = :current_contact_id",
|
||||
"People being owner of an active ticket" => "SELECT Person AS p JOIN UserRequest AS u ON u.agent_id = p.id WHERE u.status != 'closed'",
|
||||
"Contracts terminating in the next thirty days" => "SELECT Contract AS c WHERE c.end_date > NOW() AND c.end_date < DATE_ADD(NOW(), INTERVAL 30 DAY)",
|
||||
"Orphan tickets (opened one hour ago, still not assigned)" => "SELECT UserRequest AS u WHERE u.start_date < DATE_SUB(NOW(), INTERVAL 60 MINUTE) AND u.status = 'new'",
|
||||
"Long lasting incidents (duration > 8 hours)" => "SELECT UserRequest AS u WHERE u.close_date > DATE_ADD(u.start_date, INTERVAL 8 HOUR)",
|
||||
),
|
||||
);
|
||||
],
|
||||
];
|
||||
|
||||
$aDisplayData = array();
|
||||
$aDisplayData = [];
|
||||
$oAppContext = new ApplicationContext();
|
||||
$sContext = $oAppContext->GetForForm();
|
||||
foreach ($aExamples as $sTopic => $aQueries) {
|
||||
@@ -81,23 +82,23 @@ function ShowExamples($oP, $sExpression)
|
||||
$oFormButton->AddSubBlock($oButton);
|
||||
$oFormButton->AddSubBlock(new Html($sContext));
|
||||
//$aDisplayData[$sTopic][] = array(
|
||||
$aDisplayData[Dict::S('UI:RunQuery:QueryExamples')][] = array(
|
||||
$aDisplayData[Dict::S('UI:RunQuery:QueryExamples')][] = [
|
||||
'desc' => "<div class=\"$sHighlight\">".utils::EscapeHtml($sDescription)."</div>",
|
||||
'oql' => "<div class=\"$sHighlight\">".utils::EscapeHtml($sOql)."</div>",
|
||||
'go' => BlockRenderer::RenderBlockTemplates($oFormButton),
|
||||
);
|
||||
];
|
||||
}
|
||||
}
|
||||
$aDisplayConfig = array();
|
||||
$aDisplayConfig['desc'] = array(
|
||||
$aDisplayConfig = [];
|
||||
$aDisplayConfig['desc'] = [
|
||||
'label' => Dict::S('UI:RunQuery:HeaderPurpose'),
|
||||
'description' => Dict::S('UI:RunQuery:HeaderPurpose+'),
|
||||
);
|
||||
$aDisplayConfig['oql'] = array(
|
||||
];
|
||||
$aDisplayConfig['oql'] = [
|
||||
'label' => Dict::S('UI:RunQuery:HeaderOQLExpression'),
|
||||
'description' => Dict::S('UI:RunQuery:HeaderOQLExpression+'),
|
||||
);
|
||||
$aDisplayConfig['go'] = array('label' => '', 'description' => '');
|
||||
];
|
||||
$aDisplayConfig['go'] = ['label' => '', 'description' => ''];
|
||||
|
||||
foreach ($aDisplayData as $sTopic => $aQueriesDisplayData) {
|
||||
$bShowOpened = $bUsingExample;
|
||||
@@ -120,8 +121,7 @@ $sEncoding = utils::ReadParam('encoding', 'oql');
|
||||
|
||||
ShowExamples($oP, $sExpression);
|
||||
|
||||
try
|
||||
{
|
||||
try {
|
||||
if ($sEncoding == 'crypted') {
|
||||
// Translate $sExpression into a oql expression
|
||||
$oFilter = DBObjectSearch::unserialize($sExpression);
|
||||
@@ -129,32 +129,23 @@ try
|
||||
}
|
||||
|
||||
$oFilter = null;
|
||||
$aArgs = array();
|
||||
$aArgs = [];
|
||||
$sSyntaxError = null;
|
||||
|
||||
if (!empty($sExpression))
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!empty($sExpression)) {
|
||||
try {
|
||||
$oFilter = DBObjectSearch::FromOQL($sExpression);
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
if ($e instanceof OqlException)
|
||||
{
|
||||
} catch (Exception $e) {
|
||||
if ($e instanceof OqlException) {
|
||||
$sSyntaxError = $e->getHtmlDesc();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$sSyntaxError = $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
if ($oFilter)
|
||||
{
|
||||
$aArgs = array();
|
||||
foreach($oFilter->GetQueryParams() as $sParam => $foo)
|
||||
{
|
||||
if ($oFilter) {
|
||||
$aArgs = [];
|
||||
foreach ($oFilter->GetQueryParams() as $sParam => $foo) {
|
||||
$value = utils::ReadParam('arg_'.$sParam, null, true, 'raw_data');
|
||||
if (!is_null($value)) {
|
||||
$aArgs[$sParam] = $value;
|
||||
@@ -180,7 +171,8 @@ try
|
||||
$oQueryTextArea->AddCSSClasses(['ibo-input-text', 'ibo-query-oql', 'ibo-is-code']);
|
||||
$oQueryForm->AddSubBlock($oQueryTextArea);
|
||||
|
||||
$oP->add_ready_script(<<<JS
|
||||
$oP->add_ready_script(
|
||||
<<<JS
|
||||
$("#expression").select();
|
||||
$("#expression").on('keyup', function (oEvent) {
|
||||
if ((oEvent.ctrlKey || oEvent.metaKey) && oEvent.key === 'Enter') {
|
||||
@@ -193,11 +185,11 @@ JS
|
||||
if (count($aArgs) > 0) {
|
||||
//--- Query arguments
|
||||
$oQueryForm->AddSubBlock(TitleUIBlockFactory::MakeNeutral(Dict::S('UI:RunQuery:QueryArguments'), 3)->AddCSSClass("ibo-collapsible-section--title"));
|
||||
$oQueryArgsContainer = UIContentBlockUIBlockFactory::MakeStandard(null,['wizContainer']);
|
||||
$oQueryArgsContainer = UIContentBlockUIBlockFactory::MakeStandard(null, ['wizContainer']);
|
||||
$oQueryForm->AddSubBlock($oQueryArgsContainer);
|
||||
foreach ($aArgs as $sParam => $sValue) {
|
||||
$oInput = InputUIBlockFactory::MakeStandard("text",'arg_'.$sParam, $sValue);
|
||||
$oArgInput = \Combodo\iTop\Application\UI\Base\Component\Field\FieldUIBlockFactory::MakeFromObject($sParam,$oInput,Field::ENUM_FIELD_LAYOUT_SMALL);
|
||||
$oInput = InputUIBlockFactory::MakeStandard("text", 'arg_'.$sParam, $sValue);
|
||||
$oArgInput = \Combodo\iTop\Application\UI\Base\Component\Field\FieldUIBlockFactory::MakeFromObject($sParam, $oInput, Field::ENUM_FIELD_LAYOUT_SMALL);
|
||||
$oArgInput->AddCSSClass("ibo-field--label-small");
|
||||
//$oArgInput = InputUIBlockFactory::MakeForInputWithLabel( $sParam, 'arg_'.$sParam, $sValue );
|
||||
$oQueryArgsContainer->AddSubBlock($oArgInput);
|
||||
@@ -216,10 +208,9 @@ JS
|
||||
$oQueryForm->AddSubBlock($oToolbarButtons);
|
||||
$oToolbarButtons->AddSubBlock($oQuerySubmit);
|
||||
|
||||
|
||||
if ($oFilter) {
|
||||
//--- Query filter
|
||||
$oPanelResult= PanelUIBlockFactory::MakeWithBrandingSecondaryColor(Dict::S('UI:RunQuery:QueryResults'));
|
||||
$oPanelResult = PanelUIBlockFactory::MakeWithBrandingSecondaryColor(Dict::S('UI:RunQuery:QueryResults'));
|
||||
$oP->AddSubBlock($oPanelResult);
|
||||
$oResultBlock = new DisplayBlock($oFilter, 'list', false);
|
||||
$oPanelResult->AddSubBlock($oResultBlock->GetDisplay($oP, 'runquery'));
|
||||
@@ -228,10 +219,10 @@ JS
|
||||
//$iCount = $oResultBlock->GetDisplayedCount();
|
||||
$sPageId = "ui-search-".$oFilter->GetClass();
|
||||
$sLabel = MetaModel::GetName($oFilter->GetClass());
|
||||
$aArgs = array();
|
||||
$aArgs = [];
|
||||
foreach (array_merge($_POST, $_GET) as $sKey => $value) {
|
||||
if (is_array($value)) {
|
||||
$aItems = array();
|
||||
$aItems = [];
|
||||
foreach ($value as $sItemKey => $sItemValue) {
|
||||
$aArgs[] = $sKey.'['.$sItemKey.']='.urlencode($sItemValue);
|
||||
}
|
||||
@@ -242,7 +233,6 @@ JS
|
||||
$sUrl = utils::GetAbsoluteUrlAppRoot().'pages/run_query.php?'.implode('&', $aArgs);
|
||||
$oP->SetBreadCrumbEntry($sPageId, $sLabel, $oFilter->ToOQL(true), $sUrl, 'fas fa-terminal', iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES);
|
||||
|
||||
|
||||
//--- More info
|
||||
$aMoreInfoBlocks = [];
|
||||
|
||||
@@ -254,14 +244,13 @@ JS
|
||||
$oSerializedQuerySet->AddSubBlock(UIContentBlockUIBlockFactory::MakeForCode($oFilter->serialize()));
|
||||
$aMoreInfoBlocks[] = $oSerializedQuerySet;
|
||||
|
||||
|
||||
$aModifierProperties = MetaModel::MakeModifierProperties($oFilter);
|
||||
|
||||
// Avoid adding all the fields for counts or "group by" requests
|
||||
$aCountAttToLoad = array();
|
||||
$aCountAttToLoad = [];
|
||||
$sMainClass = null;
|
||||
foreach ($oFilter->GetSelectedClasses() as $sClassAlias => $sClass) {
|
||||
$aCountAttToLoad[$sClassAlias] = array();
|
||||
$aCountAttToLoad[$sClassAlias] = [];
|
||||
if (empty($sMainClass)) {
|
||||
$sMainClass = $sClass;
|
||||
}
|
||||
@@ -279,7 +268,7 @@ JS
|
||||
}
|
||||
|
||||
// SQL Count
|
||||
$sSQL = $oFilter->MakeSelectQuery(array(), $aRealArgs, $aCountAttToLoad, null, 0, 0, true);
|
||||
$sSQL = $oFilter->MakeSelectQuery([], $aRealArgs, $aCountAttToLoad, null, 0, 0, true);
|
||||
$oCountResultQuerySet = new FieldSet(Dict::S('UI:RunQuery:ResultSQLCount'));
|
||||
$oCountResultQuerySet->AddSubBlock(UIContentBlockUIBlockFactory::MakeForCode($sSQL));
|
||||
$aMoreInfoBlocks[] = $oCountResultQuerySet;
|
||||
@@ -324,13 +313,13 @@ JS
|
||||
$sEscapedExpression = json_encode(utils::EscapeHtml($sFixedExpression));
|
||||
$oUseSuggestedQueryButton = ButtonUIBlockFactory::MakeForDestructiveAction('Use this query');
|
||||
$oUseSuggestedQueryButton->SetOnClickJsCode(
|
||||
<<<JS
|
||||
<<<JS
|
||||
let \$oQueryTextarea = $('textarea[name=expression]');
|
||||
\$oQueryTextarea.val($sEscapedExpression).focus();
|
||||
\$oQueryTextarea.closest('form').submit();
|
||||
JS
|
||||
);
|
||||
$oSyntaxErrorPanel->AddSubBlock($oUseSuggestedQueryButton);
|
||||
$oSyntaxErrorPanel->AddSubBlock($oUseSuggestedQueryButton);
|
||||
} else {
|
||||
$oSyntaxErrorPanel->AddSubBlock(HtmlFactory::MakeParagraph($e->getHtmlDesc()));
|
||||
}
|
||||
@@ -341,8 +330,7 @@ JS
|
||||
$oSyntaxErrorPanel->AddSubBlock(HtmlFactory::MakeParagraph($e->getMessage()));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
$oErrorAlert = AlertUIBlockFactory::MakeForFailure(
|
||||
Dict::Format('UI:RunQuery:Error', $e->getMessage()),
|
||||
'<pre>'.$e->getTraceAsString().'</pre>'
|
||||
@@ -352,4 +340,3 @@ catch (Exception $e) {
|
||||
}
|
||||
|
||||
$oP->output();
|
||||
|
||||
|
||||
411
pages/schema.php
411
pages/schema.php
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -30,9 +31,11 @@ ApplicationMenu::CheckMenuIdEnabled('DataModelMenu');
|
||||
*/
|
||||
function MakeClassHLink($sClass, $sContext)
|
||||
{
|
||||
return "<a href=\"schema.php?operation=details_class&class=$sClass{$sContext}\" title=\"".html_entity_decode(MetaModel::GetClassDescription($sClass),
|
||||
ENT_QUOTES,
|
||||
'UTF-8')."\">".MetaModel::GetName($sClass)." (".$sClass.")</a>";
|
||||
return "<a href=\"schema.php?operation=details_class&class=$sClass{$sContext}\" title=\"".html_entity_decode(
|
||||
MetaModel::GetClassDescription($sClass),
|
||||
ENT_QUOTES,
|
||||
'UTF-8'
|
||||
)."\">".MetaModel::GetName($sClass)." (".$sClass.")</a>";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -41,25 +44,20 @@ function MakeClassHLink($sClass, $sContext)
|
||||
function DisplaySubclasses($oPage, $sClass, $sContext)
|
||||
{
|
||||
$aChildClasses = MetaModel::EnumChildClasses($sClass);
|
||||
if (count($aChildClasses) != 0)
|
||||
{
|
||||
if (count($aChildClasses) != 0) {
|
||||
$oPage->add("<ul>\n");
|
||||
$aOrderedClasses = array();
|
||||
foreach ($aChildClasses as $sClassName)
|
||||
{
|
||||
$aOrderedClasses = [];
|
||||
foreach ($aChildClasses as $sClassName) {
|
||||
// Skip indirect childs, they will be handled somewhere else
|
||||
if (MetaModel::GetParentPersistentClass($sClassName) == $sClass)
|
||||
{
|
||||
if (MetaModel::GetParentPersistentClass($sClassName) == $sClass) {
|
||||
$aOrderedClasses[$sClassName] = MetaModel::GetName($sClassName);
|
||||
}
|
||||
}
|
||||
// Sort on the display name
|
||||
asort($aOrderedClasses);
|
||||
foreach ($aOrderedClasses as $sClassName => $sDisplayName)
|
||||
{
|
||||
foreach ($aOrderedClasses as $sClassName => $sDisplayName) {
|
||||
// Skip indirect childs, they will be handled somewhere else
|
||||
if (MetaModel::GetParentPersistentClass($sClassName) == $sClass)
|
||||
{
|
||||
if (MetaModel::GetParentPersistentClass($sClassName) == $sClass) {
|
||||
$oPage->add("<li class=\"open\">".MakeClassHLink($sClassName, $sContext)."\n");
|
||||
DisplaySubclasses($oPage, $sClassName, $sContext);
|
||||
$oPage->add("</li>\n");
|
||||
@@ -73,40 +71,33 @@ function DisplaySubclasses($oPage, $sClass, $sContext)
|
||||
*/
|
||||
function GetSubclasses($sClass, $sContext)
|
||||
{
|
||||
|
||||
$sHtml = '';
|
||||
try{
|
||||
$aChildClasses = MetaModel::EnumChildClasses($sClass);
|
||||
if (count($aChildClasses) != 0)
|
||||
{
|
||||
|
||||
$sHtml .= "<ul>";
|
||||
$aOrderedClasses = array();
|
||||
foreach ($aChildClasses as $sClassName)
|
||||
{
|
||||
// Skip indirect childs, they will be handled somewhere else
|
||||
if (MetaModel::GetParentPersistentClass($sClassName) == $sClass)
|
||||
{
|
||||
$aOrderedClasses[$sClassName] = MetaModel::GetName($sClassName);
|
||||
$sHtml = '';
|
||||
try {
|
||||
$aChildClasses = MetaModel::EnumChildClasses($sClass);
|
||||
if (count($aChildClasses) != 0) {
|
||||
|
||||
$sHtml .= "<ul>";
|
||||
$aOrderedClasses = [];
|
||||
foreach ($aChildClasses as $sClassName) {
|
||||
// Skip indirect childs, they will be handled somewhere else
|
||||
if (MetaModel::GetParentPersistentClass($sClassName) == $sClass) {
|
||||
$aOrderedClasses[$sClassName] = MetaModel::GetName($sClassName);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Sort on the display name
|
||||
asort($aOrderedClasses);
|
||||
foreach ($aOrderedClasses as $sClassName => $sDisplayName)
|
||||
{
|
||||
// Skip indirect childs, they will be handled somewhere else
|
||||
if (MetaModel::GetParentPersistentClass($sClassName) == $sClass)
|
||||
{
|
||||
$sHtml .="<li class=\"open\">".MakeClassHLink($sClassName, $sContext);
|
||||
$sHtml .= GetSubclasses($sClassName, $sContext);
|
||||
$sHtml .= "</li>";
|
||||
// Sort on the display name
|
||||
asort($aOrderedClasses);
|
||||
foreach ($aOrderedClasses as $sClassName => $sDisplayName) {
|
||||
// Skip indirect childs, they will be handled somewhere else
|
||||
if (MetaModel::GetParentPersistentClass($sClassName) == $sClass) {
|
||||
$sHtml .= "<li class=\"open\">".MakeClassHLink($sClassName, $sContext);
|
||||
$sHtml .= GetSubclasses($sClassName, $sContext);
|
||||
$sHtml .= "</li>";
|
||||
}
|
||||
}
|
||||
$sHtml .= "</ul>";
|
||||
}
|
||||
$sHtml .= "</ul>";
|
||||
}
|
||||
}
|
||||
|
||||
catch(Exception $e){
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
return $sHtml;
|
||||
}
|
||||
@@ -116,12 +107,9 @@ function GetSubclasses($sClass, $sContext)
|
||||
*/
|
||||
function DisplayLifecycle($oPage, $sClass)
|
||||
{
|
||||
if (!MetaModel::HasLifecycle($sClass))
|
||||
{
|
||||
if (!MetaModel::HasLifecycle($sClass)) {
|
||||
$oPage->p(Dict::S('UI:Schema:NoLifeCyle'));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$aStates = MetaModel::EnumStates($sClass);
|
||||
$aStimuli = MetaModel::EnumStimuli($sClass);
|
||||
$oPage->add("<img id=\"img-lifecycle\" class=\"ibo-datamodel-viewer--lifecycle-image\" attr=\"$sClass lifecycle graph\" src=\"".utils::GetAbsoluteUrlAppRoot()."pages/graphviz.php?class=$sClass\">\n");
|
||||
@@ -130,7 +118,6 @@ function DisplayLifecycle($oPage, $sClass)
|
||||
$("#img-lifecycle").attr('href',$("#img-lifecycle").attr('src'));
|
||||
$("#img-lifecycle").magnificPopup({type: 'image', closeOnContentClick: true});
|
||||
EOF
|
||||
|
||||
);
|
||||
$oOpenAllButton = ButtonUIBlockFactory::MakeForAlternativePrimaryAction('Open All', '', '', false, 'lifecycleOpenAll');
|
||||
$oOpenAllButton->SetOnClickJsCode(
|
||||
@@ -138,7 +125,6 @@ EOF
|
||||
$('#LifeCycleList').find('.expandable-hitarea').click();
|
||||
$('#LifeCycleAttrOptList').find('.expandable-hitarea').click();
|
||||
JS
|
||||
|
||||
);
|
||||
$oCloseAllButton = ButtonUIBlockFactory::MakeForAlternativePrimaryAction('Close All', '', '', false, 'lifecycleCloseAll');
|
||||
$oCloseAllButton->SetOnClickJsCode(
|
||||
@@ -146,46 +132,35 @@ JS
|
||||
$('#LifeCycleList').find('.collapsable-hitarea').click();
|
||||
$('#LifeCycleAttrOptList').find('.collapsable-hitarea').click();
|
||||
JS
|
||||
|
||||
);
|
||||
$oPage->AddUiBlock($oOpenAllButton);
|
||||
$oPage->AddUiBlock($oCloseAllButton);
|
||||
$oPage->AddUiBlock(TitleUIBlockFactory::MakeNeutral(Dict::S('UI:Schema:LifeCycleTransitions'), 3));
|
||||
$oPage->add("<ul id=\"LifeCycleList\" >\n");
|
||||
foreach ($aStates as $sStateCode => $aStateDef)
|
||||
{
|
||||
foreach ($aStates as $sStateCode => $aStateDef) {
|
||||
$sStateLabel = MetaModel::GetStateLabel($sClass, $sStateCode);
|
||||
$sStateDescription = MetaModel::GetStateDescription($sClass, $sStateCode);
|
||||
$oPage->add("<li class=\"closed\">$sStateLabel <span class=\"ibo-datamodel-viewer--lifecycle--code\"> ($sStateCode) $sStateDescription</span>\n");
|
||||
$oPage->add("<ul class=\"closed\">\n");
|
||||
foreach (MetaModel::EnumTransitions($sClass, $sStateCode) as $sStimulusCode => $aTransitionDef)
|
||||
{
|
||||
foreach (MetaModel::EnumTransitions($sClass, $sStateCode) as $sStimulusCode => $aTransitionDef) {
|
||||
$sStimulusLabel = $aStimuli[$sStimulusCode]->GetLabel();
|
||||
$sTargetState = $aTransitionDef['target_state'];
|
||||
$sTargetStateLabel = MetaModel::GetStateLabel($sClass, $sTargetState);
|
||||
if (count($aTransitionDef['actions']) > 0)
|
||||
{
|
||||
$aActionsDesc = array();
|
||||
foreach ($aTransitionDef['actions'] as $actionHandler)
|
||||
{
|
||||
if (is_string($actionHandler))
|
||||
{
|
||||
if (count($aTransitionDef['actions']) > 0) {
|
||||
$aActionsDesc = [];
|
||||
foreach ($aTransitionDef['actions'] as $actionHandler) {
|
||||
if (is_string($actionHandler)) {
|
||||
$aActionsDesc[] = $actionHandler;
|
||||
}
|
||||
else
|
||||
{
|
||||
$aParamsDesc = array();
|
||||
foreach ($actionHandler['params'] as $aParamData)
|
||||
{
|
||||
} else {
|
||||
$aParamsDesc = [];
|
||||
foreach ($actionHandler['params'] as $aParamData) {
|
||||
$aParamsDesc[] = $aParamData['type'].':'.$aParamData['value'];
|
||||
}
|
||||
$aActionsDesc[] = $actionHandler['verb'].'('.implode(', ', $aParamsDesc).')';
|
||||
}
|
||||
}
|
||||
$sActions = " <em>(".implode(', ', $aActionsDesc).")</em>";
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$sActions = "";
|
||||
}
|
||||
|
||||
@@ -199,55 +174,42 @@ JS
|
||||
$oPage->add("</ul>\n");
|
||||
$oPage->AddUiBlock(TitleUIBlockFactory::MakeNeutral(Dict::S('UI:Schema:LifeCyleAttributeOptions'), 3));
|
||||
$oPage->add("<ul id=\"LifeCycleAttrOptList\">\n");
|
||||
foreach ($aStates as $sStateCode => $aStateDef)
|
||||
{
|
||||
foreach ($aStates as $sStateCode => $aStateDef) {
|
||||
$sStateLabel = MetaModel::GetStateLabel($sClass, $sStateCode);
|
||||
$sStateDescription = MetaModel::GetStateDescription($sClass, $sStateCode);
|
||||
$oPage->add("<li class=\"closed\">$sStateLabel<span class=\"ibo-datamodel-viewer--lifecycle--code\"> ($sStateCode) $sStateDescription</span>\n");
|
||||
if (count($aStates[$sStateCode]['attribute_list']) > 0)
|
||||
{
|
||||
if (count($aStates[$sStateCode]['attribute_list']) > 0) {
|
||||
$oPage->add("<ul>\n");
|
||||
foreach ($aStates[$sStateCode]['attribute_list'] as $sAttCode => $iOptions)
|
||||
{
|
||||
foreach ($aStates[$sStateCode]['attribute_list'] as $sAttCode => $iOptions) {
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||
$sAttLabel = $oAttDef->GetLabel();
|
||||
|
||||
$aOptions = array();
|
||||
if ($iOptions & OPT_ATT_HIDDEN)
|
||||
{
|
||||
$aOptions = [];
|
||||
if ($iOptions & OPT_ATT_HIDDEN) {
|
||||
$aOptions[] = Dict::S('UI:Schema:LifeCycleHiddenAttribute');
|
||||
}
|
||||
if ($iOptions & OPT_ATT_READONLY)
|
||||
{
|
||||
if ($iOptions & OPT_ATT_READONLY) {
|
||||
$aOptions[] = Dict::S('UI:Schema:LifeCycleReadOnlyAttribute');
|
||||
}
|
||||
if ($iOptions & OPT_ATT_MANDATORY)
|
||||
{
|
||||
if ($iOptions & OPT_ATT_MANDATORY) {
|
||||
$aOptions[] = Dict::S('UI:Schema:LifeCycleMandatoryAttribute');
|
||||
}
|
||||
if ($iOptions & OPT_ATT_MUSTCHANGE)
|
||||
{
|
||||
if ($iOptions & OPT_ATT_MUSTCHANGE) {
|
||||
$aOptions[] = Dict::S('UI:Schema:LifeCycleAttributeMustChange');
|
||||
}
|
||||
if ($iOptions & OPT_ATT_MUSTPROMPT)
|
||||
{
|
||||
if ($iOptions & OPT_ATT_MUSTPROMPT) {
|
||||
$aOptions[] = Dict::S('UI:Schema:LifeCycleAttributeMustPrompt');
|
||||
}
|
||||
if (count($aOptions))
|
||||
{
|
||||
if (count($aOptions)) {
|
||||
$sOptions = implode(', ', $aOptions);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$sOptions = "";
|
||||
}
|
||||
|
||||
$oPage->add("<li class=\"closed\"><span class=\"ibo-datamodel-viewer--lifecycle--attribute-option\">$sAttLabel</span> $sOptions</li>\n");
|
||||
}
|
||||
$oPage->add("</ul></li>\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$oPage->p("<em>".Dict::S('UI:Schema:LifeCycleEmptyList')."</em>");
|
||||
}
|
||||
}
|
||||
@@ -257,7 +219,6 @@ JS
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper for the trigger
|
||||
*/
|
||||
@@ -265,7 +226,7 @@ function DisplayTriggers($oPage, $sClass)
|
||||
{
|
||||
$sClassList = implode("', '", MetaModel::EnumParentClasses($sClass, ENUM_PARENT_CLASSES_ALL));
|
||||
$oSet = new CMDBObjectSet(DBObjectSearch::FromOQL("SELECT TriggerOnObject WHERE target_class IN ('$sClassList')"));
|
||||
cmdbAbstractObject::DisplaySet($oPage, $oSet, array('block_id' => 'triggers'));
|
||||
cmdbAbstractObject::DisplaySet($oPage, $oSet, ['block_id' => 'triggers']);
|
||||
}
|
||||
|
||||
function DisplayEvents(WebPage $oPage, $sClass)
|
||||
@@ -301,7 +262,7 @@ function DisplayEvents(WebPage $oPage, $sClass)
|
||||
} else {
|
||||
$oObject = MetaModel::NewObject($sClass);
|
||||
foreach (MetaModel::EnumParentClasses($sClass, ENUM_PARENT_CLASSES_ALL, false) as $sParentClass) {
|
||||
$aSources[] = $sParentClass;
|
||||
$aSources[] = $sParentClass;
|
||||
}
|
||||
}
|
||||
$aListeners = [];
|
||||
@@ -345,7 +306,7 @@ function DisplayEvents(WebPage $oPage, $sClass)
|
||||
}
|
||||
}
|
||||
$sListener = $sListenerClass.'->'.$aListener['callback'][1].'(\Combodo\iTop\Service\Events\EventData $oEventData)';
|
||||
} else if (is_array($aListener['callback'])) {
|
||||
} elseif (is_array($aListener['callback'])) {
|
||||
$sListener = $aListener['callback'][0].'::'.$aListener['callback'][1];
|
||||
} else {
|
||||
$sListener = $aListener['callback'].'(\Combodo\iTop\Service\Events\EventData $oEventData)';
|
||||
@@ -368,28 +329,24 @@ function DisplayEvents(WebPage $oPage, $sClass)
|
||||
function DisplayClassesList($oPage, $oLayout, $sContext)
|
||||
{
|
||||
$sSelectedClass = utils::ReadParam('class', '', false, 'class');
|
||||
|
||||
|
||||
$oLayout->AddSideHtml("<label for='search-model'>".Dict::S('UI:Schema:ClassFilter')."</label><br>");
|
||||
|
||||
|
||||
$oListSearch = new Select("ibo-datamodel-viewer--class-search");
|
||||
$oListSearch->SetName('aa');
|
||||
// Get all the "root" classes for display
|
||||
$aRootClasses = array();
|
||||
$aRootClasses = [];
|
||||
$aClassLabelAndCodeAsJSON = [];
|
||||
$aClassLabelAsJSON = array();
|
||||
$aClassCodeAsJSON = array();
|
||||
$aClassLabelAsJSON = [];
|
||||
$aClassCodeAsJSON = [];
|
||||
|
||||
$oOptionSearch = SelectOptionUIBlockFactory::MakeForSelectOption('', "select option", true);
|
||||
$oListSearch->AddOption($oOptionSearch->SetDisabled(true));
|
||||
|
||||
foreach (MetaModel::GetClasses() as $sClassName)
|
||||
{
|
||||
if (MetaModel::IsRootClass($sClassName))
|
||||
{
|
||||
foreach (MetaModel::GetClasses() as $sClassName) {
|
||||
if (MetaModel::IsRootClass($sClassName)) {
|
||||
$aRootClasses[$sClassName] = MetaModel::GetName($sClassName);
|
||||
}
|
||||
elseif (MetaModel::IsStandaloneClass($sClassName))
|
||||
{
|
||||
} elseif (MetaModel::IsStandaloneClass($sClassName)) {
|
||||
$aRootClasses[$sClassName] = MetaModel::GetName($sClassName);
|
||||
}
|
||||
$sLabelClassName = MetaModel::GetName($sClassName);
|
||||
@@ -398,9 +355,9 @@ function DisplayClassesList($oPage, $oLayout, $sContext)
|
||||
$oListSearch->AddOption($oOptionSearch);
|
||||
//Fetch classes names for autocomplete purpose
|
||||
// - Encode as JSON to escape quotes and other characters
|
||||
array_push ($aClassLabelAndCodeAsJSON, ["value"=>$sClassName,"label"=>"$sLabelClassName ($sClassName)"]);
|
||||
array_push ($aClassLabelAsJSON, ["value"=>$sClassName,"label"=>"$sLabelClassName"]);
|
||||
array_push ($aClassCodeAsJSON, ["value"=>$sClassName,"label"=>"$sClassName"]);
|
||||
array_push($aClassLabelAndCodeAsJSON, ["value" => $sClassName,"label" => "$sLabelClassName ($sClassName)"]);
|
||||
array_push($aClassLabelAsJSON, ["value" => $sClassName,"label" => "$sLabelClassName"]);
|
||||
array_push($aClassCodeAsJSON, ["value" => $sClassName,"label" => "$sClassName"]);
|
||||
}
|
||||
usort($aClassLabelAndCodeAsJSON, "Label_sort");
|
||||
$oLayout->AddSideBlock($oListSearch);
|
||||
@@ -457,22 +414,17 @@ JS
|
||||
}
|
||||
|
||||
JS
|
||||
|
||||
);
|
||||
|
||||
// Sort them alphabetically on their display name
|
||||
asort($aClassLabelAndCodeAsJSON);
|
||||
//usort($aRootClasses,"Label_sort");
|
||||
foreach ($aRootClasses as $sClassName => $sDisplayName)
|
||||
{
|
||||
if (MetaModel::IsRootClass($sClassName))
|
||||
{
|
||||
foreach ($aRootClasses as $sClassName => $sDisplayName) {
|
||||
if (MetaModel::IsRootClass($sClassName)) {
|
||||
$oLayout->AddSideHtml("<li class=\"open\">".MakeClassHLink($sClassName, $sContext)."\n");
|
||||
$oLayout->AddSideHtml(GetSubclasses($sClassName, $sContext));
|
||||
$oLayout->AddSideHtml("</li>\n");
|
||||
}
|
||||
elseif (MetaModel::IsStandaloneClass($sClassName))
|
||||
{
|
||||
} elseif (MetaModel::IsStandaloneClass($sClassName)) {
|
||||
$oLayout->AddSideHtml("<li>".MakeClassHLink($sClassName, $sContext)."</li>\n");
|
||||
}
|
||||
}
|
||||
@@ -480,8 +432,9 @@ JS
|
||||
$oPage->add_ready_script('$("#ibo-datamodel-viewer--classes-list--list").treeview();');
|
||||
}
|
||||
|
||||
function Label_sort($building_a, $building_b) {
|
||||
return strnatcmp ($building_a["label"], $building_b["label"]);
|
||||
function Label_sort($building_a, $building_b)
|
||||
{
|
||||
return strnatcmp($building_a["label"], $building_b["label"]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -489,29 +442,23 @@ function Label_sort($building_a, $building_b) {
|
||||
*/
|
||||
function DisplayRelatedClassesGraph($oPage, $sClass)
|
||||
{
|
||||
try
|
||||
{
|
||||
try {
|
||||
$bOnTheLeft = true;
|
||||
$bSkipLinkingClasses = false;
|
||||
// 1) Fetching referencing classes data
|
||||
//
|
||||
$aData = array();
|
||||
$aOrigins = array('_' => true);
|
||||
$aData = [];
|
||||
$aOrigins = ['_' => true];
|
||||
$aRefs = MetaModel::EnumReferencingClasses($sClass, $bSkipLinkingClasses);
|
||||
$sSelfReference = "false";
|
||||
if (count($aRefs) != 0)
|
||||
{
|
||||
foreach ($aRefs as $sRemoteClass => $aRemoteKeys)
|
||||
{
|
||||
foreach ($aRemoteKeys as $sExtKeyAttCode => $oExtKeyAttDef)
|
||||
{
|
||||
if ($sRemoteClass != $sClass)
|
||||
{
|
||||
if (count($aRefs) != 0) {
|
||||
foreach ($aRefs as $sRemoteClass => $aRemoteKeys) {
|
||||
foreach ($aRemoteKeys as $sExtKeyAttCode => $oExtKeyAttDef) {
|
||||
if ($sRemoteClass != $sClass) {
|
||||
// ref_prefix to avoid collision between attributes labels that refer to this class and local attributes label that references other classes
|
||||
$aAttribute = array('label' => 'ref_'.$sExtKeyAttCode);
|
||||
$aAttribute = ['label' => 'ref_'.$sExtKeyAttCode];
|
||||
// Test if a distant attribut exists and if it uses a link class
|
||||
if (!($oExtKeyAttDef->GetMirrorLinkAttribute() == null ? false : $oExtKeyAttDef->GetMirrorLinkAttribute() instanceof AttributeLinkedSetIndirect))
|
||||
{
|
||||
if (!($oExtKeyAttDef->GetMirrorLinkAttribute() == null ? false : $oExtKeyAttDef->GetMirrorLinkAttribute() instanceof AttributeLinkedSetIndirect)) {
|
||||
$aAttribute['related'] = $sRemoteClass;
|
||||
$aAttribute['related_icon'] = MetaModel::GetClassIcon($aAttribute['related'], false);
|
||||
$aAttribute['related_position'] = $bOnTheLeft ? -1 : 1;
|
||||
@@ -529,24 +476,21 @@ function DisplayRelatedClassesGraph($oPage, $sClass)
|
||||
|
||||
// 2) Fetching referenced classes data
|
||||
//
|
||||
$aDataRef = array(
|
||||
array(
|
||||
$aDataRef = [
|
||||
[
|
||||
'label' => $sClass,
|
||||
'icon' => MetaModel::GetClassIcon($sClass, false),
|
||||
'origin_index' => 0,
|
||||
'alphabetical_index' => 0,
|
||||
'origin' => '_',
|
||||
),
|
||||
);
|
||||
],
|
||||
];
|
||||
$bOnTheLeft = true;
|
||||
$aOriginsRef = array('_' => true);
|
||||
foreach (MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef)
|
||||
{
|
||||
$aAttribute = array('label' => $sAttCode);
|
||||
if ($oAttDef->IsLinkSet())
|
||||
{
|
||||
if ($oAttDef->IsIndirect())
|
||||
{
|
||||
$aOriginsRef = ['_' => true];
|
||||
foreach (MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef) {
|
||||
$aAttribute = ['label' => $sAttCode];
|
||||
if ($oAttDef->IsLinkSet()) {
|
||||
if ($oAttDef->IsIndirect()) {
|
||||
$sRemoteAttDef = $oAttDef->GetExtKeyToRemote();
|
||||
$aAttribute['related'] = MetaModel::GetAttributeDef($oAttDef->GetLinkedClass(), $sRemoteAttDef)->GetTargetClass();
|
||||
$aAttribute['related_icon'] = MetaModel::GetClassIcon($aAttribute['related'], false);
|
||||
@@ -557,9 +501,7 @@ function DisplayRelatedClassesGraph($oPage, $sClass)
|
||||
$aAttribute['tooltip_data']['to_me'] = $oAttDef->GetExtKeyToMe();
|
||||
|
||||
$bOnTheLeft = !$bOnTheLeft; // Toggle the side
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$aAttribute['related'] = $oAttDef->GetLinkedClass();
|
||||
$aAttribute['related_icon'] = MetaModel::GetClassIcon($aAttribute['related'], false);
|
||||
$aAttribute['related_position'] = $bOnTheLeft ? 1 : -1;
|
||||
@@ -567,22 +509,16 @@ function DisplayRelatedClassesGraph($oPage, $sClass)
|
||||
$bOnTheLeft = !$bOnTheLeft; // Toggle the side
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($oAttDef->IsHierarchicalKey())
|
||||
{
|
||||
} else {
|
||||
if ($oAttDef->IsHierarchicalKey()) {
|
||||
$aAttribute['related'] = $sClass;
|
||||
$aAttribute['related_icon'] = MetaModel::GetClassIcon($aAttribute['related'], false);
|
||||
$aAttribute['related_position'] = $bOnTheLeft ? 1 : -1;
|
||||
$aAttribute['relation_type'] = 2;
|
||||
$bOnTheLeft = !$bOnTheLeft; // Toggle the side
|
||||
$sSelfReference = "true";
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($oAttDef->IsExternalKey())
|
||||
{
|
||||
} else {
|
||||
if ($oAttDef->IsExternalKey()) {
|
||||
$aAttribute['related'] = $oAttDef->GetTargetClass();
|
||||
$aAttribute['related_icon'] = MetaModel::GetClassIcon($aAttribute['related'], false);
|
||||
$aAttribute['related_position'] = $bOnTheLeft ? 1 : -1;
|
||||
@@ -592,8 +528,7 @@ function DisplayRelatedClassesGraph($oPage, $sClass)
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($oAttDef->IsLinkSet() || $oAttDef->IsHierarchicalKey() || $oAttDef->IsExternalKey())
|
||||
{
|
||||
if ($oAttDef->IsLinkSet() || $oAttDef->IsHierarchicalKey() || $oAttDef->IsExternalKey()) {
|
||||
$sOrigin = MetaModel::GetAttributeOrigin($sClass, $sAttCode);
|
||||
|
||||
$aAttribute['origin'] = $sOrigin;
|
||||
@@ -604,39 +539,31 @@ function DisplayRelatedClassesGraph($oPage, $sClass)
|
||||
|
||||
}
|
||||
|
||||
|
||||
//sort referencing data
|
||||
|
||||
$aOrigins = array_keys($aOrigins);
|
||||
$idx = 0;
|
||||
|
||||
$bOnTheLeft = true;
|
||||
foreach ($aData as $sAttCode => $aAttribute)
|
||||
{
|
||||
foreach ($aData as $sAttCode => $aAttribute) {
|
||||
$is_also_referenced = false;
|
||||
foreach ($aDataRef as $sAttCodeRef => $aAttributeRef)
|
||||
{
|
||||
if (!empty($aDataRef[$sAttCodeRef]['related']) && ($aData[$sAttCode]['related'] == $aDataRef[$sAttCodeRef]['related']))
|
||||
{
|
||||
foreach ($aDataRef as $sAttCodeRef => $aAttributeRef) {
|
||||
if (!empty($aDataRef[$sAttCodeRef]['related']) && ($aData[$sAttCode]['related'] == $aDataRef[$sAttCodeRef]['related'])) {
|
||||
$is_also_referenced = true;
|
||||
}
|
||||
}
|
||||
if (!$is_also_referenced)
|
||||
{
|
||||
if (!$is_also_referenced) {
|
||||
$aData[$sAttCode]['related_position'] = ($bOnTheLeft) ? -1 : 1;
|
||||
$bOnTheLeft = !$bOnTheLeft;
|
||||
$aData[$sAttCode]['origin_index'] = ($aData[$sAttCode]['related_position'] == -1) ? ++$idx : $idx;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
unset($aData[$sAttCode]);
|
||||
}
|
||||
}
|
||||
ksort($aData);
|
||||
$idx = 0;
|
||||
$aFinalDataReferencing = array();
|
||||
foreach ($aData as $sAttCode => $aAttribute)
|
||||
{
|
||||
$aFinalDataReferencing = [];
|
||||
foreach ($aData as $sAttCode => $aAttribute) {
|
||||
$aData[$sAttCode]['alphabetical_index'] = $aAttribute['related_position'] == 1 ? ++$idx : $idx;
|
||||
$aFinalDataReferencing[] = $aData[$sAttCode];
|
||||
}
|
||||
@@ -646,15 +573,13 @@ function DisplayRelatedClassesGraph($oPage, $sClass)
|
||||
//sort referenced data
|
||||
|
||||
$idx = 1;
|
||||
foreach ($aDataRef as $sAttCode => $aAttribute)
|
||||
{
|
||||
foreach ($aDataRef as $sAttCode => $aAttribute) {
|
||||
$aDataRef[$sAttCode]['origin_index'] = $idx++;
|
||||
}
|
||||
|
||||
$idx = 1;
|
||||
$aFinalData = array();
|
||||
foreach ($aDataRef as $sAttCode => $aAttribute)
|
||||
{
|
||||
$aFinalData = [];
|
||||
foreach ($aDataRef as $sAttCode => $aAttribute) {
|
||||
$aDataRef[$sAttCode]['alphabetical_index'] = $idx++;
|
||||
$aFinalData[] = $aDataRef[$sAttCode];
|
||||
}
|
||||
@@ -960,9 +885,7 @@ if(window.IntersectionObserver) {
|
||||
}
|
||||
JS
|
||||
);
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
} catch (Exception $e) {
|
||||
$oPage->p('<b>'.Dict::Format('UI:RunQuery:Error', $e->getMessage()).'</b>');
|
||||
}
|
||||
}
|
||||
@@ -978,9 +901,8 @@ JS
|
||||
*/
|
||||
function DisplayClassDetails($oPage, $sClass, $sContext)
|
||||
{
|
||||
$aParentClasses = array();
|
||||
foreach (MetaModel::EnumParentClasses($sClass) as $sParentClass)
|
||||
{
|
||||
$aParentClasses = [];
|
||||
foreach (MetaModel::EnumParentClasses($sClass) as $sParentClass) {
|
||||
$aParentClasses[] = MakeClassHLink($sParentClass, $sContext);
|
||||
}
|
||||
if (count($aParentClasses) > 0) {
|
||||
@@ -1004,9 +926,9 @@ function DisplayClassDetails($oPage, $sClass, $sContext)
|
||||
$oPage->SetCurrentTabContainer('details');
|
||||
// List the attributes of the object
|
||||
$aForwardChangeTracking = MetaModel::GetTrackForwardExternalKeys($sClass);
|
||||
$aDetails = array();
|
||||
$aDetails = [];
|
||||
|
||||
$aOrigins = array();
|
||||
$aOrigins = [];
|
||||
foreach (MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef) {
|
||||
if ($oAttDef->IsExternalKey()) {
|
||||
$sValue = Dict::Format('UI:Schema:ExternalKey_To', MakeClassHLink($oAttDef->GetTargetClass(), $sContext));
|
||||
@@ -1017,9 +939,7 @@ function DisplayClassDetails($oPage, $sClass, $sContext)
|
||||
}
|
||||
} elseif ($oAttDef->IsLinkSet()) {
|
||||
$sValue = MakeClassHLink($oAttDef->GetLinkedClass(), $sContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$sValue = $oAttDef->GetDescription();
|
||||
}
|
||||
$sType = get_class($oAttDef);
|
||||
@@ -1031,30 +951,25 @@ function DisplayClassDetails($oPage, $sClass, $sContext)
|
||||
$sAllowedValues = "";
|
||||
$sMoreInfo = "";
|
||||
$sDefaultNullValue = '';
|
||||
if (call_user_func(array(get_class($oAttDef), 'IsBasedOnDBColumns')))
|
||||
{
|
||||
if (call_user_func([get_class($oAttDef), 'IsBasedOnDBColumns'])) {
|
||||
|
||||
$aMoreInfo = array();
|
||||
if ($oAttDef->IsNullAllowed())
|
||||
{
|
||||
$aMoreInfo = [];
|
||||
if ($oAttDef->IsNullAllowed()) {
|
||||
$aMoreInfo[] = Dict::S('UI:Schema:NullAllowed');
|
||||
$sDefaultNullValue = (!is_null($oAttDef->GetNullValue()) ? $oAttDef->GetNullValue() : null);
|
||||
if (!is_null($sDefaultNullValue) && !is_string($sDefaultNullValue))
|
||||
{
|
||||
if (!is_null($sDefaultNullValue) && !is_string($sDefaultNullValue)) {
|
||||
$sDefaultNullValue = json_encode($sDefaultNullValue);
|
||||
}
|
||||
$sDefaultNullValue = (!is_null($sDefaultNullValue) ? Dict::Format('UI:Schema:DefaultNullValue',
|
||||
$sDefaultNullValue) : '');
|
||||
}
|
||||
else
|
||||
{
|
||||
$sDefaultNullValue = (!is_null($sDefaultNullValue) ? Dict::Format(
|
||||
'UI:Schema:DefaultNullValue',
|
||||
$sDefaultNullValue
|
||||
) : '');
|
||||
} else {
|
||||
$aMoreInfo[] = Dict::S('UI:Schema:NullNotAllowed');
|
||||
}
|
||||
if ($oAttDef->GetDefaultValue())
|
||||
{
|
||||
if ($oAttDef->GetDefaultValue()) {
|
||||
$sDefaultValue = $oAttDef->GetDefaultValue();
|
||||
if (!is_string($sDefaultValue))
|
||||
{
|
||||
if (!is_string($sDefaultValue)) {
|
||||
$sDefaultValue = json_encode($sDefaultValue);
|
||||
}
|
||||
$aMoreInfo[] = Dict::Format("UI:Schema:Default_Description", $sDefaultValue);
|
||||
@@ -1064,28 +979,22 @@ function DisplayClassDetails($oPage, $sClass, $sContext)
|
||||
$sAttrCode = $oAttDef->GetCode();
|
||||
$sIsEnumValues = 'false';
|
||||
$sAllowedValuesEscpd = '""';
|
||||
if ($oAttDef instanceof AttributeEnum)
|
||||
{
|
||||
if ($oAttDef instanceof AttributeEnum) {
|
||||
// Display localized values for the enum (which depend on the localization provided by the class)
|
||||
$aLocalizedValues = MetaModel::GetAllowedValues_att($sClass, $sAttCode, array());
|
||||
$aDescription = array();
|
||||
foreach ($aLocalizedValues as $val => $sDisplay)
|
||||
{
|
||||
$aLocalizedValues = MetaModel::GetAllowedValues_att($sClass, $sAttCode, []);
|
||||
$aDescription = [];
|
||||
foreach ($aLocalizedValues as $val => $sDisplay) {
|
||||
$aDescription[] = $sDisplay." (".$val.")";
|
||||
}
|
||||
$sAllowedValues = implode(', ', $aDescription);
|
||||
$sIsEnumValues = 'true';
|
||||
}
|
||||
elseif (is_object($oAllowedValuesDef = $oAttDef->GetValuesDef()))
|
||||
{
|
||||
} elseif (is_object($oAllowedValuesDef = $oAttDef->GetValuesDef())) {
|
||||
$sAllowedValues = str_replace("Filter: ", "", $oAllowedValuesDef->GetValuesDescription());
|
||||
$sAllowedValuesEscpd = utils::HtmlEntities($sAllowedValues);
|
||||
|
||||
$sFilterURL = urlencode($sAllowedValues);
|
||||
$sAllowedValues = '<span id="values'.$sAttrCode.'" data-tooltip-content="'.$sAllowedValuesEscpd.'"><a href="run_query.php?expression='.$sFilterURL.'" class="fas fa-search"></a> '.Dict::S('UI:Schema:Attribute/Filter')."</span>";
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$sAllowedValues = '';
|
||||
}
|
||||
$sAttrValueEscpd = utils::HtmlEntities($sValue);
|
||||
@@ -1093,29 +1002,29 @@ function DisplayClassDetails($oPage, $sClass, $sContext)
|
||||
$sAttrOriginEscpd = utils::HtmlEntities($sOrigin);
|
||||
$sDefaultNullValueEscpd = utils::HtmlEntities($sDefaultNullValue);
|
||||
|
||||
$aDetails[] = array(
|
||||
$aDetails[] = [
|
||||
'code' => '<span id="attr'.$sAttrCode.'" data-tooltip-content="'.$sAttrValueEscpd.'" data-tooltip-html-enabled="true">'.$oAttDef->GetLabel().' ('.$oAttDef->GetCode().')</span>',
|
||||
'type' => '<span id="type'.$sAttrCode.'" data-tooltip-content="'.$sAttrTypeDescEscpd.'">'.$sTypeDict.' ('.$sType.')</span>',
|
||||
'origincolor' => '<div class="originColor'.$sOrigin.'" data-tooltip-content="'.$sAttrOriginEscpd.'"></div>',
|
||||
'origin' => "<span id=\"origin".$sAttrCode."\">$sOrigin</span>",
|
||||
'values' => $sAllowedValues,
|
||||
'moreinfo' => '<span id="moreinfo'.$sAttrCode.'" data-tooltip-content="'.$sDefaultNullValueEscpd.'">'.$sMoreInfo.'</span>',
|
||||
);
|
||||
];
|
||||
|
||||
}
|
||||
$oPage->SetCurrentTab('UI:Schema:Attributes');
|
||||
$aConfig = array(
|
||||
'origincolor' => array('label' => "", 'description' => ""),
|
||||
'code' => array('label' => Dict::S('UI:Schema:AttributeCode'), 'description' => Dict::S('UI:Schema:AttributeCode+')),
|
||||
'type' => array('label' => Dict::S('UI:Schema:Type'), 'description' => Dict::S('UI:Schema:Type+')),
|
||||
'values' => array('label' => Dict::S('UI:Schema:AllowedValues'), 'description' => Dict::S('UI:Schema:AllowedValues+')),
|
||||
'moreinfo' => array('label' => Dict::S('UI:Schema:MoreInfo'), 'description' => Dict::S('UI:Schema:MoreInfo+')),
|
||||
'origin' => array('label' => Dict::S('UI:Schema:Origin'), 'description' => Dict::S('UI:Schema:Origin+')),
|
||||
);
|
||||
$aConfig = [
|
||||
'origincolor' => ['label' => "", 'description' => ""],
|
||||
'code' => ['label' => Dict::S('UI:Schema:AttributeCode'), 'description' => Dict::S('UI:Schema:AttributeCode+')],
|
||||
'type' => ['label' => Dict::S('UI:Schema:Type'), 'description' => Dict::S('UI:Schema:Type+')],
|
||||
'values' => ['label' => Dict::S('UI:Schema:AllowedValues'), 'description' => Dict::S('UI:Schema:AllowedValues+')],
|
||||
'moreinfo' => ['label' => Dict::S('UI:Schema:MoreInfo'), 'description' => Dict::S('UI:Schema:MoreInfo+')],
|
||||
'origin' => ['label' => Dict::S('UI:Schema:Origin'), 'description' => Dict::S('UI:Schema:Origin+')],
|
||||
];
|
||||
$oTablePanel = PanelUIBlockFactory::MakeForClass($sClass, '');
|
||||
$oTablePanel->AddCSSClass('ibo-datatable-panel');
|
||||
|
||||
$oAttributesTable = DataTableUIBlockFactory::MakeForStaticData('', $aConfig, $aDetails, 'ibo-datamodel-viewer--attributes-table', [], "", array('pageLength' => -1));
|
||||
$oAttributesTable = DataTableUIBlockFactory::MakeForStaticData('', $aConfig, $aDetails, 'ibo-datamodel-viewer--attributes-table', [], "", ['pageLength' => -1]);
|
||||
$oTablePanel->AddSubBlock($oAttributesTable);
|
||||
$oPage->AddUiBlock($oTablePanel);
|
||||
$sOrigins = json_encode(array_keys($aOrigins));
|
||||
@@ -1140,9 +1049,8 @@ EOF
|
||||
|
||||
$oPage->SetCurrentTab('UI:Schema:RelatedClasses');
|
||||
DisplayRelatedClassesGraph($oPage, $sClass);
|
||||
|
||||
if (MetaModel::HasChildrenClasses($sClass))
|
||||
{
|
||||
|
||||
if (MetaModel::HasChildrenClasses($sClass)) {
|
||||
$oPage->SetCurrentTab('UI:Schema:ChildClasses');
|
||||
$oPage->add("<ul id=\"ClassHierarchy\">");
|
||||
$oPage->add("<li class=\"closed\">".$sClass."\n");
|
||||
@@ -1151,7 +1059,7 @@ EOF
|
||||
$oPage->add("</ul>\n");
|
||||
$oPage->add_ready_script('$("#ClassHierarchy").treeview({collapsed: false,});');
|
||||
}
|
||||
|
||||
|
||||
$oPage->SetCurrentTab('UI:Schema:LifeCycle');
|
||||
DisplayLifecycle($oPage, $sClass);
|
||||
|
||||
@@ -1165,14 +1073,12 @@ EOF
|
||||
$oPage->SetCurrentTabContainer();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// MAIN BLOCK //
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Display the menu on the left
|
||||
|
||||
|
||||
$oAppContext = new ApplicationContext();
|
||||
$sContext = $oAppContext->GetForLink(true);
|
||||
$operation = utils::ReadParam('operation', '');
|
||||
@@ -1184,8 +1090,14 @@ $oPage->SetContentLayout($oLayout);
|
||||
|
||||
$oPage->no_cache();
|
||||
|
||||
$oPage->SetBreadCrumbEntry('ui-tool-datamodel', Dict::S('Menu:DataModelMenu'), Dict::S('Menu:DataModelMenu+'), '',
|
||||
'fas fa-book', iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES);
|
||||
$oPage->SetBreadCrumbEntry(
|
||||
'ui-tool-datamodel',
|
||||
Dict::S('Menu:DataModelMenu'),
|
||||
Dict::S('Menu:DataModelMenu+'),
|
||||
'',
|
||||
'fas fa-book',
|
||||
iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES
|
||||
);
|
||||
|
||||
$oTitle = TitleUIBlockFactory::MakeForPage(Dict::S('UI:Schema:Title'));
|
||||
$oPage->AddUiBlock($oTitle);
|
||||
@@ -1195,17 +1107,16 @@ $oLayout->AddSideHtml("</div>");
|
||||
$oPage->add("<div id='ibo-datamodel-viewer'>");
|
||||
$oPage->add("<div class='ibo-datamodel-viewer--details'>");
|
||||
|
||||
switch ($operation)
|
||||
{
|
||||
switch ($operation) {
|
||||
case 'details_class':
|
||||
$sClass = utils::ReadParam('class', '', false, 'class');
|
||||
//if we want to see class details & class is given then display it, otherwise act default (just show the class list)
|
||||
if ($sClass != '')
|
||||
{
|
||||
if ($sClass != '') {
|
||||
$oPage->set_title(Dict::Format('UI:Schema:TitleForClass', $sClass));
|
||||
DisplayClassDetails($oPage, $sClass, $sContext);
|
||||
break;
|
||||
}
|
||||
// no break
|
||||
default:
|
||||
}
|
||||
$oPage->add("</div>");
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
@@ -26,8 +27,7 @@ require_once(APPROOT.'application/startup.inc.php');
|
||||
require_once(APPROOT.'application/loginwebpage.class.inc.php');
|
||||
IssueLog::Trace('----- Request: '.utils::GetRequestUri(), LogChannels::WEB_REQUEST);
|
||||
|
||||
try
|
||||
{
|
||||
try {
|
||||
LoginWebPage::DoLogin();
|
||||
// Check user rights and prompt if needed
|
||||
ApplicationMenu::CheckMenuIdEnabled("TagAdminMenu");
|
||||
@@ -56,16 +56,13 @@ try
|
||||
$oP->SetBreadCrumbEntry('ui-tool-tag-admin', Dict::S('Menu:TagAdminMenu'), Dict::S('Menu:TagAdminMenu+'), '', 'fas fa-tags', iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES);
|
||||
|
||||
$sSearchHeaderForceDropdown = '<select id="select_class" name="class" onChange="this.form.submit();">';
|
||||
$aClassLabels = array();
|
||||
foreach(MetaModel::EnumChildClasses($sBaseClass, ENUM_CHILD_CLASSES_EXCLUDETOP) as $sCurrentClass)
|
||||
{
|
||||
$aClassLabels = [];
|
||||
foreach (MetaModel::EnumChildClasses($sBaseClass, ENUM_CHILD_CLASSES_EXCLUDETOP) as $sCurrentClass) {
|
||||
$aClassLabels[$sCurrentClass] = MetaModel::GetName($sCurrentClass);
|
||||
}
|
||||
asort($aClassLabels);
|
||||
foreach($aClassLabels as $sCurrentClass => $sLabel)
|
||||
{
|
||||
if (empty($sClass))
|
||||
{
|
||||
foreach ($aClassLabels as $sCurrentClass => $sLabel) {
|
||||
if (empty($sClass)) {
|
||||
$sClass = $sCurrentClass;
|
||||
}
|
||||
$sSelected = ($sCurrentClass == $sClass) ? " SELECTED" : "";
|
||||
@@ -73,34 +70,24 @@ try
|
||||
}
|
||||
$sSearchHeaderForceDropdown .= "</select>\n";
|
||||
|
||||
try
|
||||
{
|
||||
if ($sOperation == 'search_form')
|
||||
{
|
||||
try {
|
||||
if ($sOperation == 'search_form') {
|
||||
$sOQL = "SELECT $sClass $sOQLClause";
|
||||
$oFilter = DBObjectSearch::FromOQL($sOQL);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// Second part: advanced search form:
|
||||
if (!empty($sFilter))
|
||||
{
|
||||
if (!empty($sFilter)) {
|
||||
$oFilter = DBSearch::unserialize($sFilter);
|
||||
}
|
||||
else if (!empty($sClass))
|
||||
{
|
||||
} elseif (!empty($sClass)) {
|
||||
$oFilter = new DBObjectSearch($sClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (CoreException $e)
|
||||
{
|
||||
} catch (CoreException $e) {
|
||||
$oFilter = new DBObjectSearch($sClass);
|
||||
$oP->P("<b>".Dict::Format('UI:TagSetFieldData:Error', $e->getHtmlDesc())."</b>");
|
||||
}
|
||||
|
||||
if (!empty($oFilter))
|
||||
{
|
||||
if (!empty($oFilter)) {
|
||||
$oSearchContext = new ContextTag(ContextTag::TAG_OBJECT_SEARCH);
|
||||
|
||||
$oSet = new CMDBObjectSet($oFilter);
|
||||
@@ -121,9 +108,7 @@ try
|
||||
// Menu node
|
||||
$sFilter = $oFilter->ToOQL();
|
||||
$oP->add("\n<!-- $sFilter -->\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$oP->add("<p>");
|
||||
$oP->add(Dict::S('UI:TagAdminMenu:NoTags'));
|
||||
$oP->add("</p>");
|
||||
@@ -131,9 +116,7 @@ try
|
||||
$oP->add("</div>\n");
|
||||
|
||||
$oP->output();
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
} catch (Exception $e) {
|
||||
require_once(APPROOT.'setup/setuppage.class.inc.php');
|
||||
|
||||
$oP = new ErrorPage(Dict::S('UI:PageTitle:FatalError'));
|
||||
|
||||
Reference in New Issue
Block a user