Ignore external keys and external fields when the target class is undefined

SVN:trunk[545]
This commit is contained in:
Romain Quetiez
2010-07-04 08:53:44 +00:00
parent 56a084cb7b
commit 99ba209152

View File

@@ -478,7 +478,7 @@ abstract class MetaModel
private static $m_aAttribDefs = array(); // array of ("classname" => array of attributes) private static $m_aAttribDefs = array(); // array of ("classname" => array of attributes)
private static $m_aAttribOrigins = array(); // array of ("classname" => array of ("attcode"=>"sourceclass")) private static $m_aAttribOrigins = array(); // array of ("classname" => array of ("attcode"=>"sourceclass"))
private static $m_aExtKeyFriends = array(); // array of ("classname" => array of ("indirect ext key attcode"=> array of ("relative ext field"))) private static $m_aExtKeyFriends = array(); // array of ("classname" => array of ("indirect ext key attcode"=> array of ("relative ext field")))
private static $m_aIgnoredLinkSets = array(); //array of ("classname" => array of ("attcode") private static $m_aIgnoredAttributes = array(); //array of ("classname" => array of ("attcode")
final static public function ListAttributeDefs($sClass) final static public function ListAttributeDefs($sClass)
{ {
@@ -917,9 +917,10 @@ abstract class MetaModel
if (is_subclass_of($sPHPClass, 'DBObject')) if (is_subclass_of($sPHPClass, 'DBObject'))
{ {
$sParent = get_parent_class($sPHPClass); $sParent = get_parent_class($sPHPClass);
if (array_key_exists($sParent, self::$m_aIgnoredLinkSets)) if (array_key_exists($sParent, self::$m_aIgnoredAttributes))
{ {
self::$m_aIgnoredLinkSets[$sPHPClass] = self::$m_aIgnoredLinkSets[$sParent]; // Inherit info about attributes to ignore
self::$m_aIgnoredAttributes[$sPHPClass] = self::$m_aIgnoredAttributes[$sParent];
} }
if (method_exists($sPHPClass, 'Init')) if (method_exists($sPHPClass, 'Init'))
{ {
@@ -1173,24 +1174,55 @@ abstract class MetaModel
} }
self::$m_aAttribDefs[$sTargetClass][$sAttCode]->OverloadParams($aParams); self::$m_aAttribDefs[$sTargetClass][$sAttCode]->OverloadParams($aParams);
} }
protected static function Init_IsKnownClass($sClass)
{
// Differs from self::IsValidClass()
// because it is being called before all the classes have been initialized
if (!class_exists($sClass)) return false;
if (!is_subclass_of($sClass, 'DBObject')) return false;
return true;
}
public static function Init_AddAttribute(AttributeDefinition $oAtt) public static function Init_AddAttribute(AttributeDefinition $oAtt)
{ {
$sTargetClass = self::GetCallersPHPClass("Init"); $sTargetClass = self::GetCallersPHPClass("Init");
// Some LinkedSet attributes could refer to a class // Some attributes could refer to a class
// declared in a module which is currently not installed/active // declared in a module which is currently not installed/active
// We simply discard those attributes // We simply discard those attributes
//
if ($oAtt->IsLinkSet()) if ($oAtt->IsLinkSet())
{ {
$sRemoteClass = $oAtt->GetLinkedClass(); $sRemoteClass = $oAtt->GetLinkedClass();
// Note: I would not use IsValidClass here because not all the classes if (!self::Init_IsKnownClass($sRemoteClass))
// have been initialized so far
if (!class_exists($sRemoteClass) || !is_subclass_of($sRemoteClass, 'DBObject'))
{ {
self::$m_aIgnoredLinkSets[$sTargetClass][$oAtt->GetCode()] = $sRemoteClass; self::$m_aIgnoredAttributes[$sTargetClass][$oAtt->GetCode()] = $sRemoteClass;
return; return;
} }
} }
elseif($oAtt->IsExternalKey())
{
$sRemoteClass = $oAtt->GetTargetClass();
if (!self::Init_IsKnownClass($sRemoteClass))
{
self::$m_aIgnoredAttributes[$sTargetClass][$oAtt->GetCode()] = $sRemoteClass;
return;
}
}
elseif($oAtt->IsExternalField())
{
$sExtKeyAttCode = $oAtt->GetKeyAttCode();
if (isset(self::$m_aIgnoredAttributes[$sTargetClass][$sExtKeyAttCode]))
{
// The corresponding external key has already been ignored
self::$m_aIgnoredAttributes[$sTargetClass][$oAtt->GetCode()] = self::$m_aIgnoredAttributes[$sTargetClass][$sExtKeyAttCode];
return;
}
// #@# todo - Check if the target attribute is still there
// this is not simple to implement because is involves
// several passes (the load order has a significant influence on that)
}
self::$m_aAttribDefs[$sTargetClass][$oAtt->GetCode()] = $oAtt; self::$m_aAttribDefs[$sTargetClass][$oAtt->GetCode()] = $oAtt;
self::$m_aAttribOrigins[$sTargetClass][$oAtt->GetCode()] = $sTargetClass; self::$m_aAttribOrigins[$sTargetClass][$oAtt->GetCode()] = $sTargetClass;
@@ -1208,11 +1240,12 @@ abstract class MetaModel
$sTargetClass = self::GetCallersPHPClass("Init"); $sTargetClass = self::GetCallersPHPClass("Init");
// Discard LinkedSets that do not make sense (missing classes in the current module combination) // Discard attributes that do not make sense
// (missing classes in the current module combination, resulting in irrelevant ext key or link set)
// //
foreach($aItems as $iFoo => $sAttCode) foreach($aItems as $iFoo => $sAttCode)
{ {
if (isset(self::$m_aIgnoredLinkSets[$sTargetClass][$sAttCode])) if (isset(self::$m_aIgnoredAttributes[$sTargetClass][$sAttCode]))
{ {
unset($aItems[$iFoo]); unset($aItems[$iFoo]);
} }
@@ -1244,6 +1277,15 @@ abstract class MetaModel
// The inherited configuration could be overriden // The inherited configuration could be overriden
$aStateDef['attribute_list'] = array_merge($aToInherit['attribute_list'], $aStateDef['attribute_list']); $aStateDef['attribute_list'] = array_merge($aToInherit['attribute_list'], $aStateDef['attribute_list']);
} }
foreach($aStateDef['attribute_list'] as $sAttCode => $iFlags)
{
if (isset(self::$m_aIgnoredAttributes[$sTargetClass][$sAttCode]))
{
unset($aStateDef['attribute_list'][$sAttCode]);
}
}
self::$m_aStates[$sTargetClass][$sStateCode] = $aStateDef; self::$m_aStates[$sTargetClass][$sStateCode] = $aStateDef;
// by default, create an empty set of transitions associated to that state // by default, create an empty set of transitions associated to that state