Merge remote-tracking branch 'origin/support/2.7' into support/3.0

# Conflicts:
#	pages/audit.php
This commit is contained in:
Anne-Cath
2024-02-29 16:50:04 +01:00
4 changed files with 178 additions and 23 deletions

View File

@@ -885,11 +885,11 @@ abstract class DBSearch
return; return;
} }
if (count($aColumns) == 0) if (count($aColumns) == 0)
{ {
$aColumns = array_keys(MetaModel::ListAttributeDefs($this->GetClass())); $aColumns = array_keys(MetaModel::ListAttributeDefs($this->GetClass()));
// Add the standard id (as first column) // Add the standard id (as first column)
array_unshift($aColumns, 'id'); array_unshift($aColumns, 'id');
} }
$aQueryCols = CMDBSource::GetColumns($resQuery, $sSQL); $aQueryCols = CMDBSource::GetColumns($resQuery, $sSQL);
@@ -919,6 +919,55 @@ abstract class DBSearch
return $aRes; return $aRes;
} }
/**
* Selects a column ($sAttCode) from the specified class ($sClassAlias - default main class) of the DBsearch object and gives the result as an array
* @param string $sAttCode
* @param string|null $sClassAlias
*
* @return array
* @throws ConfigException
* @throws CoreException
* @throws MissingQueryArgument
* @throws MySQLException
* @throws MySQLHasGoneAwayException
*/
public function SelectAttributeToArray(string $sAttCode, ?string $sClassAlias = null):array
{
if(is_null($sClassAlias)) {
$sClassAlias = $this->GetClassAlias();
}
$sClass = $this->GetClass();
if($sAttCode === 'id'){
$aAttToLoad[$sClassAlias]=[];
} else {
$aAttToLoad[$sClassAlias][$sAttCode] = MetaModel::GetAttributeDef($sClass, $sAttCode);
}
$sSQL = $this->MakeSelectQuery([], [], $aAttToLoad);
$resQuery = CMDBSource::Query($sSQL);
if (!$resQuery)
{
return [];
}
$sColName = $sClassAlias.$sAttCode;
$aRes = [];
while ($aRow = CMDBSource::FetchArray($resQuery))
{
$aMappedRow = array();
if($sAttCode === 'id') {
$aMappedRow[$sAttCode] = $aRow[$sColName];
} else {
$aMappedRow[$sAttCode] = $aAttToLoad[$sClassAlias][$sAttCode]->FromSQLToValue($aRow, $sColName);
}
$aRes[] = $aMappedRow;
}
CMDBSource::FreeResult($resQuery);
return $aRes;
}
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// //
// Construction of the SQL queries // Construction of the SQL queries

View File

@@ -161,7 +161,7 @@ abstract class UserRightsAddOnAPI
$oSearchSharers->AllowAllData(); $oSearchSharers->AllowAllData();
$oSearchSharers->AddCondition_ReferencedBy($oShareSearch, 'sharing_org_id'); $oSearchSharers->AddCondition_ReferencedBy($oShareSearch, 'sharing_org_id');
$aSharers = array(); $aSharers = array();
foreach($oSearchSharers->ToDataArray(array('id')) as $aRow) foreach($oSearchSharers->SelectAttributeToArray('id') as $aRow)
{ {
$aSharers[] = $aRow['id']; $aSharers[] = $aRow['id'];
} }
@@ -186,7 +186,7 @@ abstract class UserRightsAddOnAPI
$oOrgField = new FieldExpression('org_id', $sShareClass); $oOrgField = new FieldExpression('org_id', $sShareClass);
$oSearchShares->AddConditionExpression(new BinaryExpression($oOrgField, 'IN', $oListExpr)); $oSearchShares->AddConditionExpression(new BinaryExpression($oOrgField, 'IN', $oListExpr));
$aShared = array(); $aShared = array();
foreach($oSearchShares->ToDataArray(array($sShareAttCode)) as $aRow) foreach($oSearchShares->SelectAttributeToArray($sShareAttCode) as $aRow)
{ {
$aShared[] = $aRow[$sShareAttCode]; $aShared[] = $aRow[$sShareAttCode];
} }

View File

