From 77159e876602e7db74d0216cb59f0f70167bd85f Mon Sep 17 00:00:00 2001 From: Romain Quetiez Date: Tue, 31 Aug 2010 21:11:11 +0000 Subject: [PATCH] Notification were not working well with class hierarchy (not in Trac at that time) SVN:trunk[734] --- application/cmdbabstract.class.inc.php | 5 ++-- core/dbobject.class.php | 5 ++-- core/metamodel.class.php | 35 ++++++++++++++++++++++++-- pages/schema.php | 3 ++- 4 files changed, 41 insertions(+), 7 deletions(-) diff --git a/application/cmdbabstract.class.inc.php b/application/cmdbabstract.class.inc.php index b241cbe97..f25cfefe2 100644 --- a/application/cmdbabstract.class.inc.php +++ b/application/cmdbabstract.class.inc.php @@ -238,14 +238,15 @@ abstract class cmdbAbstractObject extends CMDBObject // If any trigger has been found then display a tab with notifications // $sClass = get_class($this); - $oTriggerSet = new CMDBObjectSet(DBObjectSearch::FromOQL("SELECT TriggerOnObject AS T WHERE T.target_class = '$sClass'")); + $sClassList = implode("', '", MetaModel::EnumParentClasses($sClass, ENUM_PARENT_CLASSES_ALL)); + $oTriggerSet = new CMDBObjectSet(DBObjectSearch::FromOQL("SELECT TriggerOnObject AS T WHERE T.target_class IN ('$sClassList')")); if ($oTriggerSet->Count() > 0) { $oPage->SetCurrentTab(Dict::S('UI:NotificationsTab')); // Display notifications regarding the object $iId = $this->GetKey(); - $oNotifSet = new CMDBObjectSet(DBObjectSearch::FromOQL("SELECT EventNotificationEmail AS Ev JOIN TriggerOnObject AS T ON Ev.trigger_id = T.id WHERE T.target_class = '$sClass' AND Ev.object_id = $iId")); + $oNotifSet = new CMDBObjectSet(DBObjectSearch::FromOQL("SELECT EventNotificationEmail AS Ev JOIN TriggerOnObject AS T ON Ev.trigger_id = T.id WHERE T.target_class IN ('$sClassList') AND Ev.object_id = $iId")); self::DisplaySet($oPage, $oNotifSet); } } diff --git a/core/dbobject.class.php b/core/dbobject.class.php index ae10c3130..331a0e933 100644 --- a/core/dbobject.class.php +++ b/core/dbobject.class.php @@ -1079,13 +1079,14 @@ abstract class DBObject // Change state triggers... $sClass = get_class($this); - $oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT TriggerOnStateLeave AS t WHERE t.target_class='$sClass' AND t.state='$sPreviousState'")); + $sClassList = implode("', '", MetaModel::EnumParentClasses($sClass, ENUM_PARENT_CLASSES_ALL)); + $oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT TriggerOnStateLeave AS t WHERE t.target_class IN ('$sClassList') AND t.state='$sPreviousState'")); while ($oTrigger = $oSet->Fetch()) { $oTrigger->DoActivate($this->ToArgs('this')); } - $oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT TriggerOnStateEnter AS t WHERE t.target_class='$sClass' AND t.state='$sNewState'")); + $oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT TriggerOnStateEnter AS t WHERE t.target_class IN ('$sClassList') AND t.state='$sNewState'")); while ($oTrigger = $oSet->Fetch()) { $oTrigger->DoActivate($this->ToArgs('this')); diff --git a/core/metamodel.class.php b/core/metamodel.class.php index 763ca5ffe..35d0e9ecc 100644 --- a/core/metamodel.class.php +++ b/core/metamodel.class.php @@ -47,6 +47,18 @@ define('ENUM_CHILD_CLASSES_EXCLUDETOP', 1); * @package iTopORM */ define('ENUM_CHILD_CLASSES_ALL', 2); +/** + * add some description here... + * + * @package iTopORM + */ +define('ENUM_PARENT_CLASSES_EXCLUDELEAF', 1); +/** + * add some description here... + * + * @package iTopORM + */ +define('ENUM_PARENT_CLASSES_ALL', 2); /** * Specifies that this attribute is visible/editable.... normal (default config) @@ -1209,6 +1221,19 @@ abstract class MetaModel self::$m_aAttribOrigins[$sTargetClass] = array(); } self::$m_aAttribDefs[$sTargetClass] = self::object_array_mergeclone(self::$m_aAttribDefs[$sTargetClass], self::$m_aAttribDefs[$sSourceClass]); + // Note: while investigating on some issues related to attribute inheritance, + // I found out that the notion of "host class" is unclear + // For stability reasons, and also because a workaround has been found + // I leave it unchanged, but later it could be a good thing to force + // attribute host class to the new class (See code below) + // In that case, we will have to review the attribute labels + // (currently relying on host class => the original declaration + // of the attribute) + // See TRAC #148 + // foreach(self::$m_aAttribDefs[$sTargetClass] as $sAttCode => $oAttDef) + // { + // $oAttDef->SetHostClass($sTargetClass); + // } self::$m_aAttribOrigins[$sTargetClass] = array_merge(self::$m_aAttribOrigins[$sTargetClass], self::$m_aAttribOrigins[$sSourceClass]); } // Build root class information @@ -1417,10 +1442,16 @@ abstract class MetaModel { return array_unique(self::$m_aRootClasses); } - public static function EnumParentClasses($sClass) + public static function EnumParentClasses($sClass, $iOption = ENUM_PARENT_CLASSES_EXCLUDELEAF) { self::_check_subclass($sClass); - return self::$m_aParentClasses[$sClass]; + if ($iOption == ENUM_PARENT_CLASSES_EXCLUDELEAF) + { + return self::$m_aParentClasses[$sClass]; + } + $aRes = self::$m_aParentClasses[$sClass]; + $aRes[] = $sClass; + return $aRes; } public static function EnumChildClasses($sClass, $iOption = ENUM_CHILD_CLASSES_EXCLUDETOP) { diff --git a/pages/schema.php b/pages/schema.php index ee4f2df00..8713cae6a 100644 --- a/pages/schema.php +++ b/pages/schema.php @@ -255,7 +255,8 @@ function DisplayLifecycle($oPage, $sClass) */ function DisplayTriggers($oPage, $sClass) { - $oSet = new CMDBObjectSet(DBObjectSearch::FromOQL("SELECT TriggerOnStateChange WHERE target_class = '$sClass'")); + $sClassList = implode("', '", MetaModel::EnumParentClasses($sClass, ENUM_PARENT_CLASSES_ALL)); + $oSet = new CMDBObjectSet(DBObjectSearch::FromOQL("SELECT TriggerOnObject WHERE target_class IN ('$sClassList')")); cmdbAbstractObject::DisplaySet($oPage, $oSet); }