mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-24 11:08:45 +02:00
Merge remote-tracking branch 'origin/support/2.7' into support/3.0
# Conflicts: # pages/audit.php
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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');
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user