diff --git a/application/cmdbabstract.class.inc.php b/application/cmdbabstract.class.inc.php
index 97f88356d..3a1af6b66 100644
--- a/application/cmdbabstract.class.inc.php
+++ b/application/cmdbabstract.class.inc.php
@@ -39,7 +39,40 @@ require_once(APPROOT.'/application/ui.passwordwidget.class.inc.php');
require_once(APPROOT.'/application/ui.extkeywidget.class.inc.php');
require_once(APPROOT.'/application/ui.htmleditorwidget.class.inc.php');
-abstract class cmdbAbstractObject extends CMDBObject
+/**
+ * All objects to be displayed in the application (either as a list or as details)
+ * must implement this interface.
+ */
+interface iDisplay
+{
+
+ /**
+ * Maps the given context parameter name to the appropriate filter/search code for this class
+ * @param string $sContextParam Name of the context parameter, i.e. 'org_id'
+ * @return string Filter code, i.e. 'customer_id'
+ */
+ public static function MapContextParam($sContextParam);
+ /**
+ * This function returns a 'hilight' CSS class, used to hilight a given row in a table
+ * There are currently (i.e defined in the CSS) 4 possible values HILIGHT_CLASS_CRITICAL,
+ * HILIGHT_CLASS_WARNING, HILIGHT_CLASS_OK, HILIGHT_CLASS_NONE
+ * To Be overridden by derived classes
+ * @param void
+ * @return String The desired higlight class for the object/row
+ */
+ public function GetHilightClass();
+ /**
+ * Returns the relative path to the page that handles the display of the object
+ * @return string
+ */
+ public static function GetUIPage();
+ /**
+ * Displays the details of the object
+ */
+ public function DisplayDetails(WebPage $oPage, $bEditMode = false);
+}
+
+abstract class cmdbAbstractObject extends CMDBObject implements iDisplay
{
protected $m_iFormId; // The ID of the form used to edit the object (when in edition mode !)
@@ -48,40 +81,6 @@ abstract class cmdbAbstractObject extends CMDBObject
return '../pages/UI.php';
}
- public static function ComputeUIPage($sClass)
- {
- static $aUIPagesCache = array(); // Cache to store the php page used to display each class of object
- if (!isset($aUIPagesCache[$sClass]))
- {
- $UIPage = false;
- if (is_callable("$sClass::GetUIPage"))
- {
- $UIPage = eval("return $sClass::GetUIPage();"); // May return false in case of error
- }
- $aUIPagesCache[$sClass] = $UIPage === false ? './UI.php' : $UIPage;
- }
- $sPage = $aUIPagesCache[$sClass];
- return $sPage;
- }
-
- protected static function MakeHyperLink($sObjClass, $sObjKey, $sLabel = '')
- {
- if ($sObjKey <= 0) return ''.Dict::S('UI:UndefinedObject').''; // Objects built in memory have negative IDs
-
- $oAppContext = new ApplicationContext();
- $sPage = self::ComputeUIPage($sObjClass);
- $sAbsoluteUrl = utils::GetAbsoluteUrlPath();
-
- // Safety net
- //
- if (empty($sLabel))
- {
- $sLabel = MetaModel::GetName($sObjClass)." #$sObjKey";
- }
- $sHint = MetaModel::GetName($sObjClass)."::$sObjKey";
- return "GetForLink()."\" title=\"$sHint\">$sLabel";
- }
-
function DisplayBareHeader(WebPage $oPage, $bEditMode = false)
{
// Standard Header with name, actions menu and history block
diff --git a/core/dbobject.class.php b/core/dbobject.class.php
index 97f696d2d..fbaa96d06 100644
--- a/core/dbobject.class.php
+++ b/core/dbobject.class.php
@@ -482,14 +482,56 @@ abstract class DBObject
protected static function MakeHyperLink($sObjClass, $sObjKey, $sLabel = '')
{
- if ($sObjKey == 0) return 'undefined';
+ if ($sObjKey <= 0) return ''.Dict::S('UI:UndefinedObject').''; // Objects built in memory have negative IDs
- return MetaModel::GetName($sObjClass)."::$sObjKey";
+ $oAppContext = new ApplicationContext();
+ $sPage = self::ComputeUIPage($sObjClass);
+ $sAbsoluteUrl = utils::GetAbsoluteUrlPath();
+
+ // Safety net
+ //
+ if (empty($sLabel))
+ {
+ $sLabel = MetaModel::GetName($sObjClass)." #$sObjKey";
+ }
+ $sHint = MetaModel::GetName($sObjClass)."::$sObjKey";
+ return "GetForLink()."\" title=\"$sHint\">$sLabel";
}
public function GetHyperlink()
{
- return $this->MakeHyperLink(get_class($this), $this->GetKey(), $this->GetName());
+ if ($this->IsNew()) return ''.Dict::S('UI:UndefinedObject').''; // Objects built in memory have negative IDs
+
+ $oAppContext = new ApplicationContext();
+ $sPage = $this->GetUIPage();
+ $sAbsoluteUrl = utils::GetAbsoluteUrlPath();
+ $sObjClass = get_class($this);
+ $sObjKey = $this->GetKey();
+
+ $sLabel = $this->GetName();
+ $sHint = MetaModel::GetName($sObjClass)."::$sObjKey";
+ return "GetForLink()."\" title=\"$sHint\">$sLabel";
+ }
+
+ public static function ComputeUIPage($sClass)
+ {
+ static $aUIPagesCache = array(); // Cache to store the php page used to display each class of object
+ if (!isset($aUIPagesCache[$sClass]))
+ {
+ $UIPage = false;
+ if (is_callable("$sClass::GetUIPage"))
+ {
+ $UIPage = eval("return $sClass::GetUIPage();"); // May return false in case of error
+ }
+ $aUIPagesCache[$sClass] = $UIPage === false ? './UI.php' : $UIPage;
+ }
+ $sPage = $aUIPagesCache[$sClass];
+ return $sPage;
+ }
+
+ public static function GetUIPage()
+ {
+ return 'UI.php';
}
diff --git a/dictionaries/dictionary.itop.core.php b/dictionaries/dictionary.itop.core.php
index 5e9d7a2a3..b121db8a5 100644
--- a/dictionaries/dictionary.itop.core.php
+++ b/dictionaries/dictionary.itop.core.php
@@ -539,7 +539,12 @@ Dict::Add('EN US', 'English', 'English', array(
'Core:Synchro:Nb_Class:Objects' => '%1$s: %2$s',
'Class:SynchroDataSource/Error:AtLeastOneReconciliationKeyMustBeSpecified' => 'At Least one reconciliation key must be specified.',
'Class:SynchroDataSource/Error:DeleteRetentionDurationMustBeSpecified' => 'A delete retention period must be specified, since objects are to be deleted after being marked as obsolete',
- 'Class:SynchroDataSource/Error:DeletePolicyUpdateMustBeSpecified' => 'Obsolete objects are to be updated, but no update is specified.',
+ 'Class:SynchroDataSource/Error:DeletePolicyUpdateMustBeSpecified' => 'Obsolete objects are to be updated, but no update is specified.',
+ 'Core:SynchroReplica:PublicData' => 'Public Data',
+ 'Core:SynchroReplica:PrivateDetails' => 'Private Details',
+ 'Core:SynchroReplica:BackToDataSource' => 'Go Back to the Synchro Data Source: %1$s',
+ 'Core:SynchroReplica:ListOfReplicas' => 'List of Replica',
+
));
//
diff --git a/synchro/replica.php b/synchro/replica.php
new file mode 100644
index 000000000..d02838a46
--- /dev/null
+++ b/synchro/replica.php
@@ -0,0 +1,83 @@
+DisplayDetails($oP);
+ break;
+
+ case 'oql':
+ $sOQL = utils::ReadParam('oql', null);
+ if ($sOQL == null)
+ {
+ throw new ApplicationException(Dict::Format('UI:Error:1ParametersMissing', 'oql'));
+ }
+ $oP->add('
";
}
protected function ProcessLog($oLastLog)
@@ -378,6 +415,37 @@ EOF
{
parent::DoCheckToWrite();
+ if ($this->IsNew())
+ {
+ // When inserting a new datasource object, also create the SynchroAttribute objects
+ // for each field of the target class
+ // Create all the SynchroAttribute records
+ $oAttributeSet = $this->Get('attribute_list');
+ foreach(MetaModel::ListAttributeDefs($this->GetTargetClass()) as $sAttCode=>$oAttDef)
+ {
+ if ($oAttDef->IsScalar() && $oAttDef->IsWritable())
+ {
+ $oAttDef = MetaModel::GetAttributeDef($this->GetTargetClass(), $sAttCode);
+ if ($oAttDef->IsExternalKey())
+ {
+ $oAttribute = new SynchroAttExtKey();
+ $oAttribute->Set('reconciliation_attcode', ''); // Blank means by pkey
+ }
+ else
+ {
+ $oAttribute = new SynchroAttribute();
+ }
+ $oAttribute->Set('sync_source_id', $this->GetKey());
+ $oAttribute->Set('attcode', $sAttCode);
+ $oAttribute->Set('reconcile', MetaModel::IsReconcKey($this->GetTargetClass(), $sAttCode) ? 1 : 0);
+ $oAttribute->Set('update', 1);
+ $oAttribute->Set('update_policy', 'master_locked');
+ $oAttributeSet->AddObject($oAttribute);
+ }
+ }
+ $this->Set('attribute_list', $oAttributeSet);
+ }
+
// Check that there is at least one reconciliation key defined
if ($this->Get('reconciliation_policy') == 'use_attributes')
{
@@ -425,38 +493,6 @@ EOF
return $sTable;
}
- /**
- * When inserting a new datasource object, also create the SynchroAttribute objects
- * for each field of the target class
- */
- protected function OnInsert()
- {
- // Create all the SynchroAttribute records
- $oAttributeSet = $this->Get('attribute_list');
- foreach(MetaModel::ListAttributeDefs($this->GetTargetClass()) as $sAttCode=>$oAttDef)
- {
- if ($oAttDef->IsScalar() && $oAttDef->IsWritable())
- {
- $oAttDef = MetaModel::GetAttributeDef($this->GetTargetClass(), $sAttCode);
- if ($oAttDef->IsExternalKey())
- {
- $oAttribute = new SynchroAttExtKey();
- $oAttribute->Set('reconciliation_attcode', ''); // Blank means by pkey
- }
- else
- {
- $oAttribute = new SynchroAttribute();
- }
- $oAttribute->Set('sync_source_id', $this->GetKey());
- $oAttribute->Set('attcode', $sAttCode);
- $oAttribute->Set('reconcile', MetaModel::IsReconcKey($this->GetTargetClass(), $sAttCode) ? 1 : 0);
- $oAttribute->Set('update', 1);
- $oAttribute->Set('update_policy', 'master_locked');
- $oAttributeSet->AddObject($oAttribute);
- }
- }
- $this->Set('attribute_list', $oAttributeSet);
- }
/**
* When the new datasource has been created, let's create the synchro_data table
* that will hold the data records and the correspoding triggers which will maintain
@@ -1084,7 +1120,7 @@ class SynchroLog extends DBObject
}
-class SynchroReplica extends DBObject
+class SynchroReplica extends DBObject implements iDisplay
{
static $aSearches = array(); // Cache of OQL queries used for reconciliation (per data source)
@@ -1460,6 +1496,94 @@ class SynchroReplica extends DBObject
return $aData[$sColumnName];
}
+
+ /**
+ * Maps the given context parameter name to the appropriate filter/search code for this class
+ * @param string $sContextParam Name of the context parameter, i.e. 'org_id'
+ * @return string Filter code, i.e. 'customer_id'
+ */
+ public static function MapContextParam($sContextParam)
+ {
+ if ($sContextParam == 'menu')
+ {
+ return null;
+ }
+ else
+ {
+ return $sContextParam;
+ }
+ }
+
+ /**
+ * This function returns a 'hilight' CSS class, used to hilight a given row in a table
+ * There are currently (i.e defined in the CSS) 4 possible values HILIGHT_CLASS_CRITICAL,
+ * HILIGHT_CLASS_WARNING, HILIGHT_CLASS_OK, HILIGHT_CLASS_NONE
+ * To Be overridden by derived classes
+ * @param void
+ * @return String The desired higlight class for the object/row
+ */
+ public function GetHilightClass()
+ {
+ // Possible return values are:
+ // HILIGHT_CLASS_CRITICAL, HILIGHT_CLASS_WARNING, HILIGHT_CLASS_OK, HILIGHT_CLASS_NONE
+ return HILIGHT_CLASS_NONE; // Not hilighted by default
+ }
+
+ public static function GetUIPage()
+ {
+ return '../synchro/replica.php';
+ }
+
+ function DisplayDetails(WebPage $oPage, $bEditMode = false)
+ {
+ // Object's details
+ //$this->DisplayBareHeader($oPage, $bEditMode);
+ $oPage->AddTabContainer(OBJECT_PROPERTIES_TAB);
+ $oPage->SetCurrentTabContainer(OBJECT_PROPERTIES_TAB);
+ $oPage->SetCurrentTab(Dict::S('UI:PropertiesTab'));
+ $this->DisplayBareProperties($oPage, $bEditMode);
+ }
+
+ function DisplayBareProperties(WebPage $oPage, $bEditMode = false)
+ {
+ if ($bEditMode) return; // Not editable
+
+ $oPage->add('