OQL normalization and dashlets have been made independent from the class MetaModel (reviewed the API)

SVN:trunk[2772]
This commit is contained in:
Romain Quetiez
2013-06-12 07:21:11 +00:00
parent ba9a50b6fb
commit 71cc6f7e6b
3 changed files with 82 additions and 40 deletions

View File

@@ -1,5 +1,5 @@
<?php
// Copyright (C) 2010-2012 Combodo SARL
// Copyright (C) 2012-2013 Combodo SARL
//
// This file is part of iTop.
//
@@ -536,16 +536,19 @@ abstract class DashletGroupBy extends Dashlet
$oSearch = DBObjectSearch::FromOQL($sOql);
$sClass = $oSearch->GetClass();
$aGroupBy = array();
foreach($this->oModelReflection->ListAttributeDefs($sClass) as $sAttCode => $oAttDef)
foreach($this->oModelReflection->ListAttributes($sClass) as $sAttCode => $sAttType)
{
if (!$oAttDef->IsScalar()) continue; // skip link sets
if ($oAttDef instanceof AttributeFriendlyName) continue;
if ($oAttDef instanceof AttributeExternalField) continue;
if ($sAttType == 'AttributeLinkedSet') continue;
if (is_subclass_of($sAttType, 'AttributeLinkedSet')) continue;
if ($sAttType == 'AttributeFriendlyName') continue;
if (is_subclass_of($sAttType, 'AttributeFriendlyName')) continue;
if ($sAttType == 'AttributeExternalField') continue;
if (is_subclass_of($sAttType, 'AttributeExternalField')) continue;
$sLabel = $oAttDef->GetLabel();
$sLabel = $this->oModelReflection->GetLabel($sClass, $sAttCode);
$aGroupBy[$sAttCode] = $sLabel;
if ($oAttDef instanceof AttributeDateTime)
if (is_subclass_of($sAttType, 'AttributeDateTime') || $sAttType == 'AttributeDateTime')
{
$aGroupBy[$sAttCode.':hour'] = Dict::Format('UI:DashletGroupBy:Prop-GroupBy:Select-Hour', $sLabel);
$aGroupBy[$sAttCode.':month'] = Dict::Format('UI:DashletGroupBy:Prop-GroupBy:Select-Month', $sLabel);
@@ -931,10 +934,13 @@ class DashletHeaderDynamic extends Dashlet
$oSearch = DBObjectSearch::FromOQL($this->aProperties['query']);
$sClass = $oSearch->GetClass();
$aGroupBy = array();
foreach($this->oModelReflection->ListAttributeDefs($sClass) as $sAttCode => $oAttDef)
foreach($this->oModelReflection->ListAttributes($sClass, 'AttributeEnum,AttributeFinalClass') as $sAttCode => $sAttType)
{
if (!$oAttDef instanceof AttributeEnum && (!$oAttDef instanceof AttributeFinalClass || !$this->oModelReflection->HasChildrenClasses($sClass))) continue;
$sLabel = $oAttDef->GetLabel();
if (is_subclass_of($sAttType, 'AttributeFinalClass') || ($sAttType == 'AttributeFinalClass'))
{
if (!$this->oModelReflection->HasChildrenClasses($sClass)) continue;
}
$sLabel = $this->oModelReflection->GetLabel($sClass, $sAttCode);
$aGroupBy[$sAttCode] = $sLabel;
}
$oField = new DesignerComboField('group_by', Dict::S('UI:DashletHeaderDynamic:Prop-GroupBy'), $this->aProperties['group_by']);
@@ -1050,11 +1056,12 @@ class DashletBadge extends Dashlet
foreach($this->oModelReflection->GetClasses('bizmodel') as $sClass)
{
foreach($this->oModelReflection->ListAttributeDefs($sClass) as $sAttCode => $oAttDef)
foreach($this->oModelReflection->ListAttributes($sClass, 'AttributeLinkedSetIndirect') as $sAttCode => $sAttType)
{
if ($oAttDef instanceof AttributeLinkedSetIndirect)
$sLinkedClass = $this->oModelReflection->GetAttributeProperty($sClass, $sAttCode, 'linked_class');
if ($sLinkedClass != null)
{
$aLinkClasses[$oAttDef->GetLinkedClass()] = true;
$aLinkClasses[$sLinkedClass] = true;
}
}
}

View File

@@ -30,13 +30,12 @@ interface ModelReflection
public function IsValidAttCode($sClass, $sAttCode);
public function GetName($sClass);
public function GetLabel($sClass, $sAttCodeEx);
public function ListAttributeDefs($sClass);
public function ListAttributes($sClass, $sScope = null);
public function GetAttributeProperty($sClass, $sAttCode, $sPropName);
public function GetAllowedValues_att($sClass, $sAttCode);
public function HasChildrenClasses($sClass);
public function GetClasses($sCategories = '');
public function IsValidClass($sClass);
public function GetExternalKeys($sClass);
public function GetAttributeDef($sClass, $sAttCode);
public function IsSameFamilyBranch($sClassA, $sClassB);
public function GetFiltersList($sClass);
public function IsValidFilterCode($sClass, $sFilterCode);
@@ -68,11 +67,55 @@ class ModelReflectionRuntime implements ModelReflection
return MetaModel::GetLabel($sClass, $sAttCodeEx);
}
public function ListAttributeDefs($sClass)
public function ListAttributes($sClass, $sScope = null)
{
return MetaModel::ListAttributeDefs($sClass);
$aScope = null;
if ($sScope != null)
{
$aScope = array();
foreach (explode(',', $sScope) as $sScopeClass)
{
$aScope[] = trim($sScopeClass);
}
}
$aAttributes = array();
foreach (MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef)
{
$sAttributeClass = get_class($oAttDef);
if ($aScope != null)
{
foreach ($aScope as $sScopeClass)
{
if (($sAttributeClass == $sScopeClass) || is_subclass_of($sAttributeClass, $sScopeClass))
{
$aAttributes[$sAttCode] = $sAttributeClass;
break;
}
}
}
else
{
$aAttributes[$sAttCode] = $sAttributeClass;
}
}
return $aAttributes;
}
public function GetAttributeProperty($sClass, $sAttCode, $sPropName, $default = null)
{
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
$aParams = $oAttDef->GetParams();
if (array_key_exists($sPropName, $aParams))
{
$ret = $aParams[$sPropName];
}
else
{
$ret = $default;
}
return $ret;
}
public function GetAllowedValues_att($sClass, $sAttCode)
{
return MetaModel::GetAllowedValues_att($sClass, $sAttCode);
@@ -93,16 +136,6 @@ class ModelReflectionRuntime implements ModelReflection
return MetaModel::IsValidClass($sClass);
}
public function GetExternalKeys($sClass)
{
return MetaModel::GetExternalKeys($sClass);
}
public function GetAttributeDef($sClass, $sAttCode)
{
return MetaModel::GetAttributeDef($sClass, $sAttCode);
}
public function IsSameFamilyBranch($sClassA, $sClassB)
{
return MetaModel::IsSameFamilyBranch($sClassA, $sClassB);

View File

@@ -1,5 +1,5 @@
<?php
// Copyright (C) 2010-2012 Combodo SARL
// Copyright (C) 2010-2013 Combodo SARL
//
// This file is part of iTop.
//
@@ -335,7 +335,7 @@ class OqlObjectQuery extends OqlQuery
if (!$oModelReflection->IsValidClass($sClass))
{
throw new UnknownClassOqlException($sSourceQuery, $this->GetClassDetails(), $oModelReflection->GetClasses('bizmodelx'));
throw new UnknownClassOqlException($sSourceQuery, $this->GetClassDetails(), $oModelReflection->GetClasses());
}
$aAliases = array($sClassAlias => $sClass);
@@ -387,18 +387,18 @@ class OqlObjectQuery extends OqlQuery
{
throw new OqlNormalizeException('Unknown class in join condition (right expression)', $sSourceQuery, $oRightField->GetParentDetails(), array_keys($aAliases));
}
$aExtKeys = array_keys($oModelReflection->GetExternalKeys($aAliases[$sFromClass]));
if (!in_array($sExtKeyAttCode, $aExtKeys))
$aExtKeys = $oModelReflection->ListAttributes($aAliases[$sFromClass], 'AttributeExternalKey');
if (!array_key_exists($sExtKeyAttCode, $aExtKeys))
{
throw new OqlNormalizeException('Unknown external key in join condition (left expression)', $sSourceQuery, $oLeftField->GetNameDetails(), $aExtKeys);
throw new OqlNormalizeException('Unknown external key in join condition (left expression)', $sSourceQuery, $oLeftField->GetNameDetails(), array_keys($aExtKeys));
}
if ($sFromClass == $sJoinClassAlias)
{
$oAttExtKey = $oModelReflection->GetAttributeDef($aAliases[$sFromClass], $sExtKeyAttCode);
if(!$oModelReflection->IsSameFamilyBranch($aAliases[$sToClass], $oAttExtKey->GetTargetClass()))
$sTargetClass = $oModelReflection->GetAttributeProperty($aAliases[$sFromClass], $sExtKeyAttCode, 'targetclass');
if(!$oModelReflection->IsSameFamilyBranch($aAliases[$sToClass], $sTargetClass))
{
throw new OqlNormalizeException("The joined class ($aAliases[$sFromClass]) is not compatible with the external key, which is pointing to {$oAttExtKey->GetTargetClass()}", $sSourceQuery, $oLeftField->GetNameDetails());
throw new OqlNormalizeException("The joined class ($aAliases[$sFromClass]) is not compatible with the external key, which is pointing to $sTargetClass", $sSourceQuery, $oLeftField->GetNameDetails());
}
}
else
@@ -434,12 +434,14 @@ class OqlObjectQuery extends OqlQuery
$iOperatorCode = TREE_OPERATOR_NOT_ABOVE_STRICT;
break;
}
$oAttExtKey = $oModelReflection->GetAttributeDef($aAliases[$sFromClass], $sExtKeyAttCode);
if(!$oModelReflection->IsSameFamilyBranch($aAliases[$sToClass], $oAttExtKey->GetTargetClass()))
$sTargetClass = $oModelReflection->GetAttributeProperty($aAliases[$sFromClass], $sExtKeyAttCode, 'targetclass');
if(!$oModelReflection->IsSameFamilyBranch($aAliases[$sToClass], $sTargetClass))
{
throw new OqlNormalizeException("The joined class ($aAliases[$sToClass]) is not compatible with the external key, which is pointing to {$oAttExtKey->GetTargetClass()}", $sSourceQuery, $oLeftField->GetNameDetails());
throw new OqlNormalizeException("The joined class ($aAliases[$sToClass]) is not compatible with the external key, which is pointing to $sTargetClass", $sSourceQuery, $oLeftField->GetNameDetails());
}
if(($iOperatorCode != TREE_OPERATOR_EQUALS) && !($oAttExtKey instanceof AttributeHierarchicalKey))
$aAttList = $oModelReflection->ListAttributes($aAliases[$sFromClass]);
$sAttType = $aAttList[$sExtKeyAttCode];
if(($iOperatorCode != TREE_OPERATOR_EQUALS) && !is_subclass_of($sAttType, 'AttributeHierarchicalKey') && ($sAttType != 'AttributeHierarchicalKey'))
{
throw new OqlNormalizeException("The specified tree operator $sOperator is not applicable to the key", $sSourceQuery, $oLeftField->GetNameDetails());
}