Browse Source

Optimization: do not load the full set of items when it comes to displaying an autocomplete!

git-svn-id: http://svn.code.sf.net/p/itop/code/trunk@1275 a333f486-631f-4898-b8df-5754b55c2be0
romainq 14 years ago
parent
commit
392591b7b4

+ 57 - 39
application/cmdbabstract.class.inc.php

@@ -1156,47 +1156,49 @@ EOF
 					}
 				}
 			}
-			$aAllowedValues = MetaModel::GetAllowedValues_flt($sClassName, $sFilterCode, $aExtraParams);
-			if ($aAllowedValues != null)
+
+			$oAttDef = MetaModel::GetAttributeDef($sClassName, $sFilterCode);
+			if ($oAttDef->IsExternalKey())
 			{
-				$oAttDef = MetaModel::GetAttributeDef($sClassName, $sFilterCode);
+				$sTargetClass = $oAttDef->GetTargetClass();
+				$oAllowedValues = new DBObjectSet(new DBObjectSearch($sTargetClass));
 
-				if ($oAttDef->IsExternalKey())
+				$iFieldSize = $oAttDef->GetMaxSize();
+				$iMaxComboLength = $oAttDef->GetMaximumComboLength();
+				$oWidget = new UIExtKeyWidget($sFilterCode, $sClassName, $oAttDef->GetLabel(), $oAllowedValues, $sFilterValue, 'search_'.$sFilterCode, false, '', '', '');
+				$sHtml .= "<label>".MetaModel::GetFilterLabel($sClassName, $sFilterCode).":</label>&nbsp;";
+				$sHtml .= $oWidget->Display($oPage, $aExtraParams, true /* bSearchMode */);
+			}
+			else
+			{
+				$aAllowedValues = MetaModel::GetAllowedValues_flt($sClassName, $sFilterCode, $aExtraParams);
+				if (is_null($aAllowedValues))
 				{
-					$iFieldSize = $oAttDef->GetMaxSize();
-					$iMaxComboLength = $oAttDef->GetMaximumComboLength();
-					$oWidget = new UIExtKeyWidget($sFilterCode, $sClassName, $oAttDef->GetLabel(), $aAllowedValues, $sFilterValue, 'search_'.$sFilterCode, false, '', '', '');
-					$sHtml .= "<label>".MetaModel::GetFilterLabel($sClassName, $sFilterCode).":</label>&nbsp;";
-					$sHtml .= $oWidget->Display($oPage, $aExtraParams, true /* bSearchMode */);
+					// Any value is possible, display an input box
+					$sHtml .= "<label>".MetaModel::GetFilterLabel($sClassName, $sFilterCode).":</label>&nbsp;<input class=\"textSearch\" name=\"$sFilterCode\" value=\"$sFilterValue\"/>\n";
 				}
 				else
 				{
-				//Enum field or external key, display a combo
-				$sValue = "<select name=\"$sFilterCode\">\n";
-				$sValue .= "<option value=\"\">".Dict::S('UI:SearchValue:Any')."</option>\n";
-				foreach($aAllowedValues as $key => $value)
-				{
-					if ($sFilterValue == $key)
-					{
-						$sSelected = ' selected';
-					}
-					else
+					//Enum field, display a combo
+					$sValue = "<select name=\"$sFilterCode\">\n";
+					$sValue .= "<option value=\"\">".Dict::S('UI:SearchValue:Any')."</option>\n";
+					foreach($aAllowedValues as $key => $value)
 					{
-						$sSelected = '';
+						if ($sFilterValue == $key)
+						{
+							$sSelected = ' selected';
+						}
+						else
+						{
+							$sSelected = '';
+						}
+						$sValue .= "<option value=\"$key\"$sSelected>$value</option>\n";
 					}
-					$sValue .= "<option value=\"$key\"$sSelected>$value</option>\n";
-				}
-				$sValue .= "</select>\n";
-				$sHtml .= "<label>".MetaModel::GetFilterLabel($sClassName, $sFilterCode).":</label>&nbsp;$sValue\n";
+					$sValue .= "</select>\n";
+					$sHtml .= "<label>".MetaModel::GetFilterLabel($sClassName, $sFilterCode).":</label>&nbsp;$sValue\n";
 				}				
-				unset($aExtraParams[$sFilterCode]);
-			}
-			else
-			{
-				// Any value is possible, display an input box
-				$sHtml .= "<label>".MetaModel::GetFilterLabel($sClassName, $sFilterCode).":</label>&nbsp;<input class=\"textSearch\" name=\"$sFilterCode\" value=\"$sFilterValue\"/>\n";
-				unset($aExtraParams[$sFilterCode]);
 			}
