Sfoglia il codice sorgente

#348 Multi-column queries not working fine with open joins and if null values to be displayed

git-svn-id: http://svn.code.sf.net/p/itop/code/trunk@1115 a333f486-631f-4898-b8df-5754b55c2be0
romainq 14 anni fa
parent
commit
e7c2c433f9

+ 53 - 10
application/cmdbabstract.class.inc.php

@@ -104,6 +104,7 @@ abstract class cmdbAbstractObject extends CMDBObject implements iDisplay
 			$sTip = "<p>The object is synchronized with an external data source</p>";
 			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 = "<a href=\"$sApplicationURL\" target=\"_blank\">".$aData['datasource']->GetName()."</a>";
 				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 .= '<tr class="containerHeader"><td>&nbsp;'.Dict::Format('UI:CountOfResults', $oSet->Count()).'</td><td>';
 			}
-			$sHtml .= $oMenuBlock->GetRenderContent($oPage, $aMenuExtraParams);
+			$sHtml .= $oMenuBlock->GetRenderContent($oPage, $aMenuExtraParams, $aMenuExtraParams['currentId']);
 			$sHtml .= '</td></tr>';
 		}
 		$sHtml .= "<tr><td $sColspan>";
@@ -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</$sAttCode>\n");
+						$oPage->add("<$sAttCode>null</$sAttCode>\n");
+					}
+					else
+					{
+						if (($oAttDef->IsWritable()) && ($oAttDef->IsScalar()))
+						{
+							$sValue = $oObj->GetAsXML($sAttCode);
+							$oPage->add("<$sAttCode>$sValue</$sAttCode>\n");
+						}
 					}
 				}
 				$oPage->add("</$sClassName>\n");

+ 14 - 2
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 .= "<tr><td>".cmdbAbstractObject::GetDisplaySet($oPage, $oSet, $aExtraParams)."</td></tr>\n";

+ 11 - 5
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 CoreException("Missing object id in query result (found null)");
+			}
+			else
 			{
-				throw new CoreWarning("An object id must be an integer value ($iPKey)");
+				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');

+ 43 - 7
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;
+			}
 		}
 	}
 

+ 1 - 1
pages/run_query.php

@@ -130,7 +130,7 @@ try
 			$oP->add("<h3>Query results</h3>\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);

+ 2 - 1
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':