diff --git a/application/dashlet.class.inc.php b/application/dashlet.class.inc.php index b3c60c7be..dc51c3a41 100644 --- a/application/dashlet.class.inc.php +++ b/application/dashlet.class.inc.php @@ -1,5 +1,5 @@ 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; } } } diff --git a/core/modelreflection.class.inc.php b/core/modelreflection.class.inc.php index cdcd1efd5..3572493de 100644 --- a/core/modelreflection.class.inc.php +++ b/core/modelreflection.class.inc.php @@ -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); diff --git a/core/oql/oqlquery.class.inc.php b/core/oql/oqlquery.class.inc.php index 61ad9644b..168d60388 100644 --- a/core/oql/oqlquery.class.inc.php +++ b/core/oql/oqlquery.class.inc.php @@ -1,5 +1,5 @@ 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()); }