+			unset($aExtraParams[$sFilterCode]);
 			$index++;
 			$sHtml .= '</span> ';
 		}
@@ -1406,10 +1408,10 @@ EOF
 					$aEventsList[] ='validate';
 					$aEventsList[] ='change';
 
-					$aAllowedValues = MetaModel::GetAllowedValues_att($sClass, $sAttCode, $aArgs);
+					$oAllowedValues = MetaModel::GetAllowedValuesAsObjectSet($sClass, $sAttCode, $aArgs);
 					$iFieldSize = $oAttDef->GetMaxSize();
 					$iMaxComboLength = $oAttDef->GetMaximumComboLength();
-					$oWidget = new UIExtKeyWidget($sAttCode, $sClass, $oAttDef->GetLabel(), $aAllowedValues, $value, $iId, $bMandatory, $sNameSuffix, $sFieldPrefix, $sFormPrefix);
+					$oWidget = new UIExtKeyWidget($sAttCode, $sClass, $oAttDef->GetLabel(), $oAllowedValues, $value, $iId, $bMandatory, $sNameSuffix, $sFieldPrefix, $sFormPrefix);
 					$sHTMLValue = $oWidget->Display($oPage, $aArgs);
 					$sHTMLValue .= "<!-- iFlags: $iFlags bMandatory: $bMandatory -->\n";
 					break;
@@ -1777,20 +1779,36 @@ EOF
 		// Now fill-in the fields with default/supplied values
 		foreach($aList as $sAttCode)
 		{
-			$aAllowedValues = MetaModel::GetAllowedValues_att($sClass, $sAttCode, $aArgs);
 			if (isset($aArgs['default'][$sAttCode]))
 			{
 				$oObj->Set($sAttCode, $aArgs['default'][$sAttCode]);			
 			}
-			elseif (count($aAllowedValues) == 1)
+			else
 			{
-				// If the field is mandatory, set it to the only possible value
 				$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
+
+				// If the field is mandatory, set it to the only possible value
 				$iFlags = $oObj->GetAttributeFlags($sAttCode);
-				if ( (!$oAttDef->IsNullAllowed()) || ($iFlags & OPT_ATT_MANDATORY))
+				if ((!$oAttDef->IsNullAllowed()) || ($iFlags & OPT_ATT_MANDATORY))
 				{
-					$aValues = array_keys($aAllowedValues);
-					$oObj->Set($sAttCode, $aValues[0]);
+					if ($oAttDef->IsExternalKey())
+					{
+						$oAllowedValues = MetaModel::GetAllowedValuesAsObjectSet($sClass, $sAttCode, $aArgs);
+						if ($oAllowedValues->Count() == 1)
+						{
+							$oRemoteObj = $oAllowedValues->Fetch();
+							$oObj->Set($sAttCode, $oRemoteObj->GetKey());
+						}
+					}
+					else
+					{
+						$aAllowedValues = MetaModel::GetAllowedValues_att($sClass, $sAttCode, $aArgs);
+						if (count($aAllowedValues) == 1)
+						{
+							$aValues = array_keys($aAllowedValues);
+							$oObj->Set($sAttCode, $aValues[0]);
+						}
+					}
 				}
 			}
 		}

+ 19 - 17
application/ui.extkeywidget.class.inc.php

