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)

SVN:trunk[88]
This commit is contained in:
Romain Quetiez
2009-07-24 13:14:51 +00:00
parent 2a7c89af21
commit 6b6f89f1c1
19 changed files with 1107 additions and 637 deletions

View File

@@ -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)
{

View File

@@ -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");

View File

@@ -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");

View File

@@ -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).'}';

View File

@@ -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);

View File

@@ -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;

View File

@@ -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, '')";
}

View File

@@ -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)

View File

@@ -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,239 +239,249 @@ 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;

View File

@@ -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;
}

File diff suppressed because it is too large Load Diff

View File

@@ -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] == '`')
{

View File

@@ -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();

View File

@@ -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_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;
protected $m_aJoins; // array of OqlJoinSpec
protected $m_oCondition; // condition tree (expressions)
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()
{
return $this->m_aJoins;
}
public function GetCondition()
{
return $this->m_oCondition;
}
}
class OqlValueSetQuery extends OqlObjectQuery
{
protected $m_oSelectExpr;
public function __construct($oSelectExpr, $oClass, $oClassAlias = '', $oCondition = null, $aJoins = null)
{
$this->m_oSelectExpr = $oSelectExpr;
parent::__construct($oClass, $oClassAlias, $oCondition, $aJoins);
}
public function GetSelectExpression()
{
return $this->m_oSelectExpr;
}
}
?>

View File

@@ -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)

View File

@@ -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;
}
}
?>

View File

@@ -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);
}

View File

@@ -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();
?>

View File

@@ -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();
?>