diff --git a/application/cmdbabstract.class.inc.php b/application/cmdbabstract.class.inc.php index 18baced5f..ce02e017e 100644 --- a/application/cmdbabstract.class.inc.php +++ b/application/cmdbabstract.class.inc.php @@ -156,17 +156,25 @@ abstract class cmdbAbstractObject extends CMDBObject { $iFlags = $this->GetAttributeFlags($sAttCode); $sClass = get_class($this); + $sInputId = $this->m_iFormId.'_'.$sAttCode; if (get_class($oAttDef) == 'AttributeLinkedSet') { // 1:n links $sTargetClass = $oAttDef->GetLinkedClass(); - $oPage->p(" ".$oAttDef->GetDescription()); + $oPage->p(MetaModel::GetClassIcon($sTargetClass)." ".$oAttDef->GetDescription()); $oFilter = new DBObjectSearch($sTargetClass); $oFilter->AddCondition($oAttDef->GetExtKeyToMe(), $this->GetKey(),'='); + $aParams = array( + 'target_attr' => $oAttDef->GetExtKeyToMe(), + 'object_id' => $this->GetKey(), + 'menu' => true, + 'default' => array($oAttDef->GetExtKeyToMe() => $this->GetKey()), + ); + $oBlock = new DisplayBlock($oFilter, 'list', false); - $oBlock->Display($oPage, 0); + $oBlock->Display($oPage, $sInputId, $aParams); } else // get_class($oAttDef) == 'AttributeLinkedSetIndirect' { @@ -179,7 +187,6 @@ abstract class cmdbAbstractObject extends CMDBObject $sValue = $this->Get($sAttCode); $sDisplayValue = $this->GetEditValue($sAttCode); $aArgs = array('this' => $this); - $sInputId = $this->m_iFormId.'_'.$sAttCode; $sHTMLValue = "".self::GetFormElementForField($oPage, $sClass, $sAttCode, $oAttDef, $sValue, $sDisplayValue, $sInputId, '', $iFlags, $aArgs).''; $aFieldsMap[$sAttCode] = $sInputId; $oPage->add($sHTMLValue); @@ -197,6 +204,7 @@ abstract class cmdbAbstractObject extends CMDBObject 'target_attr' => $oAttDef->GetExtKeyToMe(), 'object_id' => $this->GetKey(), 'menu' => true, + 'default' => array($oAttDef->GetExtKeyToMe() => $this->GetKey()), ); } else @@ -1081,7 +1089,7 @@ abstract class cmdbAbstractObject extends CMDBObject { $iFlags = $this->GetAttributeFlags($sAttCode); $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode); - if ( (!$oAttDef->IsLinkSet()) && (($iFlags & OPT_ATT_HIDDEN) == 0) ) + if ( (!$oAttDef->IsLinkSet()) && (($iFlags & OPT_ATT_HIDDEN) == 0)) { if ($oAttDef->IsWritable()) { @@ -1131,17 +1139,28 @@ abstract class cmdbAbstractObject extends CMDBObject $this->DisplayBareRelations($oPage, true); // Edit mode $oPage->SetCurrentTab(''); - $oPage->add("\n"); $oPage->add("\n"); - $oPage->add("\n"); $oPage->add("\n"); foreach($aExtraParams as $sName => $value) { $oPage->add("\n"); } $oPage->add($oAppContext->GetForForm()); - $oPage->add("    \n"); - $oPage->add("\n"); + if ($iKey > 0) + { + // The object already exists in the database, it's modification + $oPage->add("\n"); + $oPage->add("\n"); + $oPage->add("    \n"); + $oPage->add("\n"); + } + else + { + // The object does not exist in the database it's a creation + $oPage->add("\n"); + $oPage->add("    \n"); + $oPage->add("\n"); + } $oPage->add("\n"); $iFieldsCount = count($aFieldsMap); @@ -1149,7 +1168,7 @@ abstract class cmdbAbstractObject extends CMDBObject $oPage->add_script( <<add_ready_script( <<m_iFormId}', false); EOF ); } - + public static function DisplayCreationForm(WebPage $oPage, $sClass, $oObjectToClone = null, $aArgs = array(), $aExtraParams = array()) { - static $iCreationFormId = 0; - - $iCreationFormId++; - $iFieldIndex = 0; $oAppContext = new ApplicationContext(); - $aDetails = array(); - $aFieldsMap = array(); - $sOperation = ($oObjectToClone == null) ? 'apply_new' : 'apply_clone'; $sClass = ($oObjectToClone == null) ? $sClass : get_class($oObjectToClone); $sStateAttCode = MetaModel::GetStateAttributeCode($sClass); - $oPage->add("
\n"); $aStates = MetaModel::EnumStates($sClass); - $oPage->AddTabContainer(OBJECT_PROPERTIES_TAB); - $oPage->SetCurrentTabContainer(OBJECT_PROPERTIES_TAB); - $oPage->SetCurrentTab(Dict::S('UI:PropertiesTab')); - $oObj = MetaModel::NewObject($sClass); - if (isset($aArgs['default'])) - { - // Pre-populated default values - $aDefaultValues = $aArgs['default']; - foreach($aDefaultValues as $sAttCode => $value) - { - if (MetaModel::IsValidAttCode($sClass, $sAttCode)) - { - $oObj->Set($sAttCode, $value); - } - } - } - $aArgs['this'] = $oObj; - if ($oObjectToClone == null) { $sTargetState = MetaModel::GetDefaultState($sClass); + $oObj = MetaModel::NewObject($sClass); + $oObj->Set($sStateAttCode, $sTargetState); } else { - $sTargetState = $oObjectToClone->GetState(); + $oObj = clone $oObjectToClone; } - - $aDetailsList = self::FlattenZList(MetaModel::GetZListItems($sClass, 'details')); - //$aFullList = MetaModel::ListAttributeDefs($sClass); - $aList = array(); - // Compute the list of properties to display, first the attributes in the 'details' list, then - // all the remaining attributes that are not external fields - foreach($aDetailsList as $sAttCode) - { - $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode); - if (!$oAttDef->IsExternalField()) - { - $aList[] = $sAttCode; - } - } - foreach($aList as $sAttCode) - { - $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode); - $iFlags = isset($aStates[$sTargetState]['attribute_list'][$sAttCode]) ? $aStates[$sTargetState]['attribute_list'][$sAttCode] : 0; - - if ( (!$oAttDef->IsLinkSet()) && (($iFlags & OPT_ATT_HIDDEN) == 0) ) - { - if ($oAttDef->IsWritable()) - { - if ($oObjectToClone != null) - { - $sValue = $oObjectToClone->GetEditValue($sAttCode); - $aArgs['this'] = $oObjectToClone; - } - else - { - if(isset($aArgs['default'][$sAttCode])) - { - $sValue = $aArgs['default'][$sAttCode]; - } - else - { - $sValue = $oAttDef->GetDefaultValue(); - } - } - // Prepopulate with a default value -- but no display value... - $sDisplayValue = ''; - if (!empty($sValue)) - { - $aAllowedValues = MetaModel::GetAllowedValues_att($sClass, $sAttCode, $aArgs, ''); - switch (count($aAllowedValues)) - { - case 1: - case 0: - $sDisplayValue = $sValue; - break; - - default: - $sDisplayValue = $sValue; - foreach($aAllowedValues as $key => $display) - { - if ($key == $sValue) - { - $sDisplayValue = $display; - break; - } - } - } - } - if ($sStateAttCode == $sAttCode) - { - // State attribute is always read-only from the UI - $sHTMLValue = MetaModel::GetStateLabel($sClass, $sTargetState); - $aDetails[] = array('label' => $oAttDef->GetLabel(), 'value' => $sHTMLValue); - } - else - { - if ($iFlags & OPT_ATT_HIDDEN) - { - // Attribute is hidden, do nothing - } - else - { - if ($iFlags & OPT_ATT_READONLY) - { - // Attribute is read-only - $sHTMLValue = ($oObjectToClone == null) ? $sDisplayValue : $oObjectToClone->GetAsHTML($sAttCode); - } - else - { - $sFieldId = 'att_'.$iFieldIndex; - $sHTMLValue = "
".self::GetFormElementForField($oPage, $sClass, $sAttCode, $oAttDef, $sValue, $sDisplayValue, $sFieldId, '', $iFlags, $aArgs)."
"; - $aFieldsMap[$sFieldId] = $sAttCode; - $aDetails[] = array('label' => $oAttDef->GetLabel(), 'value' => $sHTMLValue); - $iFieldIndex++; - } - } - } - } - } - } - $oPage->details($aDetails); - // Now display the relations, one tab per relation - if ($oObjectToClone != null) - { - $oObj = $oObjectToClone; // Hmm, likely to fail... - } - else - { - $oObj = new $sClass; - } - $oObj->m_iFormId = $iCreationFormId; - $oObj->DisplayBareRelations($oPage, true); - /* - foreach($aList as $sAttCode) - { - $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode); - if ($oAttDef->IsLinkset()) - { - $oPage->SetCurrentTab($oAttDef->GetLabel()); - $oPage->p($oAttDef->GetDescription()); - - $iFlags = isset($aStates[$sTargetState]['attribute_list'][$sAttCode]) ? $aStates[$sTargetState]['attribute_list'][$sAttCode] : 0; - $sFieldId = 'att_'.$iFieldIndex; - $sValue = ($oObjectToClone == null) ? '' : $oObjectToClone->Get($sAttCode); - $sDisplayValue = ($oObjectToClone == null) ? '' : $oObjectToClone->GetEditValue($sAttCode); - $iFlags = isset($aStates[$sTargetState]['attribute_list'][$sAttCode]) ? $aStates[$sTargetState]['attribute_list'][$sAttCode] : 0; - $sHTMLValue = "
".self::GetFormElementForField($oPage, $sClass, $sAttCode, $oAttDef, $sValue, $sDisplayValue, $sFieldId, '', $iFlags, $aArgs)."
"; - $aFieldsMap[$sFieldId] = $sAttCode; - $aDetails[] = array('label' => $oAttDef->GetLabel(), 'value' => $sHTMLValue); - $iFieldIndex++; - $oPage->add($sHTMLValue); - } - } - $oPage->SetCurrentTab(''); - */ - - if ($oObjectToClone != null) - { - $oPage->add("GetKey()."\">\n"); - } - $oPage->add("\n"); - $oPage->add("\n"); - $oPage->add("\n"); - $oPage->add($oAppContext->GetForForm()); - foreach($aExtraParams as $sName => $value) - { - $oPage->add("\n"); - } - $oPage->add("    \n"); - $oPage->add("\n"); - $oPage->add("
\n"); - $aNewFieldsMap = array(); - foreach($aFieldsMap as $id => $sFieldCode) - { - $aNewFieldsMap[$sFieldCode] = $id; - } - $iFieldsCount = count($aFieldsMap); - $sJsonFieldsMap = json_encode($aNewFieldsMap); - - $oPage->add_script(" - // Initializes the object once at the beginning of the page... - var oWizardHelper = new WizardHelper('$sClass'); - oWizardHelper.SetFieldsMap($sJsonFieldsMap); - oWizardHelper.SetFieldsCount($iFieldsCount);"); - $oPage->add_ready_script("CheckFields('creation_form_{$iCreationFormId}', false);"); + return $oObj->DisplayModifyForm( $oPage, $aExtraParams = array()); } protected static function GetCSSClasses($aCSSClasses) diff --git a/application/displayblock.class.inc.php b/application/displayblock.class.inc.php index 826741fc7..46c1d590d 100644 --- a/application/displayblock.class.inc.php +++ b/application/displayblock.class.inc.php @@ -521,7 +521,15 @@ class DisplayBlock { $oAppContext = new ApplicationContext(); $sParams = $oAppContext->GetForLink(); - $sHtml .= $oPage->GetP("".Dict::Format('UI:ClickToCreateNew', Metamodel::GetName($sClass))."\n"); + $sDefaults = ''; + if (isset($this->m_aParams['default'])) + { + foreach($this->m_aParams['default'] as $sName => $sValue) + { + $sDefaults .= '&'.urlencode($sName).'='.urlencode($sValue); + } + } + $sHtml .= $oPage->GetP("".Dict::Format('UI:ClickToCreateNew', Metamodel::GetName($sClass))."\n"); } } } diff --git a/core/dbobject.class.php b/core/dbobject.class.php index 6d0ee602d..d4b31bb4f 100644 --- a/core/dbobject.class.php +++ b/core/dbobject.class.php @@ -915,6 +915,18 @@ abstract class DBObject $this->m_iKey = $iNewKey; return $this->DBInsert(); } + + /** + * This function is automatically called after cloning an object with the "clone" PHP language construct + * The purpose of this method is to reset the appropriate attributes of the object in + * order to make sure that the newly cloned object is really distinct from its clone + */ + public function __clone() + { + $this->m_bIsInDB = false; + $this->m_bDirty = true; + $this->m_iKey = self::GetNextTempId(get_class($this)); + } // To be optionaly overloaded protected function OnUpdate() diff --git a/pages/UI.php b/pages/UI.php index 758df0220..fcfa11b37 100644 --- a/pages/UI.php +++ b/pages/UI.php @@ -803,7 +803,20 @@ try { $aDefaults[$key] = $value; } - cmdbAbstractObject::DisplayCreationForm($oP, $sRealClass, null /* $oObjToClone */, array('default' => $aDefaults)); + // Set all the default values in an object and clone this "default" object + $oObjToClone = MetaModel::NewObject($sRealClass); + foreach($aDefaults as $sName => $value) + { + if (MetaModel::IsValidAttCode($sRealClass, $sName)) + { + $oAttDef = MetaModel::GetAttributeDef($sRealClass, $sName); + if ($oAttDef->IsWritable()) + { + $oObjToClone->Set($sName, $value); + } + } + } + cmdbAbstractObject::DisplayCreationForm($oP, $sRealClass, $oObjToClone, array('default' => $aDefaults)); $oP->add("\n"); } else