diff --git a/core/dbsearch.class.php b/core/dbsearch.class.php index 4a26452b8..75450283a 100644 --- a/core/dbsearch.class.php +++ b/core/dbsearch.class.php @@ -885,11 +885,11 @@ abstract class DBSearch return; } - if (count($aColumns) == 0) - { - $aColumns = array_keys(MetaModel::ListAttributeDefs($this->GetClass())); - // Add the standard id (as first column) - array_unshift($aColumns, 'id'); + if (count($aColumns) == 0) + { + $aColumns = array_keys(MetaModel::ListAttributeDefs($this->GetClass())); + // Add the standard id (as first column) + array_unshift($aColumns, 'id'); } $aQueryCols = CMDBSource::GetColumns($resQuery, $sSQL); @@ -919,6 +919,55 @@ abstract class DBSearch 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 diff --git a/core/userrights.class.inc.php b/core/userrights.class.inc.php index c9693c4fa..4ff5b0243 100644 --- a/core/userrights.class.inc.php +++ b/core/userrights.class.inc.php @@ -161,7 +161,7 @@ abstract class UserRightsAddOnAPI $oSearchSharers->AllowAllData(); $oSearchSharers->AddCondition_ReferencedBy($oShareSearch, 'sharing_org_id'); $aSharers = array(); - foreach($oSearchSharers->ToDataArray(array('id')) as $aRow) + foreach($oSearchSharers->SelectAttributeToArray('id') as $aRow) { $aSharers[] = $aRow['id']; } @@ -186,7 +186,7 @@ abstract class UserRightsAddOnAPI $oOrgField = new FieldExpression('org_id', $sShareClass); $oSearchShares->AddConditionExpression(new BinaryExpression($oOrgField, 'IN', $oListExpr)); $aShared = array(); - foreach($oSearchShares->ToDataArray(array($sShareAttCode)) as $aRow) + foreach($oSearchShares->SelectAttributeToArray($sShareAttCode) as $aRow) { $aShared[] = $aRow[$sShareAttCode]; } diff --git a/pages/audit.php b/pages/audit.php index 8a3f9c72a..3f8ef4570 100644 --- a/pages/audit.php +++ b/pages/audit.php @@ -1,6 +1,6 @@ ToDataArray(array('id')); + $aValidRows = $oRuleFilter->ToDataArray(array('id')); $aValidIds = array(); foreach($aValidRows as $aRow) { @@ -159,7 +159,7 @@ try require_once(APPROOT.'/application/application.inc.php'); require_once(APPROOT.'/application/itopwebpage.class.inc.php'); - + require_once(APPROOT.'/application/startup.inc.php'); $operation = utils::ReadParam('operation', ''); $oAppContext = new ApplicationContext(); @@ -291,11 +291,11 @@ try $oDashboardColumnTotal = new DashboardColumn(false, true); $oDashboardColumnError = new DashboardColumn(false, true); $oDashboardColumnWorking = new DashboardColumn(false, true); - + $oDashboardColumnTotal->AddUIBlock($oDashletContainerTotal); $oDashboardColumnError->AddUIBlock($oDashletContainerError); $oDashboardColumnWorking->AddUIBlock($oDashletContainerWorking); - + $oDashboardRow->AddDashboardColumn($oDashboardColumnTotal); $oDashboardRow->AddDashboardColumn($oDashboardColumnError); $oDashboardRow->AddDashboardColumn($oDashboardColumnWorking); @@ -306,7 +306,7 @@ try $oAuditFilter = new DBObjectSearch('AuditCategory'); $oCategoriesSet = new DBObjectSet($oAuditFilter); - + $aAuditCategoryPanels = []; while($oAuditCategory = $oCategoriesSet->fetch()) { @@ -319,7 +319,7 @@ try $oDefinitionFilter = DBObjectSearch::FromOQL($oAuditCategory->Get('definition_set')); $oDefinitionFilter->UpdateContextFromUser(); FilterByContext($oDefinitionFilter, $oAppContext); - + $aObjectsWithErrors = array(); if (!empty($currentOrganization)) { @@ -340,7 +340,7 @@ try if ($iCount == 0) { // nothing to check, really ! - $aRow['nb_errors'] = "GetKey()."&rule=".$oAuditRule->GetKey()."\">0"; + $aRow['nb_errors'] = "GetKey()."&rule=".$oAuditRule->GetKey()."\">0"; $aRow['percent_ok'] = '100.00'; $aRow['class'] = GetReportColor($iCount, 0); } @@ -349,19 +349,19 @@ try try { $oFilter = GetRuleResultFilter($oAuditRule->GetKey(), $oDefinitionFilter, $oAppContext); - $aErrors = $oFilter->ToDataArray(array('id')); + $aErrors = $oFilter->SelectAttributeToArray('id'); $iErrorsCount = count($aErrors); foreach($aErrors as $aErrorRow) { $aObjectsWithErrors[$aErrorRow['id']] = true; } - $aRow['nb_errors'] = ($iErrorsCount == 0) ? '0' : "GetKey()."&rule=".$oAuditRule->GetKey()."&".$oAppContext->GetForLink()."\">$iErrorsCount GetKey()."&rule=".$oAuditRule->GetKey()."&".$oAppContext->GetForLink()."\">"; + $aRow['nb_errors'] = ($iErrorsCount == 0) ? '0' : "GetKey()."&rule=".$oAuditRule->GetKey()."&".$oAppContext->GetForLink()."\">$iErrorsCount GetKey()."&rule=".$oAuditRule->GetKey()."&".$oAppContext->GetForLink()."\">"; $aRow['percent_ok'] = sprintf('%.2f', 100.0 * (($iCount - $iErrorsCount) / $iCount)); - $aRow['class'] = GetReportColor($iCount, $iErrorsCount); + $aRow['class'] = GetReportColor($iCount, $iErrorsCount); } 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['class'] = 'red'; $sMessage = Dict::Format('UI:Audit:ErrorIn_Rule_Reason', $oAuditRule->GetHyperlink(), $e->getMessage()); @@ -376,7 +376,7 @@ try $iTotalErrors = count($aObjectsWithErrors); $sOverallPercentOk = ($iCount == 0) ? '100.00' : sprintf('%.2f', 100.0 * (($iCount - $iTotalErrors) / $iCount)); $sClass = GetReportColor($iCount, $iTotalErrors); - + $oTotalBlock->SetCount((int)$oTotalBlock->GetCount() + ($iCount)); $oErrorBlock->SetCount((int)$oErrorBlock->GetCount() + $iTotalErrors); $oWorkingBlock->SetCount((int)$oWorkingBlock->GetCount() + ($iCount - $iTotalErrors)); @@ -391,7 +391,7 @@ try $oP->AddUiBlock($oErrorAlert); continue; } - + $oAuditCategoryPanelBlock->SetColorFromColorSemantic($sClass); $oAuditCategoryPanelBlock->AddCSSClass('ibo-audit--audit-category--panel'); $aData = []; @@ -410,7 +410,7 @@ try '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; diff --git a/tests/php-unit-tests/unitary-tests/core/DBSearchTest.php b/tests/php-unit-tests/unitary-tests/core/DBSearchTest.php index 6c54278d7..b232f9cec 100644 --- a/tests/php-unit-tests/unitary-tests/core/DBSearchTest.php +++ b/tests/php-unit-tests/unitary-tests/core/DBSearchTest.php @@ -746,4 +746,110 @@ class DBSearchTest extends ItopDataTestCase $oSearch->MakeSelectQuery(); 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'); + } +} \ No newline at end of file