@@ -68,8 +68,10 @@ class UIExtKeyWidget
 	protected $sNameSuffix;
 	protected $iId;
 	protected $sTitle;
+
+	protected $oAllowedValues = null;
 	
-	public function __construct($sAttCode, $sClass, $sTitle, $aAllowedValues, $value, $iInputId, $bMandatory, $sNameSuffix = '', $sFieldPrefix = '', $sFormPrefix = '')
+	public function __construct($sAttCode, $sClass, $sTitle, $oAllowedValues, $value, $iInputId, $bMandatory, $sNameSuffix = '', $sFieldPrefix = '', $sFormPrefix = '')
 	{
 		self::$iWidgetIndex++;
 		$this->sAttCode = $sAttCode;
@@ -77,7 +79,7 @@ class UIExtKeyWidget
 		$this->oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
 		$this->sNameSuffix = $sNameSuffix;
 		$this->iId = $iInputId;
-		$this->aAllowedValues = $aAllowedValues;
+		$this->oAllowedValues = $oAllowedValues;
 		$this->value = $value;
 		$this->sFieldPrefix = $sFieldPrefix;
 		$this->sTargetClass = $this->oAttDef->GetTargetClass();
@@ -110,7 +112,11 @@ class UIExtKeyWidget
 		{
 			$sWizHelper = 'oWizardHelper'.$this->sFormPrefix;
 		}
-		if (count($this->aAllowedValues) < $this->oAttDef->GetMaximumComboLength())
+		if (is_null($this->oAllowedValues))
+		{
+			throw new Exception('Implementation: null value for allowed values definition');
+		}
+		elseif ($this->oAllowedValues->Count() < $this->oAttDef->GetMaximumComboLength())
 		{
 			// Few choices, use a normal 'select'
 			$sSelectMode = 'true';
@@ -127,9 +133,13 @@ class UIExtKeyWidget
 			{
 				$sHTMLValue .= "<option value=\"\">".Dict::S('UI:SelectOne')."</option>\n";
 			}
-			foreach($this->aAllowedValues as $key => $display_value)
+			$this->oAllowedValues->Rewind();
+			while($oObj = $this->oAllowedValues->Fetch())
 			{
-				if ((count($this->aAllowedValues) == 1) && ($this->bMandatory == 'true') )
+				$key = $oObj->GetKey();
+				$display_value = $oObj->Get('friendlyname');
+
+				if (($this->oAllowedValues->Count() == 1) && ($this->bMandatory == 'true') )
 				{
 					// When there is only once choice, select it by default
 					$sSelected = ' selected';
@@ -168,7 +178,7 @@ EOF
 			$iFieldSize = $this->oAttDef->GetMaxSize();
 	
 			// the input for the auto-complete
-			$sHTMLValue = "<input count=\"".count($this->aAllowedValues)."\" type=\"text\" id=\"label_$this->iId\" size=\"30\" maxlength=\"$iFieldSize\" value=\"$sDisplayValue\"/>&nbsp;";
+			$sHTMLValue = "<input count=\"".$this->oAllowedValues->Count()."\" type=\"text\" id=\"label_$this->iId\" size=\"30\" maxlength=\"$iFieldSize\" value=\"$sDisplayValue\"/>&nbsp;";
 			$sHTMLValue .= "<a class=\"no-arrow\" href=\"javascript:oACWidget_{$this->iId}.Search();\"><img id=\"mini_search_{$this->iId}\" style=\"border:0;vertical-align:middle;\" src=\"../images/mini_search.gif\" /></a>&nbsp;";
 	
 			// another hidden input to store & pass the object's Id
@@ -236,19 +246,11 @@ EOF
 	 */
 	public function SearchObjectsToSelect(WebPage $oP, $sTargetClass = '')
 	{
-		if ($sTargetClass != '')
+		if (is_null($this->oAllowedValues))
 		{
-			// assert(MetaModel::IsParentClass($this->m_sRemoteClass, $sRemoteClass));
-			$oFilter = new DBObjectSearch($sTargetClass);
+			throw new Exception('Implementation: null value for allowed values definition');
 		}
-		else
-		{
-			// No remote class specified use the one defined in the linkedset
-			$oFilter = new DBObjectSearch($this->sTargetClass);		
-		}
-		$oFilter->AddCondition('id', array_keys($this->aAllowedValues), 'IN');
-		$oSet = new CMDBObjectSet($oFilter);
-		$oBlock = new DisplayBlock($oFilter, 'list', false);
+		$oBlock = new DisplayBlock($this->oAllowedValues->GetFilter(), 'list', false);
 		$oBlock->Display($oP, $this->iId, array('menu' => false, 'selection_mode' => true, 'selection_type' => 'single', 'display_limit' => false)); // Don't display the 'Actions' menu on the results
 	}
 	

+ 8 - 0
core/attributedef.class.inc.php

@@ -2339,6 +2339,7 @@ class AttributeExternalKey extends AttributeDBFieldVoid
 
 	public function GetAllowedValues($aArgs = array(), $sContains = '')
 	{
+		//throw new Exception("GetAllowedValues on ext key has been deprecated");
 		try
 		{
 			return parent::GetAllowedValues($aArgs, $sContains);
@@ -2351,6 +2352,13 @@ class AttributeExternalKey extends AttributeDBFieldVoid
 		}
 	}
 
+	public function GetAllowedValuesAsObjectSet($aArgs = array(), $sContains = '')
+	{
+		$oValSetDef = $this->GetValuesDef();
+		$oSet = $oValSetDef->ToObjectSet($aArgs, $sContains);
+		return $oSet;
+	}
+
 	public function GetDeletionPropagationOption()
 	{
 		return $this->Get("on_target_delete");

+ 4 - 1
core/dbobjectset.class.php

@@ -353,7 +353,10 @@ class DBObjectSet
 
 	public function Rewind()
 	{
-		$this->Seek(0);
+		if ($this->m_bLoaded)
+		{
+			$this->Seek(0);
+		}
 	}
 
 	public function Seek($iRow)

+ 5 - 0
core/metamodel.class.php

@@ -1024,6 +1024,11 @@ abstract class MetaModel
 		return $oFltDef->GetAllowedValues($aArgs, $sContains);
 	}
 
+	public static function GetAllowedValuesAsObjectSet($sClass, $sAttCode, $aArgs = array(), $sContains = '')
+	{
+		$oAttDef = self::GetAttributeDef($sClass, $sAttCode);
+		return $oAttDef->GetAllowedValuesAsObjectSet($aArgs, $sContains);
+	}
 	//
 	// Businezz model declaration verbs (should be static)
 	//

+ 16 - 0
core/valuesetdef.class.inc.php

@@ -101,6 +101,22 @@ class ValueSetObjects extends ValueSetDefinition
 		$this->m_bAllowAllData = $bAllowAllData;
 	}
 
+
+	public function ToObjectSet($aArgs = array(), $sContains = '')
+	{
+		if ($this->m_bAllowAllData)
+		{
+			$oFilter = DBObjectSearch::FromOQL_AllData($this->m_sFilterExpr);
+		}
+		else
+		{
+			$oFilter = DBObjectSearch::FromOQL($this->m_sFilterExpr);
+		}
+
+		return new DBObjectSet($oFilter, $this->m_aOrderBy, $aArgs);
+	}
+
+
 	protected function LoadValues($aArgs)
 	{
 		$this->m_aValues = array();

+ 9 - 9
pages/ajax.render.php

@@ -91,8 +91,8 @@ try
 			$oObj = null;
 			$currentValue = '';
 		}
-		$aAllowedValues = MetaModel::GetAllowedValues_att($sClass, $sAttCode, array('this' => $oObj));
-		$oWidget = new UIExtKeyWidget($sAttCode, $sClass, '', $aAllowedValues, $currentValue, $iInputId, false, $sSuffix, '');
+		$oAllowedValues = MetaModel::GetAllowedValuesAsObjectSet($sClass, $sAttCode, array('this' => $oObj));
+		$oWidget = new UIExtKeyWidget($sAttCode, $sClass, '', $oAllowedValues, $currentValue, $iInputId, false, $sSuffix, '');
 		$oWidget->SearchObjectsToSelect($oPage, $sTargetClass);	
 		break;
 	
@@ -105,8 +105,8 @@ try
 		$sValue = utils::ReadParam('sValue', '');
 		//$oWizardHelper = WizardHelper::FromJSON($sJson);
 		//$oObj = $oWizardHelper->GetTargetObject();
-		$aAllowedValues = MetaModel::GetAllowedValues_att($sClass, $sAttCode, array() /*array('this' => $oObj)*/);
-		$oWidget = new UIExtKeyWidget($sAttCode, $sClass, '', $aAllowedValues, $sValue, $iInputId, false, $sSuffix, '');
+		$oAllowedValues = MetaModel::GetAllowedValuesAsObjectSet($sClass, $sAttCode, array() /*array('this' => $oObj)*/);
+		$oWidget = new UIExtKeyWidget($sAttCode, $sClass, '', $oAllowedValues, $sValue, $iInputId, false, $sSuffix, '');
 		$oWidget->GetSearchDialog($oPage);
 		break;
 
@@ -119,8 +119,8 @@ try
 		$sJson = utils::ReadParam('json', '');
 		$oWizardHelper = WizardHelper::FromJSON($sJson);
 		$oObj = $oWizardHelper->GetTargetObject();
-		$aAllowedValues = MetaModel::GetAllowedValues_att($sClass, $sAttCode, array('this' => $oObj));
-		$oWidget = new UIExtKeyWidget($sAttCode, $sClass, '', $aAllowedValues, $oObj->Get($sAttCode), $iInputId, false, $sSuffix, '');
+		$oAllowedValues = MetaModel::GetAllowedValuesAsObjectSet($sClass, $sAttCode, array('this' => $oObj));
+		$oWidget = new UIExtKeyWidget($sAttCode, $sClass, '', $oAllowedValues, $oObj->Get($sAttCode), $iInputId, false, $sSuffix, '');
 		$oWidget->GetObjectCreationForm($oPage);
 		break;
 		
@@ -133,9 +133,9 @@ try
 		$sJson = utils::ReadParam('json', '');
 		$oWizardHelper = WizardHelper::FromJSON($sJson);
 		$oObj = $oWizardHelper->GetTargetObject();
-		$aAllowedValues = MetaModel::GetAllowedValues_att($sClass, $sAttCode, array('this' => $oObj));
+		$oAllowedValues = MetaModel::GetAllowedValuesAsObjectSet($sClass, $sAttCode, array('this' => $oObj));
 		// The iInputId of the autocomplete is the prefix for the form used to create the target object
-		$oWidget = new UIExtKeyWidget($sAttCode, $sClass, '', $aAllowedValues, null, $iInputId, false, $sSuffix, $oWizardHelper->GetFormPrefix());
+		$oWidget = new UIExtKeyWidget($sAttCode, $sClass, '', $oAllowedValues, null, $iInputId, false, $sSuffix, $oWizardHelper->GetFormPrefix());
 		$aResult = $oWidget->DoCreateObject($oPage);
 		echo json_encode($aResult);	
 		break;
@@ -147,7 +147,7 @@ try
 		$iInputId = utils::ReadParam('iInputId', '');
 		$iObjectId = utils::ReadParam('iObjectId', '');
 		$sSuffix = utils::ReadParam('sSuffix', '');
-		$oWidget = new UIExtKeyWidget($sAttCode, $sClass, '', array(), '', $iInputId, $sSuffix, '');
+		$oWidget = new UIExtKeyWidget($sAttCode, $sClass, '', null, '', $iInputId, $sSuffix, '');
 		$sName = $oWidget->GetObjectName($iObjectId);
 		echo json_encode(array('name' => $sName));	
 		break;