diff --git a/application/ui.extkeywidget.class.inc.php b/application/ui.extkeywidget.class.inc.php index cd0f01e83..84dd69a4b 100644 --- a/application/ui.extkeywidget.class.inc.php +++ b/application/ui.extkeywidget.class.inc.php @@ -975,6 +975,10 @@ HTML // Remove blob edition from creation form @see N°5863 to allow blob edition in modal context FormHelper::DisableAttributeBlobInputs($this->sTargetClass, $aFormExtraParams); + if(FormHelper::HasMandatoryAttributeBlobInputs($oNewObj)){ + $oPage->AddUiBlock(FormHelper::GetAlertForMandatoryAttributeBlobInputsInModal()); + } + cmdbAbstractObject::DisplayCreationForm($oPage, $this->sTargetClass, $oNewObj, array(), $aFormExtraParams); $oPage->add(<< diff --git a/application/ui.linksdirectwidget.class.inc.php b/application/ui.linksdirectwidget.class.inc.php index 6488bffa8..a3ed0a4d8 100644 --- a/application/ui.linksdirectwidget.class.inc.php +++ b/application/ui.linksdirectwidget.class.inc.php @@ -143,6 +143,10 @@ JS // Remove blob edition from creation form @see N°5863 to allow blob edition in modal context FormHelper::DisableAttributeBlobInputs($sRealClass, $aFormExtraParams); + + if(FormHelper::HasMandatoryAttributeBlobInputs($oObj)){ + $oPage->AddUiBlock(FormHelper::GetAlertForMandatoryAttributeBlobInputsInModal()); + } cmdbAbstractObject::DisplayCreationForm($oPage, $sRealClass, $oObj, array(), $aFormExtraParams); } diff --git a/core/attributedef.class.inc.php b/core/attributedef.class.inc.php index 0d18a3e93..823cfa93c 100644 --- a/core/attributedef.class.inc.php +++ b/core/attributedef.class.inc.php @@ -91,6 +91,12 @@ define('LINKSET_EDITMODE_ACTIONS', 2); // Show the usual 'Actions' popup menu define('LINKSET_EDITMODE_INPLACE', 3); // The "linked" objects can be created/modified/deleted in place define('LINKSET_EDITMODE_ADDREMOVE', 4); // The "linked" objects can be added/removed in place +define('LINKSET_EDITWHEN_NEVER', 0); // The linkset cannot be edited at all from inside this object +define('LINKSET_EDITWHEN_ON_HOST_EDITION', 1); // The only possible action is to open a new window to create a new object +define('LINKSET_EDITWHEN_ON_HOST_DISPLAY', 2); // Show the usual 'Actions' popup menu +define('LINKSET_EDITWHEN_ALWAYS', 3); // Show the usual 'Actions' popup menu + + define('LINKSET_DISPLAY_STYLE_PROPERTY', 'property'); define('LINKSET_DISPLAY_STYLE_TAB', 'tab'); @@ -1703,6 +1709,15 @@ class AttributeLinkedSet extends AttributeDefinition public function GetEditMode() { return $this->GetOptional('edit_mode', LINKSET_EDITMODE_ACTIONS); + } + + /** + * @return int see LINKSET_EDITWHEN_* constants + * @since 3.1.1 3.2.0 N°6385 + */ + public function GetEditWhen(): int + { + return $this->GetOptional('edit_when', LINKSET_EDITWHEN_ALWAYS); } /** diff --git a/dictionaries/ui/application/object/cs.dictionary.itop.object.php b/dictionaries/ui/application/object/cs.dictionary.itop.object.php index 011fc573a..282b2ceb9 100644 --- a/dictionaries/ui/application/object/cs.dictionary.itop.object.php +++ b/dictionaries/ui/application/object/cs.dictionary.itop.object.php @@ -18,4 +18,5 @@ */ Dict::Add('CS CZ', 'Czech', 'Čeština', array( 'UI:Object:Modal:Title' => 'Create an object~~', + 'UI:Object:Modal:MandatoryAttributeBlobInputs:Warning:Text' => 'This form contains a mandatory file attribute which is not supported in modal mode. The creation/modification of this object may be incomplete and may be completed in a full-page form.~~', )); \ No newline at end of file diff --git a/dictionaries/ui/application/object/da.dictionary.itop.object.php b/dictionaries/ui/application/object/da.dictionary.itop.object.php index 40dfeb55f..959419313 100644 --- a/dictionaries/ui/application/object/da.dictionary.itop.object.php +++ b/dictionaries/ui/application/object/da.dictionary.itop.object.php @@ -18,4 +18,5 @@ */ Dict::Add('DA DA', 'Danish', 'Dansk', array( 'UI:Object:Modal:Title' => 'Create an object~~', + 'UI:Object:Modal:MandatoryAttributeBlobInputs:Warning:Text' => 'This form contains a mandatory file attribute which is not supported in modal mode. The creation/modification of this object may be incomplete and may be completed in a full-page form.~~', )); \ No newline at end of file diff --git a/dictionaries/ui/application/object/de.dictionary.itop.object.php b/dictionaries/ui/application/object/de.dictionary.itop.object.php index 68dd8b494..a95f8c016 100644 --- a/dictionaries/ui/application/object/de.dictionary.itop.object.php +++ b/dictionaries/ui/application/object/de.dictionary.itop.object.php @@ -18,4 +18,5 @@ */ Dict::Add('DE DE', 'German', 'Deutsch', array( 'UI:Object:Modal:Title' => 'Ein Objekt erstellen', + 'UI:Object:Modal:MandatoryAttributeBlobInputs:Warning:Text' => 'This form contains a mandatory file attribute which is not supported in modal mode. The creation/modification of this object may be incomplete and may be completed in a full-page form.~~', )); \ No newline at end of file diff --git a/dictionaries/ui/application/object/en.dictionary.itop.object.php b/dictionaries/ui/application/object/en.dictionary.itop.object.php index ed9358bf3..7cf687207 100644 --- a/dictionaries/ui/application/object/en.dictionary.itop.object.php +++ b/dictionaries/ui/application/object/en.dictionary.itop.object.php @@ -19,4 +19,5 @@ Dict::Add('EN US', 'English', 'English', array( 'UI:Object:Modal:Title' => 'Create an object', + 'UI:Object:Modal:MandatoryAttributeBlobInputs:Warning:Text' => 'This form contains a mandatory file attribute which is not supported in modal mode. The creation/modification of this object may be incomplete and may be completed in a full-page form.', )); \ No newline at end of file diff --git a/dictionaries/ui/application/object/es_cr.dictionary.itop.object.php b/dictionaries/ui/application/object/es_cr.dictionary.itop.object.php index 5a8e751bd..5ad65e4c8 100644 --- a/dictionaries/ui/application/object/es_cr.dictionary.itop.object.php +++ b/dictionaries/ui/application/object/es_cr.dictionary.itop.object.php @@ -18,4 +18,5 @@ */ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array( 'UI:Object:Modal:Title' => 'Create an object~~', + 'UI:Object:Modal:MandatoryAttributeBlobInputs:Warning:Text' => 'This form contains a mandatory file attribute which is not supported in modal mode. The creation/modification of this object may be incomplete and may be completed in a full-page form.~~', )); \ No newline at end of file diff --git a/dictionaries/ui/application/object/fr.dictionary.itop.object.php b/dictionaries/ui/application/object/fr.dictionary.itop.object.php index da15236ab..792babcc9 100644 --- a/dictionaries/ui/application/object/fr.dictionary.itop.object.php +++ b/dictionaries/ui/application/object/fr.dictionary.itop.object.php @@ -18,4 +18,5 @@ */ Dict::Add('FR FR', 'French', 'Français', array( 'UI:Object:Modal:Title' => 'Create an object~~', + 'UI:Object:Modal:MandatoryAttributeBlobInputs:Warning:Text' => 'Ce formulaire contient un attribut fichier obligatoire qui n\'est pas supporté en mode pop-up. La création/modification de cet objet risque d\'être incomplète et pourra être complété dans un formulaire en pleine page.', )); \ No newline at end of file diff --git a/dictionaries/ui/application/object/hu.dictionary.itop.object.php b/dictionaries/ui/application/object/hu.dictionary.itop.object.php index 2ead4a47b..a560ec76b 100644 --- a/dictionaries/ui/application/object/hu.dictionary.itop.object.php +++ b/dictionaries/ui/application/object/hu.dictionary.itop.object.php @@ -18,4 +18,5 @@ */ Dict::Add('HU HU', 'Hungarian', 'Magyar', array( 'UI:Object:Modal:Title' => 'Create an object~~', + 'UI:Object:Modal:MandatoryAttributeBlobInputs:Warning:Text' => 'This form contains a mandatory file attribute which is not supported in modal mode. The creation/modification of this object may be incomplete and may be completed in a full-page form.~~', )); \ No newline at end of file diff --git a/dictionaries/ui/application/object/it.dictionary.itop.object.php b/dictionaries/ui/application/object/it.dictionary.itop.object.php index ad91e6f0a..ab9669d04 100644 --- a/dictionaries/ui/application/object/it.dictionary.itop.object.php +++ b/dictionaries/ui/application/object/it.dictionary.itop.object.php @@ -18,4 +18,5 @@ */ Dict::Add('IT IT', 'Italian', 'Italiano', array( 'UI:Object:Modal:Title' => 'Create an object~~', + 'UI:Object:Modal:MandatoryAttributeBlobInputs:Warning:Text' => 'This form contains a mandatory file attribute which is not supported in modal mode. The creation/modification of this object may be incomplete and may be completed in a full-page form.~~', )); \ No newline at end of file diff --git a/dictionaries/ui/application/object/ja.dictionary.itop.object.php b/dictionaries/ui/application/object/ja.dictionary.itop.object.php index d82f655a7..cf384f357 100644 --- a/dictionaries/ui/application/object/ja.dictionary.itop.object.php +++ b/dictionaries/ui/application/object/ja.dictionary.itop.object.php @@ -18,4 +18,5 @@ */ Dict::Add('JA JP', 'Japanese', '日本語', array( 'UI:Object:Modal:Title' => 'Create an object~~', + 'UI:Object:Modal:MandatoryAttributeBlobInputs:Warning:Text' => 'This form contains a mandatory file attribute which is not supported in modal mode. The creation/modification of this object may be incomplete and may be completed in a full-page form.~~', )); \ No newline at end of file diff --git a/dictionaries/ui/application/object/nl.dictionary.itop.object.php b/dictionaries/ui/application/object/nl.dictionary.itop.object.php index eb271666f..69f069982 100644 --- a/dictionaries/ui/application/object/nl.dictionary.itop.object.php +++ b/dictionaries/ui/application/object/nl.dictionary.itop.object.php @@ -18,4 +18,5 @@ */ Dict::Add('NL NL', 'Dutch', 'Nederlands', array( 'UI:Object:Modal:Title' => 'Create an object~~', + 'UI:Object:Modal:MandatoryAttributeBlobInputs:Warning:Text' => 'This form contains a mandatory file attribute which is not supported in modal mode. The creation/modification of this object may be incomplete and may be completed in a full-page form.~~', )); \ No newline at end of file diff --git a/dictionaries/ui/application/object/pl.dictionary.itop.object.php b/dictionaries/ui/application/object/pl.dictionary.itop.object.php index b7fd4c436..80e8c71a1 100644 --- a/dictionaries/ui/application/object/pl.dictionary.itop.object.php +++ b/dictionaries/ui/application/object/pl.dictionary.itop.object.php @@ -18,4 +18,5 @@ */ Dict::Add('PL PL', 'Polish', 'Polski', array( 'UI:Object:Modal:Title' => 'Create an object~~', + 'UI:Object:Modal:MandatoryAttributeBlobInputs:Warning:Text' => 'This form contains a mandatory file attribute which is not supported in modal mode. The creation/modification of this object may be incomplete and may be completed in a full-page form.~~', )); \ No newline at end of file diff --git a/dictionaries/ui/application/object/pt_br.dictionary.itop.object.php b/dictionaries/ui/application/object/pt_br.dictionary.itop.object.php index a043d6678..8bb1a9327 100644 --- a/dictionaries/ui/application/object/pt_br.dictionary.itop.object.php +++ b/dictionaries/ui/application/object/pt_br.dictionary.itop.object.php @@ -18,4 +18,5 @@ */ Dict::Add('PT BR', 'Brazilian', 'Brazilian', array( 'UI:Object:Modal:Title' => 'Create an object~~', + 'UI:Object:Modal:MandatoryAttributeBlobInputs:Warning:Text' => 'This form contains a mandatory file attribute which is not supported in modal mode. The creation/modification of this object may be incomplete and may be completed in a full-page form.~~', )); \ No newline at end of file diff --git a/dictionaries/ui/application/object/ru.dictionary.itop.object.php b/dictionaries/ui/application/object/ru.dictionary.itop.object.php index 23e558c51..68ef89486 100644 --- a/dictionaries/ui/application/object/ru.dictionary.itop.object.php +++ b/dictionaries/ui/application/object/ru.dictionary.itop.object.php @@ -18,4 +18,5 @@ */ Dict::Add('RU RU', 'Russian', 'Русский', array( 'UI:Object:Modal:Title' => 'Create an object~~', + 'UI:Object:Modal:MandatoryAttributeBlobInputs:Warning:Text' => 'This form contains a mandatory file attribute which is not supported in modal mode. The creation/modification of this object may be incomplete and may be completed in a full-page form.~~', )); \ No newline at end of file diff --git a/dictionaries/ui/application/object/sk.dictionary.itop.object.php b/dictionaries/ui/application/object/sk.dictionary.itop.object.php index 819aeef34..86588dbdb 100644 --- a/dictionaries/ui/application/object/sk.dictionary.itop.object.php +++ b/dictionaries/ui/application/object/sk.dictionary.itop.object.php @@ -18,4 +18,5 @@ */ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array( 'UI:Object:Modal:Title' => 'Create an object~~', + 'UI:Object:Modal:MandatoryAttributeBlobInputs:Warning:Text' => 'This form contains a mandatory file attribute which is not supported in modal mode. The creation/modification of this object may be incomplete and may be completed in a full-page form.~~', )); \ No newline at end of file diff --git a/dictionaries/ui/application/object/tr.dictionary.itop.object.php b/dictionaries/ui/application/object/tr.dictionary.itop.object.php index ca4108aba..8c54de0a3 100644 --- a/dictionaries/ui/application/object/tr.dictionary.itop.object.php +++ b/dictionaries/ui/application/object/tr.dictionary.itop.object.php @@ -18,4 +18,5 @@ */ Dict::Add('TR TR', 'Turkish', 'Türkçe', array( 'UI:Object:Modal:Title' => 'Create an object~~', + 'UI:Object:Modal:MandatoryAttributeBlobInputs:Warning:Text' => 'This form contains a mandatory file attribute which is not supported in modal mode. The creation/modification of this object may be incomplete and may be completed in a full-page form.~~', )); \ No newline at end of file diff --git a/dictionaries/ui/application/object/zh_cn.dictionary.itop.object.php b/dictionaries/ui/application/object/zh_cn.dictionary.itop.object.php index 90f847766..49d3d2038 100644 --- a/dictionaries/ui/application/object/zh_cn.dictionary.itop.object.php +++ b/dictionaries/ui/application/object/zh_cn.dictionary.itop.object.php @@ -18,4 +18,5 @@ */ Dict::Add('ZH CN', 'Chinese', '简体中文', array( 'UI:Object:Modal:Title' => 'Create an object~~', + 'UI:Object:Modal:MandatoryAttributeBlobInputs:Warning:Text' => 'This form contains a mandatory file attribute which is not supported in modal mode. The creation/modification of this object may be incomplete and may be completed in a full-page form.~~', )); \ No newline at end of file diff --git a/setup/compiler.class.inc.php b/setup/compiler.class.inc.php index 10aeba488..9bbb07a6a 100644 --- a/setup/compiler.class.inc.php +++ b/setup/compiler.class.inc.php @@ -938,6 +938,30 @@ EOF return $aXmlToPHP[$sEditMode]; } + + /** + * Helper to format the edit-when for direct linkset + * + * @param string $sEditWhen Value set from within the XML + * @return string PHP flag + * + * @throws \DOMFormatException + */ + protected function EditWhenToPHP($sEditWhen): string + { + static $aXmlToPHP = array( + 'never' => 'LINKSET_EDITWHEN_NEVER', + 'on_host_edition' => 'LINKSET_EDITWHEN_ON_HOST_EDITION', + 'on_host_display' => 'LINKSET_EDITWHEN_ON_HOST_DISPLAY', + 'always' => 'LINKSET_EDITWHEN_ALWAYS', + ); + + if (!array_key_exists($sEditWhen, $aXmlToPHP)) + { + throw new DOMFormatException("Edit mode: unknown value '$sEditWhen'"); + } + return $aXmlToPHP[$sEditWhen]; + } /** * Format a path (file or url) as an absolute path or relative to the module or the app @@ -2053,6 +2077,7 @@ EOF $this->CompileCommonProperty('duplicates', $oField, $aParameters, $sModuleRelativeDir, false); $this->CompileCommonProperty('display_style', $oField, $aParameters, $sModuleRelativeDir); $this->CompileCommonProperty('edit_mode', $oField, $aParameters, $sModuleRelativeDir); + $this->CompileCommonProperty('edit_when', $oField, $aParameters, $sModuleRelativeDir); $this->CompileCommonProperty('filter', $oField, $aParameters, $sModuleRelativeDir); $this->CompileCommonProperty('with_php_constraint', $oField, $aParameters, $sModuleRelativeDir, false); $aParameters['depends_on'] = $sDependencies; @@ -2063,6 +2088,7 @@ EOF $this->CompileCommonProperty('count_max', $oField, $aParameters, $sModuleRelativeDir, 0); $this->CompileCommonProperty('display_style', $oField, $aParameters, $sModuleRelativeDir); $this->CompileCommonProperty('edit_mode', $oField, $aParameters, $sModuleRelativeDir); + $this->CompileCommonProperty('edit_when', $oField, $aParameters, $sModuleRelativeDir); $this->CompileCommonProperty('filter', $oField, $aParameters, $sModuleRelativeDir); $this->CompileCommonProperty('with_php_constraint', $oField, $aParameters, $sModuleRelativeDir, false); $aParameters['depends_on'] = $sDependencies; @@ -2288,6 +2314,12 @@ EOF $aParameters['edit_mode'] = $this->EditModeToPHP($sEditMode); } break; + case 'edit_when': + $sEditWhen = $oField->GetChildText('edit_when'); + if(!is_null($sEditWhen)){ + $aParameters['edit_when'] = $this->EditWhenToPHP($sEditWhen); + } + break; case 'mappings': $oMappings = $oField->GetUniqueElement('mappings'); $oMappingNodes = $oMappings->getElementsByTagName('mapping'); diff --git a/setup/modelfactory.class.inc.php b/setup/modelfactory.class.inc.php index acea63e85..fe84b3603 100644 --- a/setup/modelfactory.class.inc.php +++ b/setup/modelfactory.class.inc.php @@ -1466,7 +1466,7 @@ EOF switch ($sAlteration) { case '': if ($oNodeClone->hasAttribute('id')) { - $oNodeClone->setAttribute('_delta', 'must_exist'); + //$oNodeClone->setAttribute('_delta', 'merge'); } break; case 'added': diff --git a/sources/Application/Helper/FormHelper.php b/sources/Application/Helper/FormHelper.php index 43b78393a..8d775f6b5 100644 --- a/sources/Application/Helper/FormHelper.php +++ b/sources/Application/Helper/FormHelper.php @@ -7,6 +7,8 @@ namespace Combodo\iTop\Application\Helper; use AttributeBlob; +use Combodo\iTop\Application\UI\Base\Component\Alert\Alert; +use Combodo\iTop\Application\UI\Base\Component\Alert\AlertUIBlockFactory; use DBObject; use Dict; use MetaModel; @@ -56,6 +58,39 @@ class FormHelper } } + /** + * Returns true if the object has a mandatory attribute blob + * + * @see N°6861 - Display warning when creating/editing a mandatory blob in modal + * + * @param \DBObject $oObject + * + * @return bool + * @throws \CoreException + */ + public static function HasMandatoryAttributeBlobInputs(DBObject $oObject): bool + { + foreach (MetaModel::ListAttributeDefs(get_class($oObject)) as $sAttCode => $oAttDef) { + if ($oAttDef instanceof AttributeBlob && (!$oAttDef->IsNullAllowed() || ($oObject->GetFormAttributeFlags($sAttCode) & OPT_ATT_MANDATORY))) { + return true; + } + } + return false; + } + + /** + * Returns an Alert explaining what will happen when a mandatory attribute blob is displayed in a form + * + * @see N°6861 - Display warning when creating/editing a mandatory blob in modal + * + * @return \Combodo\iTop\Application\UI\Base\Component\Alert\Alert + */ + public static function GetAlertForMandatoryAttributeBlobInputsInModal(): Alert + { + $oAlert = AlertUIBlockFactory::MakeForWarning('',Dict::S('UI:Object:Modal:MandatoryAttributeBlobInputs:Warning:Text')); + return $oAlert; + } + /** * Update flags to be sent to form with url parameters * For now only supports "readonly" param diff --git a/sources/Application/UI/Links/AbstractBlockLinkSetViewTable.php b/sources/Application/UI/Links/AbstractBlockLinkSetViewTable.php index a7f7b3b98..10f08155a 100644 --- a/sources/Application/UI/Links/AbstractBlockLinkSetViewTable.php +++ b/sources/Application/UI/Links/AbstractBlockLinkSetViewTable.php @@ -216,8 +216,20 @@ abstract class AbstractBlockLinkSetViewTable extends UIContentBlock { $iFlags = $this->oDbObject->GetAttributeFlags($this->sAttCode); } + + $bEditWhen = $this->IsEditableBasedOnEditWhen(); - $this->bIsAttEditable = !($iFlags & (OPT_ATT_READONLY | OPT_ATT_SLAVE | OPT_ATT_HIDDEN)); + $this->bIsAttEditable = !($iFlags & (OPT_ATT_READONLY | OPT_ATT_SLAVE | OPT_ATT_HIDDEN)) && $bEditWhen; + } + + /** + * Compares Linkset attribute edit_when values with its usage requirements + * + * @return bool + * @since 3.1.1 3.2.0 N°6385 + */ + protected function IsEditableBasedOnEditWhen(): bool{ + return true; } /** diff --git a/sources/Application/UI/Links/Direct/BlockDirectLinkSetEditTable.php b/sources/Application/UI/Links/Direct/BlockDirectLinkSetEditTable.php index 633d41780..2dd105f94 100644 --- a/sources/Application/UI/Links/Direct/BlockDirectLinkSetEditTable.php +++ b/sources/Application/UI/Links/Direct/BlockDirectLinkSetEditTable.php @@ -121,10 +121,13 @@ class BlockDirectLinkSetEditTable extends UIContentBlock { $this->oAttributeLinkedSet = MetaModel::GetAttributeDef($this->oUILinksDirectWidget->GetClass(), $this->oUILinksDirectWidget->GetAttCode()); + $sEditWhen = $this->oAttributeLinkedSet->GetEditWhen(); + $bIsEditableBasedOnEditWhen = ($sEditWhen === LINKSET_EDITWHEN_ALWAYS || $sEditWhen === LINKSET_EDITWHEN_ON_HOST_EDITION); + // User rights - $this->bIsAllowCreate = UserRights::IsActionAllowed($this->oAttributeLinkedSet->GetLinkedClass(), UR_ACTION_CREATE) == UR_ALLOWED_YES; - $this->bIsAllowModify = UserRights::IsActionAllowed($this->oAttributeLinkedSet->GetLinkedClass(), UR_ACTION_MODIFY) == UR_ALLOWED_YES; - $this->bIsAllowDelete = UserRights::IsActionAllowed($this->oAttributeLinkedSet->GetLinkedClass(), UR_ACTION_DELETE) == UR_ALLOWED_YES; + $this->bIsAllowCreate = UserRights::IsActionAllowed($this->oAttributeLinkedSet->GetLinkedClass(), UR_ACTION_CREATE) == UR_ALLOWED_YES && $bIsEditableBasedOnEditWhen; + $this->bIsAllowModify = UserRights::IsActionAllowed($this->oAttributeLinkedSet->GetLinkedClass(), UR_ACTION_MODIFY) == UR_ALLOWED_YES && $bIsEditableBasedOnEditWhen; + $this->bIsAllowDelete = UserRights::IsActionAllowed($this->oAttributeLinkedSet->GetLinkedClass(), UR_ACTION_DELETE) == UR_ALLOWED_YES && $bIsEditableBasedOnEditWhen; } /** diff --git a/sources/Application/UI/Links/Direct/BlockDirectLinkSetViewTable.php b/sources/Application/UI/Links/Direct/BlockDirectLinkSetViewTable.php index 831193e9b..ad431fa0a 100644 --- a/sources/Application/UI/Links/Direct/BlockDirectLinkSetViewTable.php +++ b/sources/Application/UI/Links/Direct/BlockDirectLinkSetViewTable.php @@ -179,4 +179,13 @@ class BlockDirectLinkSetViewTable extends AbstractBlockLinkSetViewTable return $aDefaults; } + + /** + * @inheritDoc + */ + protected function IsEditableBasedOnEditWhen(): bool + { + $sEditWhen = $this->oAttDef->GetEditWhen(); + return $sEditWhen === LINKSET_EDITWHEN_ALWAYS || $sEditWhen === LINKSET_EDITWHEN_ON_HOST_DISPLAY; + } } \ No newline at end of file diff --git a/sources/Application/UI/Links/Indirect/BlockIndirectLinkSetEditTable.php b/sources/Application/UI/Links/Indirect/BlockIndirectLinkSetEditTable.php index 21346df70..36e6bc359 100644 --- a/sources/Application/UI/Links/Indirect/BlockIndirectLinkSetEditTable.php +++ b/sources/Application/UI/Links/Indirect/BlockIndirectLinkSetEditTable.php @@ -107,10 +107,13 @@ class BlockIndirectLinkSetEditTable extends UIContentBlock { $this->oAttributeLinkedSetIndirect = MetaModel::GetAttributeDef($this->oUILinksWidget->GetClass(), $this->oUILinksWidget->GetAttCode()); + $sEditWhen = $this->oAttributeLinkedSetIndirect->GetEditWhen(); + $bIsEditableBasedOnEditWhen = ($sEditWhen === LINKSET_EDITWHEN_ALWAYS || $sEditWhen === LINKSET_EDITWHEN_ON_HOST_EDITION); + // User rights - $this->bIsAllowCreate = UserRights::IsActionAllowed($this->oAttributeLinkedSetIndirect->GetLinkedClass(), UR_ACTION_CREATE) == UR_ALLOWED_YES; - $this->bIsAllowModify = UserRights::IsActionAllowed($this->oAttributeLinkedSetIndirect->GetLinkedClass(), UR_ACTION_MODIFY) == UR_ALLOWED_YES; - $this->bIsAllowDelete = UserRights::IsActionAllowed($this->oAttributeLinkedSetIndirect->GetLinkedClass(), UR_ACTION_DELETE) == UR_ALLOWED_YES; + $this->bIsAllowCreate = UserRights::IsActionAllowed($this->oAttributeLinkedSetIndirect->GetLinkedClass(), UR_ACTION_CREATE) == UR_ALLOWED_YES && $bIsEditableBasedOnEditWhen; + $this->bIsAllowModify = UserRights::IsActionAllowed($this->oAttributeLinkedSetIndirect->GetLinkedClass(), UR_ACTION_MODIFY) == UR_ALLOWED_YES && $bIsEditableBasedOnEditWhen; + $this->bIsAllowDelete = UserRights::IsActionAllowed($this->oAttributeLinkedSetIndirect->GetLinkedClass(), UR_ACTION_DELETE) == UR_ALLOWED_YES && $bIsEditableBasedOnEditWhen; } /** diff --git a/sources/Application/UI/Links/Indirect/BlockIndirectLinkSetViewTable.php b/sources/Application/UI/Links/Indirect/BlockIndirectLinkSetViewTable.php index dbd18fa18..9447c4f26 100644 --- a/sources/Application/UI/Links/Indirect/BlockIndirectLinkSetViewTable.php +++ b/sources/Application/UI/Links/Indirect/BlockIndirectLinkSetViewTable.php @@ -126,4 +126,13 @@ class BlockIndirectLinkSetViewTable extends AbstractBlockLinkSetViewTable return $sAttCodesToDisplay; } + + /** + * @inheritDoc + */ + protected function IsEditableBasedOnEditWhen(): bool + { + $sEditWhen = $this->oAttDef->GetEditWhen(); + return $sEditWhen === LINKSET_EDITWHEN_ALWAYS || $sEditWhen === LINKSET_EDITWHEN_ON_HOST_DISPLAY; + } } \ No newline at end of file diff --git a/sources/Controller/Base/Layout/ObjectController.php b/sources/Controller/Base/Layout/ObjectController.php index 1725be8dc..7ead393ce 100644 --- a/sources/Controller/Base/Layout/ObjectController.php +++ b/sources/Controller/Base/Layout/ObjectController.php @@ -170,6 +170,10 @@ JS; // Remove blob edition from creation form @see N°5863 to allow blob edition in modal context FormHelper::DisableAttributeBlobInputs($sRealClass, $aFormExtraParams); + if(FormHelper::HasMandatoryAttributeBlobInputs($oObjToClone)){ + $oPage->AddUiBlock(FormHelper::GetAlertForMandatoryAttributeBlobInputsInModal()); + } + $aFormExtraParams['js_handlers']['cancel_button_on_click'] = <<AddUiBlock(FormHelper::GetAlertForMandatoryAttributeBlobInputsInModal()); + } } else { $oPage = new iTopWebPage('', $bPrintable); $oPage->DisableBreadCrumb(); diff --git a/sources/Controller/Links/LinkSetController.php b/sources/Controller/Links/LinkSetController.php index 57cbc740e..3b8836bfd 100644 --- a/sources/Controller/Links/LinkSetController.php +++ b/sources/Controller/Links/LinkSetController.php @@ -228,6 +228,10 @@ JS // Remove blob edition from creation form @see N°5863 to allow blob edition in modal context FormHelper::DisableAttributeBlobInputs($sRealClass, $aExtraParams); + + if(FormHelper::HasMandatoryAttributeBlobInputs($oObj)){ + $oPage->AddUiBlock(FormHelper::GetAlertForMandatoryAttributeBlobInputsInModal()); + } cmdbAbstractObject::DisplayCreationForm($oPage, $sRealClass, $oObj, array(), $aExtraParams); } diff --git a/tests/php-unit-tests/unitary-tests/setup/ModelFactoryTest.php b/tests/php-unit-tests/unitary-tests/setup/ModelFactoryTest.php index b5ff5a8db..f5eff7661 100644 --- a/tests/php-unit-tests/unitary-tests/setup/ModelFactoryTest.php +++ b/tests/php-unit-tests/unitary-tests/setup/ModelFactoryTest.php @@ -678,6 +678,59 @@ XML Luke Banner +XML + ]; + $aDeltas['_delta="define_and_must_exits"'] = [ + 'sInitialXML' => << + +XML + , + 'sDeltaXML' => << +