@@ -1,6 +1,6 @@
<?php <?php
/* /*
* @copyright Copyright (C) 2010-2021 Combodo SARL * @copyright Copyright (C) 2010-2023 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0 * @license http://opensource.org/licenses/AGPL-3.0
*/ */
@@ -110,7 +110,7 @@ function GetRuleResultFilter($iRuleId, $oDefinitionFilter, $oAppContext)
{ {
// The query returns only the valid elements, all the others are invalid // 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 ! // 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')); $aValidRows = $oRuleFilter->ToDataArray(array('id'));
$aValidIds = array(); $aValidIds = array();
foreach($aValidRows as $aRow) foreach($aValidRows as $aRow)
{ {
@@ -159,7 +159,7 @@ try
require_once(APPROOT.'/application/application.inc.php'); require_once(APPROOT.'/application/application.inc.php');
require_once(APPROOT.'/application/itopwebpage.class.inc.php'); require_once(APPROOT.'/application/itopwebpage.class.inc.php');
require_once(APPROOT.'/application/startup.inc.php'); require_once(APPROOT.'/application/startup.inc.php');
$operation = utils::ReadParam('operation', ''); $operation = utils::ReadParam('operation', '');
$oAppContext = new ApplicationContext(); $oAppContext = new ApplicationContext();
@@ -291,11 +291,11 @@ try
$oDashboardColumnTotal = new DashboardColumn(false, true); $oDashboardColumnTotal = new DashboardColumn(false, true);
$oDashboardColumnError = new DashboardColumn(false, true); $oDashboardColumnError = new DashboardColumn(false, true);
$oDashboardColumnWorking = new DashboardColumn(false, true); $oDashboardColumnWorking = new DashboardColumn(false, true);
$oDashboardColumnTotal->AddUIBlock($oDashletContainerTotal); $oDashboardColumnTotal->AddUIBlock($oDashletContainerTotal);
$oDashboardColumnError->AddUIBlock($oDashletContainerError); $oDashboardColumnError->AddUIBlock($oDashletContainerError);
$oDashboardColumnWorking->AddUIBlock($oDashletContainerWorking); $oDashboardColumnWorking->AddUIBlock($oDashletContainerWorking);
$oDashboardRow->AddDashboardColumn($oDashboardColumnTotal); $oDashboardRow->AddDashboardColumn($oDashboardColumnTotal);
$oDashboardRow->AddDashboardColumn($oDashboardColumnError); $oDashboardRow->AddDashboardColumn($oDashboardColumnError);
$oDashboardRow->AddDashboardColumn($oDashboardColumnWorking); $oDashboardRow->AddDashboardColumn($oDashboardColumnWorking);
@@ -306,7 +306,7 @@ try
$oAuditFilter = new DBObjectSearch('AuditCategory'); $oAuditFilter = new DBObjectSearch('AuditCategory');
$oCategoriesSet = new DBObjectSet($oAuditFilter); $oCategoriesSet = new DBObjectSet($oAuditFilter);
$aAuditCategoryPanels = []; $aAuditCategoryPanels = [];
while($oAuditCategory = $oCategoriesSet->fetch()) while($oAuditCategory = $oCategoriesSet->fetch())
{ {
@@ -319,7 +319,7 @@ try
$oDefinitionFilter = DBObjectSearch::FromOQL($oAuditCategory->Get('definition_set')); $oDefinitionFilter = DBObjectSearch::FromOQL($oAuditCategory->Get('definition_set'));
$oDefinitionFilter->UpdateContextFromUser(); $oDefinitionFilter->UpdateContextFromUser();
FilterByContext($oDefinitionFilter, $oAppContext); FilterByContext($oDefinitionFilter, $oAppContext);
$aObjectsWithErrors = array(); $aObjectsWithErrors = array();
if (!empty($currentOrganization)) if (!empty($currentOrganization))
{ {
@@ -340,7 +340,7 @@ try
if ($iCount == 0) if ($iCount == 0)
{ {
// nothing to check, really ! // nothing to check, really !
$aRow['nb_errors'] = "<a href=\"audit.php?operation=errors&category=".$oAuditCategory->GetKey()."&rule=".$oAuditRule->GetKey()."\">0</a>"; $aRow['nb_errors'] = "<a href=\"audit.php?operation=errors&category=".$oAuditCategory->GetKey()."&rule=".$oAuditRule->GetKey()."\">0</a>";
$aRow['percent_ok'] = '100.00'; $aRow['percent_ok'] = '100.00';
$aRow['class'] = GetReportColor($iCount, 0); $aRow['class'] = GetReportColor($iCount, 0);
} }
@@ -349,19 +349,19 @@ try
try try
{ {
$oFilter = GetRuleResultFilter($oAuditRule->GetKey(), $oDefinitionFilter, $oAppContext); $oFilter = GetRuleResultFilter($oAuditRule->GetKey(), $oDefinitionFilter, $oAppContext);
$aErrors = $oFilter->ToDataArray(array('id')); $aErrors = $oFilter->SelectAttributeToArray('id');
$iErrorsCount = count($aErrors); $iErrorsCount = count($aErrors);
foreach($aErrors as $aErrorRow) foreach($aErrors as $aErrorRow)
{ {
$aObjectsWithErrors[$aErrorRow['id']] = true; $aObjectsWithErrors[$aErrorRow['id']] = true;
} }
$aRow['nb_errors'] = ($iErrorsCount == 0) ? '0' : "<a href=\"?operation=errors&category=".$oAuditCategory->GetKey()."&rule=".$oAuditRule->GetKey()."&".$oAppContext->GetForLink()."\">$iErrorsCount</a> <a href=\"?operation=csv&category=".$oAuditCategory->GetKey()."&rule=".$oAuditRule->GetKey()."&".$oAppContext->GetForLink()."\"><img src=\"../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()."\">$iErrorsCount</a> <a href=\"?operation=csv&category=".$oAuditCategory->GetKey()."&rule=".$oAuditRule->GetKey()."&".$oAppContext->GetForLink()."\"><img src=\"../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['percent_ok'] = sprintf('%.2f', 100.0 * (($iCount - $iErrorsCount) / $iCount));
$aRow['class'] = GetReportColor($iCount, $iErrorsCount); $aRow['class'] = GetReportColor($iCount, $iErrorsCount);
} }
catch(Exception $e) catch(Exception $e)
{ {
$aRow['nb_errors'] = Dict::S('UI:Audit:OqlError'); $aRow['nb_errors'] = Dict::S('UI:Audit:OqlError');
$aRow['percent_ok'] = Dict::S('UI:Audit:Error:ValueNA'); $aRow['percent_ok'] = Dict::S('UI:Audit:Error:ValueNA');
$aRow['class'] = 'red'; $aRow['class'] = 'red';
$sMessage = Dict::Format('UI:Audit:ErrorIn_Rule_Reason', $oAuditRule->GetHyperlink(), $e->getMessage()); $sMessage = Dict::Format('UI:Audit:ErrorIn_Rule_Reason', $oAuditRule->GetHyperlink(), $e->getMessage());
@@ -376,7 +376,7 @@ try
$iTotalErrors = count($aObjectsWithErrors); $iTotalErrors = count($aObjectsWithErrors);
$sOverallPercentOk = ($iCount == 0) ? '100.00' : sprintf('%.2f', 100.0 * (($iCount - $iTotalErrors) / $iCount)); $sOverallPercentOk = ($iCount == 0) ? '100.00' : sprintf('%.2f', 100.0 * (($iCount - $iTotalErrors) / $iCount));
$sClass = GetReportColor($iCount, $iTotalErrors); $sClass = GetReportColor($iCount, $iTotalErrors);
$oTotalBlock->SetCount((int)$oTotalBlock->GetCount() + ($iCount)); $oTotalBlock->SetCount((int)$oTotalBlock->GetCount() + ($iCount));
$oErrorBlock->SetCount((int)$oErrorBlock->GetCount() + $iTotalErrors); $oErrorBlock->SetCount((int)$oErrorBlock->GetCount() + $iTotalErrors);
$oWorkingBlock->SetCount((int)$oWorkingBlock->GetCount() + ($iCount - $iTotalErrors)); $oWorkingBlock->SetCount((int)$oWorkingBlock->GetCount() + ($iCount - $iTotalErrors));
@@ -391,7 +391,7 @@ try
$oP->AddUiBlock($oErrorAlert); $oP->AddUiBlock($oErrorAlert);
continue; continue;
} }
$oAuditCategoryPanelBlock->SetColorFromColorSemantic($sClass); $oAuditCategoryPanelBlock->SetColorFromColorSemantic($sClass);
$oAuditCategoryPanelBlock->AddCSSClass('ibo-audit--audit-category--panel'); $oAuditCategoryPanelBlock->AddCSSClass('ibo-audit--audit-category--panel');
$aData = []; $aData = [];
@@ -410,7 +410,7 @@ try
'nb_err' => array('label' => Dict::S('UI:Audit:HeaderNbErrors'), 'description' => Dict::S('UI:Audit:HeaderNbErrors')), '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')), 'percentage_ok' => array('label' => Dict::S('UI:Audit:PercentageOk'), 'description' => Dict::S('UI:Audit:PercentageOk')),
); );
$oAttachmentTableBlock = DataTableUIBlockFactory::MakeForStaticData('', $aAttribs, $aData, null, [], "", array('pageLength' => -1)); $oAttachmentTableBlock = DataTableUIBlockFactory::MakeForStaticData('', $aAttribs, $aData, null, [], "", array('pageLength' => -1));
$oAuditCategoryPanelBlock->AddSubBlock($oAttachmentTableBlock); $oAuditCategoryPanelBlock->AddSubBlock($oAttachmentTableBlock);
$aAuditCategoryPanels[] = $oAuditCategoryPanelBlock; $aAuditCategoryPanels[] = $oAuditCategoryPanelBlock;

View File

@@ -746,4 +746,110 @@ class DBSearchTest extends ItopDataTestCase
$oSearch->MakeSelectQuery(); $oSearch->MakeSelectQuery();
self::assertTrue(true); self::assertTrue(true);
} }
} /**
* @dataProvider QueriesProvider
* @param $sOQL
*
* @return void
*/
public function testQueries($sOQL)
{
$oSearch = DBSearch::FromOQL($sOQL);
$oSet = new DBObjectSet($oSearch);
if ($oSet->Count() > 0) {
$aSelectedAliases = array_keys($oSearch->GetSelectedClasses());
$aFirstRow = $oSet->FetchAssoc();
$aAliases = array_keys($aFirstRow);
$this->assertEquals($aSelectedAliases, $aAliases);
}
}
public function QueriesProvider()
{
return [
['SELECT L,P FROM Person AS P JOIN Location AS L ON P.location_id=L.id'],
['SELECT P,L FROM Person AS P JOIN Location AS L ON P.location_id=L.id'],
];
}
public function SelectAttributeToArrayProvider()
{
return array(
'select id from FunctionalCI' => array(
'SELECT FunctionalCI',
'id',
),
'select name from FunctionalCI' => array(
'SELECT FunctionalCI',
'name',
),
'select org_id from FunctionalCI' => array(
'SELECT FunctionalCI',
'org_id',
),
'select organization_name from FunctionalCI' => array(
'SELECT FunctionalCI',
'organization_name',
),
'select business_criticity from FunctionalCI' => array(
'SELECT FunctionalCI',
'business_criticity',
),
'select org_id from FunctionalCI' => array(
'SELECT FunctionalCI',
'org_id',
),
'select email from Person' => array(
'SELECT Person',
'email',
),
'select phone from Person' => array(
'SELECT Person',
'phone',
),
'select picture from Person' => array(
'SELECT Person',
'picture',
),
'select description from Ticket' => array(
'SELECT Ticket',
'description',
),
'select start_date from Ticket' => array(
'SELECT Ticket',
'start_date',
),
'select private_log from Ticket' => array(
'SELECT Ticket',
'private_log',
),
);
}
/**
* @dataProvider SelectAttributeToArrayProvider
*
* @return void
* @throws \ConfigException
* @throws \CoreException
* @throws \MissingQueryArgument
* @throws \MySQLException
* @throws \MySQLHasGoneAwayException
* @throws \OQLException
*/
public function testSelectAttributeToArray($sQuery, $sField){
$oSearch = \DBObjectSearch::FromOQL($sQuery);
$aResToDataArray=[];
$oSet = new \DBObjectSet($oSearch);
while ($oRecord = $oSet->Fetch()) {
$aMappedRow[$sField] =$oRecord->Get($sField);
$aResToDataArray[] = $aMappedRow;
}
array_multisort (array_column($aResToDataArray, $sField), SORT_DESC, $aResToDataArray);
$aResSelectColumnToArray = $oSearch->SelectAttributeToArray($sField);
array_multisort (array_column($aResSelectColumnToArray, $sField), SORT_DESC, $aResSelectColumnToArray);
self::assertEquals( $aResToDataArray, $aResSelectColumnToArray, 'The array constructed using the OQL query and the result of testSelectAttributeToArray must be the same');
}
}