소스 검색

User management by profile moving forward: pages to check the projection of objects/users in user defined dimensions
Introduced parameters in OQL (:myvar)
Added the verb MetaModel::IsValidObject($oMyObj)

git-svn-id: http://svn.code.sf.net/p/itop/code/trunk@88 a333f486-631f-4898-b8df-5754b55c2be0

romainq 16 년 전
부모
커밋
972bb29ffe

+ 142 - 59
addons/userrights/userrightsprofile.class.inc.php

@@ -98,10 +98,81 @@ class URP_Dimensions extends DBObject
 		//MetaModel::Init_InheritAttributes();
 		MetaModel::Init_AddAttribute(new AttributeString("name", array("label"=>"name", "description"=>"label", "allowed_values"=>null, "sql"=>"name", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
 		MetaModel::Init_AddAttribute(new AttributeString("description", array("label"=>"description", "description"=>"one line description", "allowed_values"=>null, "sql"=>"description", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
+		MetaModel::Init_AddAttribute(new AttributeString("type", array("label"=>"type", "description"=>"class name or data type (projection unit)", "allowed_values"=>new ValueSetEnumClasses('bizmodel', 'String,Integer'), "sql"=>"type", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
 
 		//MetaModel::Init_InheritFilters();
 		MetaModel::Init_AddFilterFromAttribute("name");
 		MetaModel::Init_AddFilterFromAttribute("description");
+		MetaModel::Init_AddFilterFromAttribute("type");
+	}
+
+	public function CheckProjectionSpec($oProjectionSpec)
+	{
+		$sExpression = $oProjectionSpec->Get('value');
+		$sAttribute = $oProjectionSpec->Get('attribute');
+
+		// Shortcut: "any value" or "no value" means no projection
+		if (empty($sExpression)) return;
+		if ($sExpression == '<any>') return;
+
+		// 1st - compute the data type for the dimension
+		//
+		$sType = $this->Get('type');
+		if (MetaModel::IsValidClass($sType))
+		{
+			$sExpectedType = $sType;
+		}
+		else
+		{
+			$sExpectedType = '_scalar_';
+		}
+
+		// 2nd - compute the data type for the projection
+		//
+		$bIsOql = true;
+		$sExpressionClass = '';
+		try
+		{
+			$oObjectSearch = DBObjectSearch::FromOQL($sExpression);
+			$sExpressionClass = $oObjectSearch->GetClass();
+		}
+		catch (OqlException $e)
+		{
+			$bIsOql = false;
+		}
+		if ($bIsOql)
+		{
+			if (empty($sAttribute))
+			{
+				$sFoundType = $sExpressionClass;
+			}
+			else
+			{
+				if (!MetaModel::IsValidAttCode($sExpressionClass, $sAttribute))
+				{
+					throw new CoreException('Unkown attribute code in projection specification', array('found' => $sAttribute, 'expecting' => MetaModel::GetAttributesList($sExpressionClass), 'class' => $sExpressionClass, 'projection' => $oProjectionSpec));
+				}
+				$oAttDef = MetaModel::GetAttributeDef($sExpressionClass, $sAttribute);
+				if ($oAttDef->IsExternalKey())
+				{
+					$sFoundType = $oAttDef->GetTargetClass();
+				}
+				else
+				{
+					$sFoundType = '_scalar_';
+				}
+			}
+		}
+		else
+		{
+			$sFoundType = '_scalar_';
+		}
+
+		// Compare the dimension type and projection type
+		if ($sFoundType != $sExpectedType)
+		{
+			throw new CoreException('Wrong type in projection specification', array('found' => $sFoundType, 'expecting' => $sExpectedType, 'expression' => $sExpression, 'attribute' => $sAttribute, 'projection' => $oProjectionSpec));
+		}
 	}
 }
 
@@ -163,7 +234,8 @@ class URP_ProfileProjection extends DBObject
 		MetaModel::Init_AddAttribute(new AttributeExternalKey("profileid", array("targetclass"=>"URP_Profiles", "jointype"=> "", "label"=>"profile", "description"=>"usage profile", "allowed_values"=>null, "sql"=>"profileid", "is_null_allowed"=>false, "depends_on"=>array())));
 		MetaModel::Init_AddAttribute(new AttributeExternalField("profile", array("label"=>"Profile", "description"=>"Profile name", "allowed_values"=>null, "extkey_attcode"=> 'profileid', "target_attcode"=>"name")));
 
-		MetaModel::Init_AddAttribute(new AttributeString("value", array("label"=>"Value expression", "description"=>"OQL expression (using \$user) | constant", "allowed_values"=>null, "sql"=>"value", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
+		MetaModel::Init_AddAttribute(new AttributeString("value", array("label"=>"Value expression", "description"=>"OQL expression (using \$user) | constant | <any>", "allowed_values"=>null, "sql"=>"value", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
+		MetaModel::Init_AddAttribute(new AttributeString("attribute", array("label"=>"Attribute", "description"=>"Target attribute code (optional)", "allowed_values"=>null, "sql"=>"attribute", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
 
 		//MetaModel::Init_InheritFilters();
 		MetaModel::Init_AddFilterFromAttribute("dimensionid");
@@ -172,7 +244,25 @@ class URP_ProfileProjection extends DBObject
 
 	public function ProjectUser(URP_Users $oUser)
 	{
-		// #@# to be implemented
+		$sExpr = $this->Get('value');
+		if (preg_match('/^\s*([a-zA-Z0-9;]+)\s*$/', $sExpr, $aMatches))
+		{
+			// Constant value(s)
+			$aRes = explode(';', $aMatches[1]);
+		}
+		elseif ($sExpr == '<any>')
+		{
+			$aRes = array('<any>');
+		}
+		else
+		{
+			$sColumn = $this->Get('attribute');
+			// SELECT...
+			$oValueSetDef = new ValueSetObjects($sExpr, $sColumn);
+			$aValues = $oValueSetDef->GetValues(array('user' => $oUser), '');
+			$aRes = array_values($aValues);
+		}
+		return $aRes;
 	}
 }
 
@@ -201,29 +291,53 @@ class URP_ClassProjection extends DBObject
 
 		MetaModel::Init_AddAttribute(new AttributeString("class", array("label"=>"Class", "description"=>"Target class", "allowed_values"=>null, "sql"=>"class", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
 
-		MetaModel::Init_AddAttribute(new AttributeString("value", array("label"=>"Value expression", "description"=>"OQL expression (using \$this) | constant", "allowed_values"=>null, "sql"=>"value", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
+		MetaModel::Init_AddAttribute(new AttributeString("value", array("label"=>"Value expression", "description"=>"OQL expression (using \$this) | constant | <any>", "allowed_values"=>null, "sql"=>"value", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
+		MetaModel::Init_AddAttribute(new AttributeString("attribute", array("label"=>"Attribute", "description"=>"Target attribute code (optional)", "allowed_values"=>null, "sql"=>"attribute", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
 
 		//MetaModel::Init_InheritFilters();
 		MetaModel::Init_AddFilterFromAttribute("dimensionid");
 		MetaModel::Init_AddFilterFromAttribute("class");
 	}
+
+	public function ProjectObject($oObject)
+	{
+		$sExpr = $this->Get('value');
+		if (preg_match('/^\s*([a-zA-Z0-9;]+)\s*$/', $sExpr, $aMatches))
+		{
+			// Constant value(s)
+			$aRes = explode(';', $aMatches[1]);
+		}
+		elseif ($sExpr == '<any>')
+		{
+			$aRes = array('<any>');
+		}
+		else
+		{
+			$sColumn = $this->Get('attribute');
+			// SELECT...
+			$oValueSetDef = new ValueSetObjects($sExpr, $sColumn);
+			$aValues = $oValueSetDef->GetValues(array('this' => $oObject), '');
+			$aRes = array_values($aValues);
+		}
+		return $aRes;
+	}
 }
 
-class URP_ClassGrant extends DBObject
+class URP_ActionGrant extends DBObject
 {
 	public static function Init()
 	{
 		$aParams = array
 		(
 			"category" => "addon/userrights",
-			"name" => "class_permission",
+			"name" => "action_permission",
 			"description" => "permissions on classes",
 			"key_type" => "autoincrement",
 			"key_label" => "",
 			"name_attcode" => "",
 			"state_attcode" => "",
 			"reconc_keys" => array(),
-			"db_table" => "priv_urp_grant_classes",
+			"db_table" => "priv_urp_grant_actions",
 			"db_key_field" => "id",
 			"db_finalclass_field" => "",
 		);
@@ -308,23 +422,12 @@ class URP_AttributeGrant extends DBObject
 		MetaModel::Init_Params($aParams);
 		//MetaModel::Init_InheritAttributes();
 
-		// Common to all grant classes (could be factorized by class inheritence, but this has to be benchmarked)
-		MetaModel::Init_AddAttribute(new AttributeExternalKey("profileid", array("targetclass"=>"URP_Profiles", "jointype"=> "", "label"=>"Profile", "description"=>"usage profile", "allowed_values"=>null, "sql"=>"profileid", "is_null_allowed"=>false, "depends_on"=>array())));
-		MetaModel::Init_AddAttribute(new AttributeExternalField("profile", array("label"=>"Profile", "description"=>"usage profile", "allowed_values"=>null, "extkey_attcode"=> 'profileid', "target_attcode"=>"name")));
-		MetaModel::Init_AddAttribute(new AttributeString("class", array("label"=>"class", "description"=>"class name", "allowed_values"=>null, "sql"=>"class", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
-		MetaModel::Init_AddAttribute(new AttributeEnum("permission", array("label"=>"permission", "description"=>"allowed or not allowed?", "allowed_values"=>new ValueSetEnum('yes,no'), "sql"=>"permission", "default_value"=>"yes", "is_null_allowed"=>false, "depends_on"=>array())));
-
+		MetaModel::Init_AddAttribute(new AttributeExternalKey("actiongrantid", array("targetclass"=>"URP_ActionGrant", "jointype"=> "", "label"=>"Action grant", "description"=>"action grant", "allowed_values"=>null, "sql"=>"actiongrantid", "is_null_allowed"=>false, "depends_on"=>array())));
 		MetaModel::Init_AddAttribute(new AttributeString("attcode", array("label"=>"attribute", "description"=>"attribute code", "allowed_values"=>null, "sql"=>"attcode", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
-		MetaModel::Init_AddAttribute(new AttributeString("action", array("label"=>"action", "description"=>"operations to perform on the given class", "allowed_values"=>null, "sql"=>"action", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
 
 		//MetaModel::Init_InheritFilters();
-		// Common to all grant classes (could be factorized by class inheritence, but this has to be benchmarked)
-		MetaModel::Init_AddFilterFromAttribute("profileid");
-		MetaModel::Init_AddFilterFromAttribute("profile");
-		MetaModel::Init_AddFilterFromAttribute("class");
-
+		MetaModel::Init_AddFilterFromAttribute("actiongrantid");
 		MetaModel::Init_AddFilterFromAttribute("attcode");
-		MetaModel::Init_AddFilterFromAttribute("action");
 	}
 }
 
@@ -454,18 +557,18 @@ class UserRightsProfile extends UserRightsAddOnAPI
 					}
 					else
 					{
-						$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_ClassGrant WHERE class = '$sClass' AND action = '$sAction' AND profileid = $iProfileId"));
+						$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_ActionGrant WHERE class = '$sClass' AND action = '$sAction' AND profileid = $iProfileId"));
 						$bAddCell = ($oSet->Count() < 1);
 					}
 					if ($bAddCell)
 					{
 						// Create a new entry
-						$oMyClassGrant = MetaModel::NewObject("URP_ClassGrant");
-						$oMyClassGrant->Set("profileid", $iProfileId);
-						$oMyClassGrant->Set("class", $sClass);
-						$oMyClassGrant->Set("action", $sAction);
-						$oMyClassGrant->Set("permission", "yes");
-						$iId = $oMyClassGrant->DBInsertNoReload();
+						$oMyActionGrant = MetaModel::NewObject("URP_ActionGrant");
+						$oMyActionGrant->Set("profileid", $iProfileId);
+						$oMyActionGrant->Set("class", $sClass);
+						$oMyActionGrant->Set("action", $sAction);
+						$oMyActionGrant->Set("permission", "yes");
+						$iId = $oMyActionGrant->DBInsertNoReload();
 					}
 				}
 				foreach (MetaModel::EnumStimuli($sClass) as $sStimulusCode => $oStimulus)
@@ -482,38 +585,12 @@ class UserRightsProfile extends UserRightsAddOnAPI
 					if ($bAddCell)
 					{
 						// Create a new entry
-						$oMyClassGrant = MetaModel::NewObject("URP_StimulusGrant");
-						$oMyClassGrant->Set("profileid", $iProfileId);
-						$oMyClassGrant->Set("class", $sClass);
-						$oMyClassGrant->Set("stimulus", $sStimulusCode);
-						$oMyClassGrant->Set("permission", "yes");
-						$iId = $oMyClassGrant->DBInsertNoReload();
-					}
-				}
-				foreach (MetaModel::GetAttributesList($sClass) as $sAttCode)
-				{
-					if ($bNewProfile)
-					{
-						$bAddCell = true;
-					}
-					else
-					{
-						$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_AttributeGrant WHERE class = '$sClass' AND attcode = '$sAttCode' AND profileid = $iProfileId"));
-						$bAddCell = ($oSet->Count() < 1);
-					}
-					if ($bAddCell)
-					{
-						foreach (array('read', 'modify') as $sAction)
-						{
-							// Create a new entry
-							$oMyAttGrant = MetaModel::NewObject("URP_AttributeGrant");
-							$oMyAttGrant->Set("profileid", $iProfileId);
-							$oMyAttGrant->Set("class", $sClass);
-							$oMyAttGrant->Set("attcode", $sAttCode);
-							$oMyAttGrant->Set("action", $sAction);
-							$oMyAttGrant->Set("permission", "yes");
-							$iId = $oMyAttGrant->DBInsertNoReload();
-						}
+						$oMyStGrant = MetaModel::NewObject("URP_StimulusGrant");
+						$oMyStGrant->Set("profileid", $iProfileId);
+						$oMyStGrant->Set("class", $sClass);
+						$oMyStGrant->Set("stimulus", $sStimulusCode);
+						$oMyStGrant->Set("permission", "yes");
+						$iId = $oMyStGrant->DBInsertNoReload();
 					}
 				}
 			}
@@ -577,13 +654,15 @@ class UserRightsProfile extends UserRightsAddOnAPI
 
 	public function IsActionAllowed($sUserName, $sClass, $iActionCode, dbObjectSet $aInstances)
 	{
+		// #@# temporary
+		return true;
 		if (!array_key_exists($iActionCode, self::$m_aActionCodes))
 		{
 			return UR_ALLOWED_NO;
 		}
 		$sAction = self::$m_aActionCodes[$iActionCode];
 
-		$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_ClassGrant WHERE class = '$sClass' AND action = '$sAction' AND login = '$sUserName'"));
+		$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_ActionGrant WHERE class = '$sClass' AND action = '$sAction' AND login = '$sUserName'"));
 		if ($oSet->Count() < 1)
 		{
 			return UR_ALLOWED_NO;
@@ -605,6 +684,8 @@ class UserRightsProfile extends UserRightsAddOnAPI
 
 	public function IsActionAllowedOnAttribute($sUserName, $sClass, $sAttCode, $iActionCode, dbObjectSet $aInstances)
 	{
+		// #@# temporary
+		return true;
 		if (!array_key_exists($iActionCode, self::$m_aActionCodes))
 		{
 			return UR_ALLOWED_NO;
@@ -633,6 +714,8 @@ class UserRightsProfile extends UserRightsAddOnAPI
 
 	public function IsStimulusAllowed($sUserName, $sClass, $sStimulusCode, dbObjectSet $aInstances)
 	{
+		// #@# temporary
+		return true;
 		$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_StimulusGrant WHERE class = '$sClass' AND stimulus = '$sStimulusCode' AND login = '$sUserName'"));
 		if ($oSet->Count() < 1)
 		{

+ 2 - 0
business/itop.business.class.inc.php

@@ -260,6 +260,8 @@ class bizPerson extends bizContact
 		MetaModel::Init_AddAttribute(new AttributeString("first_name", array("label"=>"first Name", "description"=>"First name", "allowed_values"=>null, "sql"=>"first_name", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
 		MetaModel::Init_AddAttribute(new AttributeString("employe_number", array("label"=>"Employe Number", "description"=>"employe number", "allowed_values"=>null, "sql"=>"employe_number", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
 
+		MetaModel::Init_AddAttribute(new AttributeExternalKey("login_id", array("targetclass"=>"URP_Users", "label"=>"Login", "description"=>"Login information", "allowed_values"=>null, "sql"=>"login_id", "is_null_allowed"=>true, "depends_on"=>array())));
+
 		MetaModel::Init_InheritFilters();
 		MetaModel::Init_AddFilterFromAttribute("first_name");
 		MetaModel::Init_AddFilterFromAttribute("employe_number");

+ 1 - 1
core/config.class.inc.php

@@ -256,7 +256,7 @@ class Config
 			fwrite($hFile, "\t\t// to be continued...\n");
 			fwrite($hFile, "\t),\n");
 			fwrite($hFile, "\t'addons' => array (\n");
-			fwrite($hFile, "\t\t'user rights' => '../addons/userrights/userrightsmatrix.class.inc.php',\n");
+			fwrite($hFile, "\t\t'user rights' => '../addons/userrights/userrightsprofile.class.inc.php',\n");
 			fwrite($hFile, "\t\t// other modules to come later\n");
 			fwrite($hFile, "\t)\n");
 			fwrite($hFile, ");\n");

+ 2 - 2
core/coreexception.class.inc.php

@@ -23,11 +23,11 @@ class CoreException extends Exception
 					{
 						if (is_array($val))
 						{
-							$aPairs[$key] = '('.implode(', ', $val).')';
+							$aPairs[] = $key.'=>('.implode(', ', $val).')';
 						}
 						else
 						{
-							$aPairs[$key] = $val;
+							$aPairs[] = $key.'=>'.$val;
 						}
 					}
 					$sValue = '{'.implode('; ', $aPairs).'}';

+ 11 - 6
core/dbobjectsearch.class.php

@@ -662,7 +662,7 @@ class DBObjectSearch
 		}
 		if (count($aParams) > 0)
 		{
-			throw new CoreException("Unused parameter(s) for this SibusQL expression: (".implode(', ', array_keys($aParams)).")");
+//			throw new CoreException("Unused parameter(s) for this SibusQL expression: (".implode(', ', array_keys($aParams)).")");
 		}
 		return $sQuery;
 	}
@@ -736,6 +736,10 @@ class DBObjectSearch
 
 			return new FieldExpression($sFltCode, $sClassAlias);
 		}
+		elseif ($oExpression instanceof VariableOqlExpression)
+		{
+			return new VariableExpression($oExpression->GetName());
+		}
 		elseif ($oExpression instanceof TrueOqlExpression)
 		{
 			return new TrueExpression;
@@ -763,7 +767,7 @@ class DBObjectSearch
 		if (empty($sQuery)) return null;
 
 		$oOql = new OqlInterpreter($sQuery);
-		$oOqlQuery = $oOql->ParseQuery();
+		$oOqlQuery = $oOql->ParseObjectQuery();
 		
 		$sClass = $oOqlQuery->GetClass();
 		$sClassAlias = $oOqlQuery->GetClassAlias();
@@ -860,13 +864,14 @@ class DBObjectSearch
 		if (empty($sQuery)) return null;
 		$sQuery = self::privProcessParams($sQuery, $aParams, $oObject);
 
+		if (preg_match('@^\\s*SELECT@', $sQuery))
+		{
+			return self::FromOQL($sQuery, $aParams, $oObject);
+		}
+
 		$iSepPos = strpos($sQuery, ":");
 		if ($iSepPos === false)
 		{
-			if (preg_match('@^\\s*SELECT@', $sQuery))
-			{
-				return self::FromOQL($sQuery, $aParams, $oObject);
-			}
 			// Only the class was specified -> all rows are required
 			$sClass = trim($sQuery);
 			$oFilter = new DBObjectSearch($sClass);

+ 4 - 3
core/dbobjectset.class.php

@@ -21,10 +21,11 @@ class DBObjectSet
 	private $m_aId2Row;
 	private $m_iCurrRow;
 
-	public function __construct($oFilter, $aOrderBy = array())
+	public function __construct($oFilter, $aOrderBy = array(), $aArgs = array())
 	{
 		$this->m_oFilter = $oFilter;
 		$this->m_aOrderBy = $aOrderBy;
+		$this->m_aArgs = $aArgs;
 
 		$this->m_bLoaded = false;
 		$this->m_aData = array();
@@ -109,8 +110,8 @@ class DBObjectSet
 	public function Load()
 	{
 		if ($this->m_bLoaded) return;
-// #@# debug - echo "Loading (".$this->m_oFilter->ToSibuSQL().")....</br>\n";
-		$sSQL = MetaModel::MakeSelectQuery($this->m_oFilter, $this->m_aOrderBy);
+
+		$sSQL = MetaModel::MakeSelectQuery($this->m_oFilter, $this->m_aOrderBy, $this->m_aArgs);
 		$resQuery = CMDBSource::Query($sSQL);
 		if (!$resQuery) return;
 

+ 51 - 14
core/expression.class.inc.php

@@ -17,7 +17,7 @@ abstract class Expression
 	abstract public function Translate($aTranslationData, $bMatchAll = true);
 
 	// recursive rendering
-	abstract public function Render();
+	abstract public function Render($aArgs = array());
 
 	// recursively builds an array of class => fieldname
 	abstract public function ListRequiredFields();
@@ -119,11 +119,11 @@ class BinaryExpression extends Expression
 	}
 
 	// recursive rendering
-	public function Render()
+	public function Render($aArgs = array())
 	{
 		$sOperator = $this->GetOperator();
-		$sLeft = $this->GetLeftExpr()->Render();
-		$sRight = $this->GetRightExpr()->Render();
+		$sLeft = $this->GetLeftExpr()->Render($aArgs);
+		$sRight = $this->GetRightExpr()->Render($aArgs);
 		return "($sLeft $sOperator $sRight)";
 	}
 
@@ -164,7 +164,7 @@ class UnaryExpression extends Expression
 	} 
 
 	// recursive rendering
-	public function Render()
+	public function Render($aArgs = array())
 	{
 		return CMDBSource::Quote($this->m_value);
 	}
@@ -228,7 +228,7 @@ class FieldExpression extends UnaryExpression
 	public function GetName() {return $this->m_sName;}
 
 	// recursive rendering
-	public function Render()
+	public function Render($aArgs = array())
 	{
 		if (empty($this->m_sParent))
 		{
@@ -270,6 +270,43 @@ class FieldExpression extends UnaryExpression
 }
 
 
+class VariableExpression extends UnaryExpression
+{
+	protected $m_sName;
+
+	public function __construct($sName)
+	{
+		parent::__construct($sName);
+
+		$this->m_sName = $sName;
+	}
+
+	public function IsTrue()
+	{
+		// return true if we are certain that it will be true
+		return false;
+	}
+
+	public function GetName() {return $this->m_sName;}
+
+	// recursive rendering
+	public function Render($aArgs = array())
+	{
+		if (array_key_exists($this->m_sName, $aArgs))
+		{
+			return $aArgs[$this->m_sName];
+		}
+		elseif (is_null($aArgs))
+		{
+			return ':'.$this->m_sName;
+		}
+		else
+		{
+			throw new CoreException('Missing query argument', array('expecting'=>$this->m_sName, 'available'=>$aArgs));
+		}
+	}
+}
+
 // Temporary, until we implement functions and expression casting!
 // ... or until we implement a real full text search based in the MATCH() expression
 class ListExpression extends Expression
@@ -293,12 +330,12 @@ class ListExpression extends Expression
 	}
 
 	// recursive rendering
-	public function Render()
+	public function Render($aArgs = array())
 	{
 		$aRes = array();
 		foreach ($this->m_aExpressions as $oExpr)
 		{
-			$aRes[] = $oExpr->Render();
+			$aRes[] = $oExpr->Render($aArgs);
 		}
 		return '('.implode(', ', $aRes).')';
 	}
@@ -353,12 +390,12 @@ class FunctionExpression extends Expression
 	}
 
 	// recursive rendering
-	public function Render()
+	public function Render($aArgs = array())
 	{
 		$aRes = array();
 		foreach ($this->m_aArgs as $oExpr)
 		{
-			$aRes[] = $oExpr->Render();
+			$aRes[] = $oExpr->Render($aArgs);
 		}
 		return $this->m_sVerb.'('.implode(', ', $aRes).')';
 	}
@@ -412,9 +449,9 @@ class IntervalExpression extends Expression
 	}
 
 	// recursive rendering
-	public function Render()
+	public function Render($aArgs = array())
 	{
-		return 'INTERVAL '.$this->m_oValue->Render().' '.$this->m_sUnit;
+		return 'INTERVAL '.$this->m_oValue->Render($aArgs).' '.$this->m_sUnit;
 	}
 
 	public function Translate($aTranslationData, $bMatchAll = true)
@@ -449,12 +486,12 @@ class CharConcatExpression extends Expression
 	}
 
 	// recursive rendering
-	public function Render()
+	public function Render($aArgs = array())
 	{
 		$aRes = array();
 		foreach ($this->m_aExpressions as $oExpr)
 		{
-			$sCol = $oExpr->Render();
+			$sCol = $oExpr->Render($aArgs);
 			// Concat will be globally NULL if one single argument is null ! 
 			$aRes[] = "COALESCE($sCol, '')";
 		}

+ 30 - 2
core/metamodel.class.php

@@ -394,6 +394,12 @@ abstract class MetaModel
 		return (array_key_exists($sClass, self::$m_aAttribDefs));
 	}
 
+	public static function IsValidObject($oObject)
+	{
+		if (!is_object($oObject)) return false;
+		return (self::IsValidClass(get_class($oObject)));
+	}
+
 	public static function IsReconcKey($sClass, $sAttCode)
 	{
 		return (in_array($sAttCode, self::GetReconcKeys($sClass)));
@@ -1161,7 +1167,7 @@ abstract class MetaModel
 		return false;
 	}
 
-	public static function MakeSelectQuery(DBObjectSearch $oFilter, $aOrderBy = array())
+	public static function MakeSelectQuery(DBObjectSearch $oFilter, $aOrderBy = array(), $aArgs = array())
 	{
 		$aTranslation = array();
 		$aClassAliases = array();
@@ -1188,8 +1194,30 @@ abstract class MetaModel
 			}
 		}
 		
+		// Prepare arguments (translate any object into scalars)
+		//
+		$aScalarArgs = array();
+		foreach($aArgs as $sArgName => $value)
+		{
+			if (self::IsValidObject($value))
+			{
+				$aScalarArgs[$sArgName] = $value->GetKey();
+				$aScalarArgs[$sArgName.'->id'] = $value->GetKey();
+			
+				$sClass = get_class($value);
+				foreach(self::ListAttributeDefs($sClass) as $sAttCode => $oAttDef)
+				{
+					$aScalarArgs[$sArgName.'->'.$sAttCode] = $value->Get($sAttCode);
+				}
+			}
+			else
+			{
+				$aScalarArgs[$sArgName] = (string) $value;
+			}
+		}
+		
 		//MyHelpers::var_dump_html($oSelect->RenderSelect($aOrderBy));
-		return $oSelect->RenderSelect($aOrderBy);
+		return $oSelect->RenderSelect($aOrderBy, $aScalarArgs);
 	}
 
 	public static function MakeDeleteQuery(DBObjectSearch $oFilter)

+ 59 - 47
core/oql/oql-lexer.php

@@ -84,6 +84,7 @@ class OQLLexerRaw
 	    	$rules = array(
     			'/^[ \t\n]+/',
     			'/^SELECT/',
+    			'/^FROM/',
     			'/^AS/',
     			'/^WHERE/',
     			'/^JOIN/',
@@ -131,6 +132,7 @@ class OQLLexerRaw
     			'/^[0-9]+|0x[0-9a-fA-F]+/',
     			'/^\"([^\\\\\"]|\\\\\"|\\\\\\\\)*\"|'.chr(94).chr(39).'([^\\\\'.chr(39).']|\\\\'.chr(39).'|\\\\\\\\)*'.chr(39).'/',
     			'/^([_a-zA-Z][_a-zA-Z0-9]*|`[^`]+`)/',
+    			'/^:([_a-zA-Z][_a-zA-Z0-9]*->[_a-zA-Z][_a-zA-Z0-9]*|[_a-zA-Z][_a-zA-Z0-9]*)/',
     			'/^\\./',
 	    	);
 	    	$match = false;
@@ -237,241 +239,251 @@ class OQLLexerRaw
     function yy_r1_2($yy_subpatterns)
     {
 
-	$this->token = OQLParser::AS_ALIAS;
+	$this->token = OQLParser::FROM;
     }
     function yy_r1_3($yy_subpatterns)
     {
 
-	$this->token = OQLParser::WHERE;
+	$this->token = OQLParser::AS_ALIAS;
     }
     function yy_r1_4($yy_subpatterns)
     {
 
-	$this->token = OQLParser::JOIN;
+	$this->token = OQLParser::WHERE;
     }
     function yy_r1_5($yy_subpatterns)
     {
 
-	$this->token = OQLParser::ON;
+	$this->token = OQLParser::JOIN;
     }
     function yy_r1_6($yy_subpatterns)
     {
 
-	$this->token = OQLParser::MATH_DIV;
+	$this->token = OQLParser::ON;
     }
     function yy_r1_7($yy_subpatterns)
     {
 
-	$this->token = OQLParser::MATH_MULT;
+	$this->token = OQLParser::MATH_DIV;
     }
     function yy_r1_8($yy_subpatterns)
     {
 
-	$this->token = OQLParser::MATH_PLUS;
+	$this->token = OQLParser::MATH_MULT;
     }
     function yy_r1_9($yy_subpatterns)
     {
 
-	$this->token = OQLParser::MATH_MINUS;
+	$this->token = OQLParser::MATH_PLUS;
     }
     function yy_r1_10($yy_subpatterns)
     {
 
-	$this->token = OQLParser::LOG_AND;
+	$this->token = OQLParser::MATH_MINUS;
     }
     function yy_r1_11($yy_subpatterns)
     {
 
-	$this->token = OQLParser::LOG_OR;
+	$this->token = OQLParser::LOG_AND;
     }
     function yy_r1_12($yy_subpatterns)
     {
 
-	$this->token = OQLParser::COMA;
+	$this->token = OQLParser::LOG_OR;
     }
     function yy_r1_13($yy_subpatterns)
     {
 
-	$this->token = OQLParser::PAR_OPEN;
+	$this->token = OQLParser::COMA;
     }
     function yy_r1_14($yy_subpatterns)
     {
 
-	$this->token = OQLParser::PAR_CLOSE;
+	$this->token = OQLParser::PAR_OPEN;
     }
     function yy_r1_15($yy_subpatterns)
     {
 
-	$this->token = OQLParser::EQ;
+	$this->token = OQLParser::PAR_CLOSE;
     }
     function yy_r1_16($yy_subpatterns)
     {
 
-	$this->token = OQLParser::NOT_EQ;
+	$this->token = OQLParser::EQ;
     }
     function yy_r1_17($yy_subpatterns)
     {
 
-	$this->token = OQLParser::GT;
+	$this->token = OQLParser::NOT_EQ;
     }
     function yy_r1_18($yy_subpatterns)
     {
 
-	$this->token = OQLParser::LT;
+	$this->token = OQLParser::GT;
     }
     function yy_r1_19($yy_subpatterns)
     {
 
-	$this->token = OQLParser::GE;
+	$this->token = OQLParser::LT;
     }
     function yy_r1_20($yy_subpatterns)
     {
 
-	$this->token = OQLParser::LE;
+	$this->token = OQLParser::GE;
     }
     function yy_r1_21($yy_subpatterns)
     {
 
-	$this->token = OQLParser::LIKE;
+	$this->token = OQLParser::LE;
     }
     function yy_r1_22($yy_subpatterns)
     {
 
-	$this->token = OQLParser::NOT_LIKE;
+	$this->token = OQLParser::LIKE;
     }
     function yy_r1_23($yy_subpatterns)
     {
 
-	$this->token = OQLParser::IN;
+	$this->token = OQLParser::NOT_LIKE;
     }
     function yy_r1_24($yy_subpatterns)
     {
 
-	$this->token = OQLParser::NOT_IN;
+	$this->token = OQLParser::IN;
     }
     function yy_r1_25($yy_subpatterns)
     {
 
-	$this->token = OQLParser::INTERVAL;
+	$this->token = OQLParser::NOT_IN;
     }
     function yy_r1_26($yy_subpatterns)
     {
 
-	$this->token = OQLParser::F_IF;
+	$this->token = OQLParser::INTERVAL;
     }
     function yy_r1_27($yy_subpatterns)
     {
 
-	$this->token = OQLParser::F_ELT;
+	$this->token = OQLParser::F_IF;
     }
     function yy_r1_28($yy_subpatterns)
     {
 
-	$this->token = OQLParser::F_COALESCE;
+	$this->token = OQLParser::F_ELT;
     }
     function yy_r1_29($yy_subpatterns)
     {
 
-	$this->token = OQLParser::F_CONCAT;
+	$this->token = OQLParser::F_COALESCE;
     }
     function yy_r1_30($yy_subpatterns)
     {
 
-	$this->token = OQLParser::F_SUBSTR;
+	$this->token = OQLParser::F_CONCAT;
     }
     function yy_r1_31($yy_subpatterns)
     {
 
-	$this->token = OQLParser::F_TRIM;
+	$this->token = OQLParser::F_SUBSTR;
     }
     function yy_r1_32($yy_subpatterns)
     {
 
-	$this->token = OQLParser::F_DATE;
+	$this->token = OQLParser::F_TRIM;
     }
     function yy_r1_33($yy_subpatterns)
     {
 
-	$this->token = OQLParser::F_DATE_FORMAT;
+	$this->token = OQLParser::F_DATE;
     }
     function yy_r1_34($yy_subpatterns)
     {
 
-	$this->token = OQLParser::F_CURRENT_DATE;
+	$this->token = OQLParser::F_DATE_FORMAT;
     }
     function yy_r1_35($yy_subpatterns)
     {
 
-	$this->token = OQLParser::F_NOW;
+	$this->token = OQLParser::F_CURRENT_DATE;
     }
     function yy_r1_36($yy_subpatterns)
     {
 
-	$this->token = OQLParser::F_TIME;
+	$this->token = OQLParser::F_NOW;
     }
     function yy_r1_37($yy_subpatterns)
     {
 
-	$this->token = OQLParser::F_TO_DAYS;
+	$this->token = OQLParser::F_TIME;
     }
     function yy_r1_38($yy_subpatterns)
     {
 
-	$this->token = OQLParser::F_FROM_DAYS;
+	$this->token = OQLParser::F_TO_DAYS;
     }
     function yy_r1_39($yy_subpatterns)
     {
 
-	$this->token = OQLParser::F_YEAR;
+	$this->token = OQLParser::F_FROM_DAYS;
     }
     function yy_r1_40($yy_subpatterns)
     {
 
-	$this->token = OQLParser::F_MONTH;
+	$this->token = OQLParser::F_YEAR;
     }
     function yy_r1_41($yy_subpatterns)
     {
 
-	$this->token = OQLParser::F_DAY;
+	$this->token = OQLParser::F_MONTH;
     }
     function yy_r1_42($yy_subpatterns)
     {
 
-	$this->token = OQLParser::F_DATE_ADD;
+	$this->token = OQLParser::F_DAY;
     }
     function yy_r1_43($yy_subpatterns)
     {
 
-	$this->token = OQLParser::F_DATE_SUB;
+	$this->token = OQLParser::F_DATE_ADD;
     }
     function yy_r1_44($yy_subpatterns)
     {
 
-	$this->token = OQLParser::F_ROUND;
+	$this->token = OQLParser::F_DATE_SUB;
     }
     function yy_r1_45($yy_subpatterns)
     {
 
-	$this->token = OQLParser::F_FLOOR;
+	$this->token = OQLParser::F_ROUND;
     }
     function yy_r1_46($yy_subpatterns)
     {
 
-	$this->token = OQLParser::NUMVAL;
+	$this->token = OQLParser::F_FLOOR;
     }
     function yy_r1_47($yy_subpatterns)
     {
 
-	$this->token = OQLParser::STRVAL;
+	$this->token = OQLParser::NUMVAL;
     }
     function yy_r1_48($yy_subpatterns)
     {
 
-	$this->token = OQLParser::NAME;
+	$this->token = OQLParser::STRVAL;
     }
     function yy_r1_49($yy_subpatterns)
     {
 
+	$this->token = OQLParser::NAME;
+    }
+    function yy_r1_50($yy_subpatterns)
+    {
+
+	$this->token = OQLParser::VARNAME;
+    }
+    function yy_r1_51($yy_subpatterns)
+    {
+
 	$this->token = OQLParser::DOT;
     }
 

+ 9 - 1
core/oql/oql-lexer.plex

@@ -55,7 +55,8 @@ class OQLLexerRaw
 %line    $this->line
 %matchlongest 1
 whitespace = /[ \t\n]+/
-select	  = "SELECT"
+select     = "SELECT"
+from       = "FROM"
 as_alias   = "AS"
 where	     = "WHERE"
 join	     = "JOIN"
@@ -103,6 +104,7 @@ f_floor    = "FLOOR"
 numval     = /[0-9]+|0x[0-9a-fA-F]+/
 strval     = /"([^\\"]|\\"|\\\\)*"|'.chr(94).chr(39).'([^\\'.chr(39).']|\\'.chr(39).'|\\\\)*'.chr(39).'/
 name       = /([_a-zA-Z][_a-zA-Z0-9]*|`[^`]+`)/
+varname    = /:([_a-zA-Z][_a-zA-Z0-9]*->[_a-zA-Z][_a-zA-Z0-9]*|[_a-zA-Z][_a-zA-Z0-9]*)/
 dot       = "."
 */
 
@@ -113,6 +115,9 @@ whitespace {
 select {
 	$this->token = OQLParser::SELECT;
 }
+from {
+	$this->token = OQLParser::FROM;
+}
 as_alias {
 	$this->token = OQLParser::AS_ALIAS;
 }
@@ -254,6 +259,9 @@ strval {
 name {
 	$this->token = OQLParser::NAME;
 }
+varname {
+	$this->token = OQLParser::VARNAME;
+}
 dot {
 	$this->token = OQLParser::DOT;
 }

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 475 - 461
core/oql/oql-parser.php


+ 15 - 2
core/oql/oql-parser.y

@@ -30,12 +30,21 @@ result ::= query(X). { $this->my_result = X; }
 result ::= condition(X). { $this->my_result = X; }
 
 query(A) ::= SELECT class_name(X) join_statement(J) where_statement(W). {
-	A = new OqlQuery(X, X, W, J);
+	A = new OqlObjectQuery(X, X, W, J);
 }
 query(A) ::= SELECT class_name(X) AS_ALIAS class_name(Y) join_statement(J) where_statement(W). {
-	A = new OqlQuery(X, Y, W, J);
+	A = new OqlObjectQuery(X, Y, W, J);
 }
 
+/*
+query(A) ::= SELECT field_id(E) FROM class_name(X) join_statement(J) where_statement(W). {
+	A = new OqlValueSetQuery(E, X, X, W, J);
+}
+query(A) ::= SELECT field_id(E) FROM class_name(X) AS_ALIAS class_name(Y) join_statement(J) where_statement(W). {
+	A = new OqlValueSetQuery(E, X, Y, W, J);
+}
+*/
+
 where_statement(A) ::= WHERE condition(C). { A = C;}
 where_statement(A) ::= . { A = null;}
 
@@ -67,6 +76,7 @@ condition(A) ::= expression_prio4(X). { A = X; }
 
 expression_basic(A) ::= scalar(X). { A = X; } 
 expression_basic(A) ::= field_id(X). { A = X; }
+expression_basic(A) ::= var_name(X). { A = X; }
 expression_basic(A) ::= func_name(X) PAR_OPEN arg_list(Y) PAR_CLOSE. { A = new FunctionOqlExpression(X, Y); }
 expression_basic(A) ::= PAR_OPEN expression_prio4(X) PAR_CLOSE. { A = X; }
 expression_basic(A) ::= expression_basic(X) list_operator(Y) list(Z). { A = new BinaryOqlExpression(X, Y, Z); }
@@ -122,6 +132,9 @@ field_id(A) ::= name(X). { A = new FieldOqlExpression(X); }
 field_id(A) ::= class_name(X) DOT name(Y). { A = new FieldOqlExpression(Y, X); }
 class_name(A) ::= name(X). { A=X; }
 
+
+var_name(A) ::= VARNAME(X). { A = new VariableOqlExpression(substr(X, 1)); }
+
 name(A) ::= NAME(X). {
 	if (X[0] == '`')
 	{

+ 15 - 3
core/oql/oqlinterpreter.class.inc.php

@@ -35,16 +35,28 @@ class OqlInterpreter
 		return $res;
 	}
 
-	public function ParseQuery()
+	public function ParseObjectQuery()
 	{
 		$oRes = $this->Parse();
-		if (!$oRes instanceof OqlQuery)
+		if (!$oRes instanceof OqlObjectQuery)
 		{
-			throw new OqlException('Expecting an OQL query', $this->m_sQuery, 0, 0, get_class($oRes), array('OqlQuery'));
+			throw new OqlException('Expecting an OQL query', $this->m_sQuery, 0, 0, get_class($oRes), array('OqlObjectQuery'));
 		}
 		return $oRes;
 	}
 
+/*
+	public function ParseValueSetQuery()
+	{
+		$oRes = $this->Parse();
+		if (!$oRes instanceof OqlValueSetQuery)
+		{
+			throw new OqlException('Expecting a value set query', $this->m_sQuery, 0, 0, get_class($oRes), array('OqlValueSetQuery'));
+		}
+		return $oRes;
+	}
+*/
+
 	public function ParseExpression()
 	{
 		$oRes = $this->Parse();

+ 40 - 10
core/oql/oqlquery.class.inc.php

@@ -111,6 +111,10 @@ class FieldOqlExpression extends FieldExpression
 	}
 }
 
+class VariableOqlExpression extends VariableExpression
+{
+}
+
 class ListOqlExpression extends ListExpression
 {
 }
@@ -122,19 +126,38 @@ class FunctionOqlExpression extends FunctionExpression
 class IntervalOqlExpression extends IntervalExpression
 {
 }
-class OqlQuery
+
+abstract class OqlQuery
 {
-	protected $m_oClass;
-	protected $m_oClassAlias;
 	protected $m_aJoins; // array of OqlJoinSpec
 	protected $m_oCondition; // condition tree (expressions)
 
+	public function __construct($oCondition = null, $aJoins = null)
+	{
+		$this->m_aJoins = $aJoins;
+		$this->m_oCondition = $oCondition;
+	}
+
+	public function GetJoins()
+	{
+		return $this->m_aJoins;
+	}
+	public function GetCondition()
+	{
+		return $this->m_oCondition;
+	}
+}
+
+class OqlObjectQuery extends OqlQuery
+{
+	protected $m_oClass;
+	protected $m_oClassAlias;
+
 	public function __construct($oClass, $oClassAlias = '', $oCondition = null, $aJoins = null)
 	{
 		$this->m_oClass = $oClass;
 		$this->m_oClassAlias = $oClassAlias;
-		$this->m_aJoins = $aJoins;
-		$this->m_oCondition = $oCondition;
+		parent::__construct($oCondition, $aJoins);
 	}
 
 	public function GetClass()
@@ -154,15 +177,22 @@ class OqlQuery
 	{
 		return $this->m_oClassAlias;
 	}
+}
 
-	public function GetJoins()
+
+class OqlValueSetQuery extends OqlObjectQuery
+{
+	protected $m_oSelectExpr;
+
+	public function __construct($oSelectExpr, $oClass, $oClassAlias = '', $oCondition = null, $aJoins = null)
 	{
-		return $this->m_aJoins;
+		$this->m_oSelectExpr = $oSelectExpr;
+		parent::__construct($oClass, $oClassAlias, $oCondition, $aJoins);
 	}
-	public function GetCondition()
+
+	public function GetSelectExpression()
 	{
-		return $this->m_oCondition;
+		return $this->m_oSelectExpr;
 	}
 }
-
 ?>

+ 7 - 4
core/sqlquery.class.inc.php

@@ -28,6 +28,9 @@ class TrueSQLExpression extends TrueExpression
 class FieldSQLExpression extends FieldExpression
 {
 }
+class VariableSQLExpression extends VariableExpression
+{
+}
 
 
 
@@ -212,7 +215,7 @@ class SQLQuery
 	}
 
 	// Interface, build the SQL query
-	public function RenderSelect($aOrderBy = array())
+	public function RenderSelect($aOrderBy = array(), $aArgs = array())
 	{
 		// The goal will be to complete the lists as we build the Joins
 		$aFrom = array();
@@ -224,7 +227,7 @@ class SQLQuery
 
 		$sSelect = self::ClauseSelect($aFields);
 		$sFrom   = self::ClauseFrom($aFrom);
-		$sWhere  = self::ClauseWhere($oCondition);
+		$sWhere  = self::ClauseWhere($oCondition, $aArgs);
 		$sOrderBy = self::ClauseOrderBy($aOrderBy);
 		if (!empty($sOrderBy))
 		{
@@ -294,9 +297,9 @@ class SQLQuery
 		return $sSetValues;
 	}
 
-	private static function ClauseWhere($oConditionExpr)
+	private static function ClauseWhere($oConditionExpr, $aArgs = array())
 	{
-		return $oConditionExpr->Render();
+		return $oConditionExpr->Render($aArgs);
 	}
 
 	private static function ClauseOrderBy($aOrderBy)

+ 38 - 6
core/valuesetdef.class.inc.php

@@ -104,14 +104,15 @@ class ValueSetObjects extends ValueSetDefinition
 	{
 		$this->m_aValues = array();
 		
-		$oFilter = DBObjectSearch::FromSibuSQL($this->m_sFilterExpr, $aArgs);
+		$oFilter = DBObjectSearch::FromSibusQL($this->m_sFilterExpr, $aArgs);
 		if (!$oFilter) return false;
 
-        if (empty($this->m_sValueAttCode))
-        {
-            $this->m_sValueAttCode = MetaModel::GetNameAttributeCode($oFilter->GetClass());
-        }
-		$oObjects = new DBObjectSet($oFilter, $this->m_aOrderBy);
+		if (empty($this->m_sValueAttCode))
+		{
+		   $this->m_sValueAttCode = MetaModel::GetNameAttributeCode($oFilter->GetClass());
+		}
+
+		$oObjects = new DBObjectSet($oFilter, $this->m_aOrderBy, $aArgs);
 		while ($oObject = $oObjects->Fetch())
 		{
 			$this->m_aValues[$oObject->GetKey()] = $oObject->GetAsHTML($this->m_sValueAttCode);
@@ -235,4 +236,35 @@ class ValueSetEnum extends ValueSetDefinition
 	}
 }
 
+
+/**
+ * Data model classes 
+ *
+ * @package     iTopORM
+ * @author      Romain Quetiez <romainquetiez@yahoo.fr>
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.itop.com
+ * @since       1.0
+ * @version     $itopversion$
+ */
+class ValueSetEnumClasses extends ValueSetEnum
+{
+	public function __construct($sCategory = '', $sAdditionalValues = '')
+	{
+		// First, build it from the series of additional values
+		parent::__construct($sAdditionalValues);
+
+		// Second: add the list of classes
+		foreach (MetaModel::GetClasses($sCategory) as $sClass)
+		{
+			$this->m_aValues[$sClass] = MetaModel::GetName($sClass);
+		}
+	}
+
+	protected function LoadValues($aArgs)
+	{
+		return true;
+	}
+}
+
 ?>

+ 2 - 2
pages/testlist.inc.php

@@ -75,7 +75,7 @@ class TestOQLParser extends TestFunction
 		$oOql = new OqlInterpreter($sQuery);
 		try
 		{
-			$oTrash = $oOql->ParseQuery();
+			$oTrash = $oOql->Parse(); // Not expecting a given format, otherwise use ParseExpression/ParseObjectQuery/ParseValueSetQuery
 			MyHelpers::var_dump_html($oTrash, true);
 		}
 		catch (OQLException $OqlException)
@@ -687,7 +687,7 @@ class TestQueriesOnFarm extends TestBizModel
 		try
 		{
 			//$oOql = new OqlInterpreter($sQuery);
-			//$oTrash = $oOql->ParseQuery();
+			//$oTrash = $oOql->ParseObjectQuery();
 			//MyHelpers::var_dump_html($oTrash, true);
 			$oMyFilter = DBObjectSearch::FromOQL($sQuery);
 		}

+ 90 - 0
pages/usermanagement_classproj.php

@@ -0,0 +1,90 @@
+<?php
+require_once('../application/application.inc.php');
+require_once('../application/itopwebpage.class.inc.php');
+
+require_once('../application/startup.inc.php');
+
+
+function ComputeProjections($oPage, $sScope)
+{
+	// Load the classes for a further usage
+	//
+	$aClasses = MetaModel::GetClasses();
+	
+	// Load the dimensions for a further usage
+	//
+	$aDimensions = array();
+	$oDimensionSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_Dimensions"));
+	while ($oDimension = $oDimensionSet->Fetch())
+	{
+		$aDimensions[$oDimension->GetKey()] = $oDimension; 
+	}
+	
+	// Load the class projections for a further usage
+	//
+	$aClassProj = array();
+	$oClassProjSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_ClassProjection"));
+	while ($oClassProj = $oClassProjSet->Fetch())
+	{
+		$aClassProjs[$oClassProj->Get('class')][$oClassProj->Get('dimensionid')] = $oClassProj; 
+	}
+	
+	// Setup display structure
+	//
+	$aDisplayConfig = array();
+	$aDisplayConfig['class'] = array('label' => 'Class', 'description' => 'Class');
+	$aDisplayConfig['object'] = array('label' => 'Object', 'description' => 'Projected object');
+	foreach ($aDimensions as $iDimension => $oDimension)
+	{
+		$aDisplayConfig['dim'.$oDimension->GetKey()] = array('label' => $oDimension->GetName(), 'description' => $oDimension->Get('description'));
+	}
+	
+	// Load objects
+	//
+	$aDisplayData = array();
+	$oObjectSet = new DBObjectSet(DBObjectSearch::FromOQL($sScope));
+	$sClass = $oObjectSet->GetClass();
+	while ($oObject = $oObjectSet->Fetch())
+	{
+		$aObjectProj = array();
+		$oObjectProj['class'] = $sClass;
+		$oObjectProj['object'] = $oObject->GetName();
+		foreach ($aDimensions as $iDimension => $oDimension)
+		{
+			// #@# to be moved, may be time consuming
+			$oDimension->CheckProjectionSpec($aClassProjs[$sClass][$iDimension]);
+
+			$aValues = $aClassProjs[$sClass][$iDimension]->ProjectObject($oObject);
+			$sValues = implode(', ', $aValues);
+			$oObjectProj['dim'.$oDimension->GetKey()] = htmlentities($sValues);
+		}
+	
+		$aDisplayData[] = $oObjectProj;
+	}
+
+	$oPage->table($aDisplayConfig, $aDisplayData);
+
+//$oPage->SetCurrentTab('Attributes');
+//$oPage->p("[<a href=\"?operation='list'\">All classes</a>]");
+//$oPage->add("</ul>\n");
+
+}
+
+
+require_once('../application/loginwebpage.class.inc.php');
+login_web_page::DoLogin(); // Check user rights and prompt if needed
+
+// Display the menu on the left
+$oContext = new UserContext();
+$oAppContext = new ApplicationContext();
+$iActiveNodeId = utils::ReadParam('menu', -1);
+$currentOrganization = utils::ReadParam('org_id', 1);
+$sScope = utils::ReadParam('scope', 'SELECT bizDevice');
+
+$oPage = new iTopWebPage("iTop user management - class projections", $currentOrganization);
+$oPage->no_cache();
+
+ComputeProjections($oPage, $sScope);
+$oPage->output();
+
+?>

+ 100 - 0
pages/usermanagement_profileproj.php

@@ -0,0 +1,100 @@
+<?php
+require_once('../application/application.inc.php');
+require_once('../application/itopwebpage.class.inc.php');
+
+require_once('../application/startup.inc.php');
+
+
+function ComputeProjections($oPage)
+{
+	// Load the profiles for a further usage
+	//
+	$aProfiles = array();
+	$oProfileSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_Profiles"));
+	while ($oProfile = $oProfileSet->Fetch())
+	{
+		$aProfiles[$oProfile->GetKey()] = $oProfile; 
+	}
+	
+	// Load the dimensions for a further usage
+	//
+	$aDimensions = array();
+	$oDimensionSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_Dimensions"));
+	while ($oDimension = $oDimensionSet->Fetch())
+	{
+		$aDimensions[$oDimension->GetKey()] = $oDimension; 
+	}
+	
+	// Load the profile projections for a further usage
+	//
+	$aProPro = array();
+	$oProProSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_ProfileProjection"));
+	while ($oProPro = $oProProSet->Fetch())
+	{
+		$aProPros[$oProPro->Get('profileid')][$oProPro->Get('dimensionid')] = $oProPro; 
+	}
+	
+	// Setup display structure
+	//
+	$aDisplayConfig = array();
+	$aDisplayConfig['user'] = array('label' => 'User', 'description' => 'User concerned by the projection');
+	$aDisplayConfig['profile'] = array('label' => 'Profile', 'description' => 'Profile in which the projection is specified');
+	foreach ($aDimensions as $iDimension => $oDimension)
+	{
+		$aDisplayConfig['dim'.$oDimension->GetKey()] = array('label' => $oDimension->GetName(), 'description' => $oDimension->Get('description'));
+	}
+	
+	// Load users, and create a record per couple user/profile
+	//
+	$aDisplayData = array();
+	$oUserSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_Users"));
+	while ($oUser = $oUserSet->Fetch())
+	{
+		$oUserProfileSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_UserProfile WHERE userid = :user->id"), array(), array('user' => $oUser));
+		while ($oUserProfile = $oUserProfileSet->Fetch())
+		{
+			$iProfile = $oUserProfile->Get('profileid');
+			$oProfile = $aProfiles[$iProfile];
+	
+			$aUserProfileProj = array();
+			$aUserProfileProj['user'] = $oUser->GetName();
+			$aUserProfileProj['profile'] = $oProfile->GetName();
+			foreach ($aDimensions as $iDimension => $oDimension)
+			{
+				// #@# to be moved, may be time consuming
+				$oDimension->CheckProjectionSpec($aProPros[$iProfile][$iDimension]);
+	
+				$aValues = $aProPros[$iProfile][$iDimension]->ProjectUser($oUser);
+				$sValues = implode(', ', $aValues);
+				$aUserProfileProj['dim'.$oDimension->GetKey()] = htmlentities($sValues);
+			}
+		
+			$aDisplayData[] = $aUserProfileProj;
+		}
+	}
+
+	$oPage->table($aDisplayConfig, $aDisplayData);
+
+//$oPage->SetCurrentTab('Attributes');
+//$oPage->p("[<a href=\"?operation='list'\">All classes</a>]");
+//$oPage->add("</ul>\n");
+
+}
+
+
+require_once('../application/loginwebpage.class.inc.php');
+login_web_page::DoLogin(); // Check user rights and prompt if needed
+
+// Display the menu on the left
+$oContext = new UserContext();
+$oAppContext = new ApplicationContext();
+$iActiveNodeId = utils::ReadParam('menu', -1);
+$currentOrganization = utils::ReadParam('org_id', 1);
+
+$oPage = new iTopWebPage("iTop user management - profile projections", $currentOrganization);
+$oPage->no_cache();
+
+ComputeProjections($oPage);
+$oPage->output();
+
+?>

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.