diff --git a/application/cmdbabstract.class.inc.php b/application/cmdbabstract.class.inc.php index 1a7a40d90..6da6d6985 100644 --- a/application/cmdbabstract.class.inc.php +++ b/application/cmdbabstract.class.inc.php @@ -104,6 +104,7 @@ abstract class cmdbAbstractObject extends CMDBObject implements iDisplay $sTip = "

The object is synchronized with an external data source

"; while($aData = $oReplicaSet->FetchAssoc()) { + // Assumption: $aData['datasource'] will not be null because the data source id is always set... $sApplicationURL = $aData['datasource']->GetApplicationUrl($this, $aData['replica']); $sLink = "".$aData['datasource']->GetName().""; if ($aData['replica']->Get('status_dest_creator') == 1) @@ -741,11 +742,25 @@ EOF { if ($bViewLink) { - $aRow['key_'.$sAlias] = $aObjects[$sAlias]->GetHyperLink(); + if (is_null($aObjects[$sAlias])) + { + $aRow['key_'.$sAlias] = ''; + } + else + { + $aRow['key_'.$sAlias] = $aObjects[$sAlias]->GetHyperLink(); + } } foreach($aList[$sClassName] as $sAttCode) { - $aRow[$sAttCode.'_'.$sAlias] = $aObjects[$sAlias]->GetAsHTML($sAttCode); + if (is_null($aObjects[$sAlias])) + { + $aRow[$sAttCode.'_'.$sAlias] = ''; + } + else + { + $aRow[$sAttCode.'_'.$sAlias] = $aObjects[$sAlias]->GetAsHTML($sAttCode); + } } } $aValues[] = $aRow; @@ -778,7 +793,7 @@ EOF // Full list $sHtml .= ' '.Dict::Format('UI:CountOfResults', $oSet->Count()).''; } - $sHtml .= $oMenuBlock->GetRenderContent($oPage, $aMenuExtraParams); + $sHtml .= $oMenuBlock->GetRenderContent($oPage, $aMenuExtraParams, $aMenuExtraParams['currentId']); $sHtml .= ''; } $sHtml .= ""; @@ -860,10 +875,24 @@ EOF foreach($aAuthorizedClasses as $sAlias => $sClassName) { $oObj = $aObjects[$sAlias]; - $aRow[] = $oObj->GetKey(); + if (is_null($oObj)) + { + $aRow[] = ''; + } + else + { + $aRow[] = $oObj->GetKey(); + } foreach($aList[$sClassName] as $sAttCode => $oAttDef) { - $aRow[] = $oObj->GetAsCSV($sAttCode, $sSeparator, '\\'); + if (is_null($oObj)) + { + $aRow[] = ''; + } + else + { + $aRow[] = $oObj->GetAsCSV($sAttCode, $sSeparator, '\\'); + } } } $sHtml .= implode($sSeparator, $aRow)."\n"; @@ -898,14 +927,28 @@ EOF foreach($aAuthorizedClasses as $sAlias => $sClassName) { $oObj = $aObjects[$sAlias]; - $sClassName = get_class($oObj); - $oPage->add("<$sClassName alias=\"$sAlias\" id=\"".$oObj->GetKey()."\">\n"); + if (is_null($oObj)) + { + $oPage->add("<$sClassName alias=\"$sAlias\" id=\"null\">\n"); + } + else + { + $sClassName = get_class($oObj); + $oPage->add("<$sClassName alias=\"$sAlias\" id=\"".$oObj->GetKey()."\">\n"); + } foreach(MetaModel::ListAttributeDefs($sClassName) as $sAttCode=>$oAttDef) { - if (($oAttDef->IsWritable()) && ($oAttDef->IsScalar())) + if (is_null($oObj)) { - $sValue = $oObj->GetAsXML($sAttCode); - $oPage->add("<$sAttCode>$sValue\n"); + $oPage->add("<$sAttCode>null\n"); + } + else + { + if (($oAttDef->IsWritable()) && ($oAttDef->IsScalar())) + { + $sValue = $oObj->GetAsXML($sAttCode); + $oPage->add("<$sAttCode>$sValue\n"); + } } } $oPage->add("\n"); diff --git a/application/displayblock.class.inc.php b/application/displayblock.class.inc.php index 981507430..31080aa53 100644 --- a/application/displayblock.class.inc.php +++ b/application/displayblock.class.inc.php @@ -441,7 +441,15 @@ class DisplayBlock $aKeys = array(); foreach($aGroupByFields as $aField) { - $aKeys[$aField['alias'].'.'.$aField['att_code']] = $aObjects[$aField['alias']]->Get($aField['att_code']); + $sAlias = $aField['alias']; + if (is_null($aObjects[$sAlias])) + { + $aKeys[$sAlias.'.'.$aField['att_code']] = ''; + } + else + { + $aKeys[$sAlias.'.'.$aField['att_code']] = $aObjects[$sAlias]->Get($aField['att_code']); + } } $sCategory = implode($aKeys, ' '); $aResults[$sCategory][] = $aObjects; @@ -469,7 +477,11 @@ class DisplayBlock $aSimpleArray = array(); foreach($aObjects as $aRow) { - $aSimpleArray[] = $aRow[$aDisplayAliases[0]]; + $oObj = $aRow[$aDisplayAliases[0]]; + if (!is_null($oObj)) + { + $aSimpleArray[] = $oObj; + } } $oSet = CMDBObjectSet::FromArray($this->m_oFilter->GetClass(), $aSimpleArray); $sHtml .= "".cmdbAbstractObject::GetDisplaySet($oPage, $oSet, $aExtraParams)."\n"; diff --git a/core/dbobject.class.php b/core/dbobject.class.php index b9ef03b72..19d977c37 100644 --- a/core/dbobject.class.php +++ b/core/dbobject.class.php @@ -207,15 +207,20 @@ abstract class DBObject // #@# Bug ? throw new CoreException("Missing key for class '".get_class($this)."'"); } - else + + $iPKey = $aRow[$sKeyField]; + if (!self::IsValidPKey($iPKey)) { - $iPKey = $aRow[$sKeyField]; - if (!self::IsValidPKey($iPKey)) + if (is_null($iPKey)) { - throw new CoreWarning("An object id must be an integer value ($iPKey)"); + throw new CoreException("Missing object id in query result (found null)"); + } + else + { + throw new CoreException("An object id must be an integer value ($iPKey)"); } - $this->m_iKey = $iPKey; } + $this->m_iKey = $iPKey; // Build the object from an array of "attCode"=>"value") // @@ -1434,6 +1439,7 @@ abstract class DBObject $oSet = $this->GetMasterReplica(); while($aData = $oSet->FetchAssoc()) { + // Assumption: $aData['datasource'] will not be null because the data source id is always set... $oReplica = $aData['replica']; $oSource = $aData['datasource']; $oAttrSet = $oSource->Get('attribute_list'); diff --git a/core/dbobjectset.class.php b/core/dbobjectset.class.php index 1255fa79e..de3724c38 100644 --- a/core/dbobjectset.class.php +++ b/core/dbobjectset.class.php @@ -48,7 +48,7 @@ class DBObjectSet $this->m_iLimitStart = $iLimitStart; $this->m_bLoaded = false; // true when the filter has been used OR the set is built step by step (AddObject...) - $this->m_aData = array(); // array of (row => array of (classalias) => object) + $this->m_aData = array(); // array of (row => array of (classalias) => object/null) $this->m_aId2Row = array(); $this->m_iCurrRow = 0; } @@ -163,19 +163,42 @@ class DBObjectSet { if (!$this->m_bLoaded) $this->Load(); + $aSelectedClasses = $this->m_oFilter->GetSelectedClasses(); + $aRet = array(); foreach($this->m_aData as $iRow => $aObjects) { foreach($aObjects as $sClassAlias => $oObject) { - $aRet[$iRow][$sClassAlias.'.'.'id'] = $oObject->GetKey(); - $sClass = get_class($oObject); + if (is_null($oObject)) + { + $aRet[$iRow][$sClassAlias.'.'.'id'] = null; + } + else + { + $aRet[$iRow][$sClassAlias.'.'.'id'] = $oObject->GetKey(); + } + if (is_null($oObject)) + { + $sClass = $aSelectedClasses[$sClassAlias]; + } + else + { + $sClass = get_class($oObject); + } foreach(MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef) { if ($oAttDef->IsScalar()) { $sAttName = $sClassAlias.'.'.$sAttCode; - $aRet[$iRow][$sAttName] = $oObject->Get($sAttCode); + if (is_null($oObject)) + { + $aRet[$iRow][$sAttName] = null; + } + else + { + $aRet[$iRow][$sAttName] = $oObject->Get($sAttCode); + } } } } @@ -261,7 +284,14 @@ class DBObjectSet $aObjects = array(); foreach ($this->m_oFilter->GetSelectedClasses() as $sClassAlias => $sClass) { - $oObject = MetaModel::GetObjectByRow($sClass, $aRow, $sClassAlias, $this->m_aExtendedDataSpec); + if (is_null($aRow[$sClassAlias.'id'])) + { + $oObject = null; + } + else + { + $oObject = MetaModel::GetObjectByRow($sClass, $aRow, $sClassAlias, $this->m_aExtendedDataSpec); + } $aObjects[$sClassAlias] = $oObject; } $this->AddObjectExtended($aObjects); @@ -345,7 +375,10 @@ class DBObjectSet $iNextPos = count($this->m_aData); $this->m_aData[$iNextPos][$sClassAlias] = $oObject; - $this->m_aId2Row[$sClassAlias][$oObject->GetKey()] = $iNextPos; + if (!is_null($oObject)) + { + $this->m_aId2Row[$sClassAlias][$oObject->GetKey()] = $iNextPos; + } } protected function AddObjectExtended($aObjectArray) @@ -357,7 +390,10 @@ class DBObjectSet foreach ($aObjectArray as $sClassAlias => $oObject) { $this->m_aData[$iNextPos][$sClassAlias] = $oObject; - $this->m_aId2Row[$sClassAlias][$oObject->GetKey()] = $iNextPos; + if (!is_null($oObject)) + { + $this->m_aId2Row[$sClassAlias][$oObject->GetKey()] = $iNextPos; + } } } diff --git a/pages/run_query.php b/pages/run_query.php index 0b6667aca..2cbb7f229 100644 --- a/pages/run_query.php +++ b/pages/run_query.php @@ -130,7 +130,7 @@ try $oP->add("

Query results

\n"); $oResultBlock = new DisplayBlock($oFilter, 'list', false); - $oResultBlock->Display($oP, 1); + $oResultBlock->Display($oP, 'runquery'); $oP->p(''); $oP->StartCollapsibleSection(Dict::S('UI:RunQuery:MoreInfo'), false); diff --git a/webservices/export.php b/webservices/export.php index 5b69117b5..60c20f764 100644 --- a/webservices/export.php +++ b/webservices/export.php @@ -71,7 +71,8 @@ if (!empty($sExpression)) } $sUrl = "$sProtocol://{$sServerName}{$sPort}/pages/"; $oP->set_base($sUrl); - cmdbAbstractObject::DisplaySet($oP, $oSet, array('block_id' => 'expresult', 'menu' => false, 'display_limit' => false, 'zlist' => 'details')); // no menu, no truncated list, "details" zlist + $oResultBlock = new DisplayBlock($oFilter, 'list', false, array('menu' => false, 'display_limit' => false, 'zlist' => 'details')); + $oResultBlock->Display($oP, 'expresult'); break; case 'csv':