diff --git a/application/cmdbabstract.class.inc.php b/application/cmdbabstract.class.inc.php index d81da14f1..64693fa20 100644 --- a/application/cmdbabstract.class.inc.php +++ b/application/cmdbabstract.class.inc.php @@ -299,24 +299,31 @@ abstract class cmdbAbstractObject extends CMDBObject $oPage->add(''); foreach($aCols as $sColIndex => $aFieldsets) { - $aDetails[$sTab][$sColIndex] = array(); + $oPage->add(''); } $oPage->add('
'); + //$aDetails[$sTab][$sColIndex] = array(); foreach($aFieldsets as $sFieldsetName => $aFields) { - //if ($sFieldsetName == '') - //{ - foreach($aFields as $sAttCode) + $aDetails[$sTab][$sColIndex] = array(); + if (!empty($sFieldsetName)) + { + $oPage->add('
'); + $oPage->add(''.Dict::S($sFieldsetName).''); + } + foreach($aFields as $sAttCode) + { + $val = $this->GetFieldAsHtml($sClass, $sAttCode, $sStateAttCode); + if ($val != null) { - $val = $this->GetFieldAsHtml($sClass, $sAttCode, $sStateAttCode); - if ($val != null) - { - // The field is visible, add it to the current column - $aDetails[$sTab][$sColIndex][] = $val; - } - } - //} + // The field is visible, add it to the current column + $aDetails[$sTab][$sColIndex][] = $val; + } + } + $oPage->Details($aDetails[$sTab][$sColIndex]); + if (!empty($sFieldsetName)) + { + $oPage->add('
'); + } } - $oPage->add('
'); - $oPage->Details($aDetails[$sTab][$sColIndex]); $oPage->add('
'); @@ -743,9 +750,15 @@ EOF $aHeader[] = 'id'; foreach($aList[$sClassName] as $sAttCode => $oAttDef) { + $sStar = ''; if ($oAttDef->IsExternalField()) { $sExtKeyLabel = MetaModel::GetLabel($sClassName, $oAttDef->GetKeyAttCode()); + $oExtKeyAttDef = MetaModel::GetAttributeDef($sClassName, $oAttDef->GetKeyAttCode()); + if (!$oExtKeyAttDef->IsNullAllowed() && isset($aParams['showMandatoryFields'])) + { + $sStar = '*'; + } $sRemoteAttLabel = MetaModel::GetLabel($oAttDef->GetTargetClass(), $oAttDef->GetExtAttCode()); $oTargetAttDef = MetaModel::GetAttributeDef($oAttDef->GetTargetClass(), $oAttDef->GetExtAttCode()); $sSuffix = ''; @@ -754,11 +767,15 @@ EOF $sSuffix = '->id'; } - $aHeader[] = $sExtKeyLabel.'->'.$sRemoteAttLabel.$sSuffix; + $aHeader[] = $sExtKeyLabel.'->'.$sRemoteAttLabel.$sSuffix.$sStar; } else { - $aHeader[] = MetaModel::GetLabel($sClassName, $sAttCode); + if (!$oAttDef->IsNullAllowed() && isset($aParams['showMandatoryFields'])) + { + $sStar = '*'; + } + $aHeader[] = MetaModel::GetLabel($sClassName, $sAttCode).$sStar; } } } @@ -1184,69 +1201,107 @@ EOF $oPage->AddTabContainer(OBJECT_PROPERTIES_TAB); $oPage->SetCurrentTabContainer(OBJECT_PROPERTIES_TAB); $oPage->SetCurrentTab(Dict::S('UI:PropertiesTab')); - $aDetailsList = $this->FLattenZList(MetaModel::GetZListItems($sClass, 'details')); +// $aDetailsList = $this->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($aDetailsList as $sAttCode) +// { +// $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode); +// if (!$oAttDef->IsExternalField()) +// { +// $aList[] = $sAttCode; +// } +// } - foreach($aList as $sAttCode) + $aDetailsList = MetaModel::GetZListItems($sClass, 'details'); + $aDetailsStruct = self::ProcessZlist($aDetailsList, array('UI:PropertiesTab' => array()), 'UI:PropertiesTab', 'col1', ''); + $sHtml = ''; + $aDetails = array(); + foreach($aDetailsStruct as $sTab => $aCols ) { - $iFlags = $this->GetAttributeFlags($sAttCode); - $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode); - if ( (!$oAttDef->IsLinkSet()) && (($iFlags & OPT_ATT_HIDDEN) == 0)) + $aDetails[$sTab] = array(); + ksort($aCols); + $oPage->SetCurrentTab(Dict::S($sTab)); + $oPage->add(''); + foreach($aCols as $sColIndex => $aFieldsets) { - if ($oAttDef->IsWritable()) + $oPage->add(''); } + $oPage->add('
'); + //$aDetails[$sTab][$sColIndex] = array(); + foreach($aFieldsets as $sFieldsetName => $aFields) { - if ($sStateAttCode == $sAttCode) + $aDetails[$sTab][$sColIndex] = array(); + if (!empty($sFieldsetName)) { - // State attribute is always read-only from the UI - $sHTMLValue = $this->GetStateLabel(); - $aDetails[] = array('label' => $oAttDef->GetLabel(), 'value' => $sHTMLValue); + $oPage->add('
'); + $oPage->add(''.Dict::S($sFieldsetName).''); } - else + foreach($aFields as $sAttCode) { - $iFlags = $this->GetAttributeFlags($sAttCode); - if ($iFlags & OPT_ATT_HIDDEN) + $aVal = null; + $iFlags = $this->GetAttributeFlags($sAttCode); + $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode); + if ( (!$oAttDef->IsLinkSet()) && (($iFlags & OPT_ATT_HIDDEN) == 0)) { - // Attribute is hidden, do nothing - } - else - { - if ($iFlags & OPT_ATT_READONLY) + if ($oAttDef->IsWritable()) { - // Attribute is read-only - $sHTMLValue = $this->GetAsHTML($sAttCode); + if ($sStateAttCode == $sAttCode) + { + // State attribute is always read-only from the UI + $sHTMLValue = $this->GetStateLabel(); + $aVal = array('label' => $oAttDef->GetLabel(), 'value' => $sHTMLValue); + } + else + { + $iFlags = $this->GetAttributeFlags($sAttCode); + if ($iFlags & OPT_ATT_HIDDEN) + { + // Attribute is hidden, do nothing + } + else + { + if ($iFlags & OPT_ATT_READONLY) + { + // Attribute is read-only + $sHTMLValue = $this->GetAsHTML($sAttCode); + } + else + { + $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; + + } + $aVal = array('label' => ''.$oAttDef->GetLabel().'', 'value' => $sHTMLValue); + } + } } else { - $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; - + $aVal = array('label' => ''.$oAttDef->GetLabel().'', 'value' => $this->GetAsHTML($sAttCode)); } - $aDetails[] = array('label' => ''.$oAttDef->GetLabel().'', 'value' => $sHTMLValue); } + if ($aVal != null) + { + // The field is visible, add it to the current column + $aDetails[$sTab][$sColIndex][] = $aVal; + } + } + $oPage->Details($aDetails[$sTab][$sColIndex]); + if (!empty($sFieldsetName)) + { + $oPage->add('
'); } } - else - { - $aDetails[] = array('label' => ''.$oAttDef->GetLabel().'', 'value' => $this->GetAsHTML($sAttCode)); - } + $oPage->add('
'); } - $oPage->details($aDetails); + // Now display the relations, one tab per relation $this->DisplayBareRelations($oPage, true); // Edit mode @@ -1413,7 +1468,7 @@ EOF } else { - $aResult = array_merge($aResult, $this->FlattenZList($value)); + $aResult = array_merge($aResult,self::FlattenZList($value)); } } return $aResult; diff --git a/pages/ajax.csvimport.php b/pages/ajax.csvimport.php index ef9ecf72e..b5d78e38b 100644 --- a/pages/ajax.csvimport.php +++ b/pages/ajax.csvimport.php @@ -104,6 +104,13 @@ function GetMappingForField($sClassName, $sFieldName, $iFieldIndex, $bAdvancedMo $aChoices = array('' => Dict::S('UI:CSVImport:MappingSelectOne')); $aChoices[':none:'] = Dict::S('UI:CSVImport:MappingNotApplicable'); $sFieldCode = ''; // Code of the attribute, if there is a match + $aMatches = array(); + if (preg_match('/^(.+)\*$/', $sFieldName, $aMatches)) + { + // Remove any trailing "star" character. + // A star character at the end can be used to indicate a mandatory field + $sFieldName = $aMatches[1]; + } if ($sFieldName == 'id') { $sFieldCode = 'id'; @@ -114,6 +121,7 @@ function GetMappingForField($sClassName, $sFieldName, $iFieldIndex, $bAdvancedMo } foreach(MetaModel::ListAttributeDefs($sClassName) as $sAttCode => $oAttDef) { + $sStar = ''; if ($oAttDef->IsExternalKey()) { if ( ($sFieldName == $oAttDef->GetLabel()) || ($sFieldName == $sAttCode)) @@ -124,6 +132,11 @@ function GetMappingForField($sClassName, $sFieldName, $iFieldIndex, $bAdvancedMo { $aChoices[$sAttCode] = $oAttDef->GetLabel(); } + $oExtKeyAttDef = MetaModel::GetAttributeDef($sClassName, $oAttDef->GetKeyAttCode()); + if (!$oExtKeyAttDef->IsNullAllowed()) + { + $sStar = '*'; + } // Get fields of the external class that are considered as reconciliation keys $sTargetClass = $oAttDef->GetTargetClass(); foreach(MetaModel::ListAttributeDefs($sTargetClass) as $sTargetAttCode => $oTargetAttDef) @@ -140,7 +153,7 @@ function GetMappingForField($sClassName, $sFieldName, $iFieldIndex, $bAdvancedMo { // When not in advanced mode do not allow to use reconciliation keys (on external keys) if they are themselves external keys ! - $aChoices[$sAttCode.'->'.$sTargetAttCode] = $oAttDef->GetLabel().'->'.$oTargetAttDef->GetLabel().$sSuffix; + $aChoices[$sAttCode.'->'.$sTargetAttCode] = $oAttDef->GetLabel().'->'.$oTargetAttDef->GetLabel().$sSuffix.$sStar; if ((strcasecmp($sFieldName, $aChoices[$sAttCode.'->'.$sTargetAttCode]) == 0) || (strcasecmp($sFieldName, ($sAttCode.'->'.$sTargetAttCode.$sSuffix)) == 0) ) { $sFieldCode = $sAttCode.'->'.$sTargetAttCode; @@ -151,7 +164,11 @@ function GetMappingForField($sClassName, $sFieldName, $iFieldIndex, $bAdvancedMo } else if ( ($oAttDef->IsWritable()) && (!$oAttDef->IsLinkSet()) ) { - $aChoices[$sAttCode] = $oAttDef->GetLabel(); + if (!$oAttDef->IsNullAllowed()) + { + $sStar = '*'; + } + $aChoices[$sAttCode] = $oAttDef->GetLabel().$sStar; if ( ($sFieldName == $oAttDef->GetLabel()) || ($sFieldName == $sAttCode)) { $sFieldCode = $sAttCode; @@ -356,7 +373,7 @@ EOF $oSearch = new DBObjectSearch($sClassName); $oSearch->AddCondition('id', 0, '='); // Make sure we create an empty set $oSet = new CMDBObjectSet($oSearch); - $sResult = cmdbAbstractObject::GetSetAsCSV($oSet); + $sResult = cmdbAbstractObject::GetSetAsCSV($oSet, array('showMandatoryFields' => true)); //$aCSV = explode("\n", $sCSV); // If there are more than one line, let's assume that the first line is a comment and skip it. //if (count($aCSV) > 1) diff --git a/webservices/import.php b/webservices/import.php index 89998fb16..9b1009a85 100644 --- a/webservices/import.php +++ b/webservices/import.php @@ -279,6 +279,12 @@ try $aExtKeys = array(); foreach($aRawFieldList as $iFieldId => $sFieldName) { + $aMatches = array(); + if (preg_match('/^(.+)\*$/', $sFieldName, $aMatches)) + { + // Ignore any trailing "star" (*) that simply indicates a mandatory field + $sFieldName = $aMatches[1]; + } if (preg_match('/^(.*)->(.*)$/', trim($sFieldName), $aMatches)) { // The column has been specified as "extkey->attcode"