diff --git a/CHANGELOG.md b/CHANGELOG.md index 33fc5c3d2fc..fe6ec3934e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Release Notes for Craft CMS 5 +## Unreleased + +- Fixed a JavaScript error that could occur if there was a problem applying changes to field layout elements. ([#16380](https://github.com/craftcms/cms/issues/16380)) +- Fixed a bug where field layout designers were validating field names, handles, and instructions, even if they weren’t overridden within the field instance. ([#16380](https://github.com/craftcms/cms/issues/16380)) + ## 5.5.8 - 2025-01-02 - Fixed a bug where custom fields were getting included in rendered field layout forms, even if their `getInputHtml()` method returned an empty string. diff --git a/src/controllers/FieldsController.php b/src/controllers/FieldsController.php index 21c9d46434d..e6442a35da2 100644 --- a/src/controllers/FieldsController.php +++ b/src/controllers/FieldsController.php @@ -478,14 +478,22 @@ public function actionApplyLayoutTabSettings(): Response public function actionApplyLayoutElementSettings(): Response { /** @var FieldLayoutElement $element */ - $element = $this->_fldComponent(); + $element = $this->_fldComponent($settings); + + if (!empty($settings)) { + $validateAttributes = array_intersect( + array_keys(array_filter($settings)), + ['name', 'handle', 'instructions'], + ); + } - if ($element instanceof CustomField) { + if (!empty($validateAttributes) && $element instanceof CustomField) { $field = $element->getField(); if ($field instanceof Field) { $field->validateHandleUniqueness = false; } - if (!$field->validate(['name', 'handle', 'instructions'])) { + + if (!$field->validate($validateAttributes)) { if ($field->hasErrors('name')) { $field->addErrors(['label' => $field->getErrors('name')]); $field->clearErrors('name'); @@ -574,9 +582,10 @@ public function actionRenderCardPreview() /** * Returns the field layout component being edited, populated with the posted config/settings. * + * @param array|null $settings The `settings` array that might have been posted * @return FieldLayoutComponent */ - private function _fldComponent(): FieldLayoutComponent + private function _fldComponent(?array &$settings = null): FieldLayoutComponent { $uid = $this->request->getRequiredBodyParam('uid'); $elementType = $this->request->getRequiredBodyParam('elementType'); @@ -593,9 +602,10 @@ private function _fldComponent(): FieldLayoutComponent $settingsStr = $this->request->getBodyParam('settings'); if ($settingsStr !== null) { - parse_str($settingsStr, $settings); + parse_str($settingsStr, $postedSettings); $settingsNamespace = $this->request->getRequiredBodyParam('settingsNamespace'); - $componentConfig = array_merge($componentConfig, ArrayHelper::getValue($settings, $settingsNamespace, [])); + $settings = ArrayHelper::getValue($postedSettings, $settingsNamespace, []); + $componentConfig = array_merge($componentConfig, $settings); } $isTab = false; diff --git a/src/migrations/m230617_070415_entrify_matrix_blocks.php b/src/migrations/m230617_070415_entrify_matrix_blocks.php index 2817754324f..332ba47a2de 100644 --- a/src/migrations/m230617_070415_entrify_matrix_blocks.php +++ b/src/migrations/m230617_070415_entrify_matrix_blocks.php @@ -107,7 +107,7 @@ public function safeUp(): bool 'showSlugField' => false, ]); - $fieldLayoutUid = ArrayHelper::firstKey($blockTypeConfig['fieldLayouts'] ?? []); + $fieldLayoutUid = array_key_first($blockTypeConfig['fieldLayouts'] ?? []); $fieldLayout = $fieldLayoutUid ? $fieldsService->getLayoutByUid($fieldLayoutUid) : new FieldLayout(); $fieldLayout->type = Entry::class; $entryType->setFieldLayout($fieldLayout); diff --git a/src/web/assets/cp/dist/cp.js b/src/web/assets/cp/dist/cp.js index 4c53de2c7b3..73dcc4e16eb 100644 --- a/src/web/assets/cp/dist/cp.js +++ b/src/web/assets/cp/dist/cp.js @@ -1,3 +1,3 @@ /*! For license information please see cp.js.LICENSE.txt */ -(function(){var __webpack_modules__={463:function(){Craft.Accordion=Garnish.Base.extend({$trigger:null,targetSelector:null,_$target:null,init:function(t){var e=this;this.$trigger=$(t),this.$trigger.data("accordion")&&(console.warn("Double-instantiating an accordion trigger on an element"),this.$trigger.data("accordion").destroy()),this.$trigger.data("accordion",this),this.targetSelector=this.$trigger.attr("aria-controls")?"#".concat(this.$trigger.attr("aria-controls")):null,this.targetSelector&&(this._$target=$(this.targetSelector)),this.addListener(this.$trigger,"click","onTriggerClick"),this.addListener(this.$trigger,"keypress",(function(t){var n=t.keyCode;n!==Garnish.SPACE_KEY&&n!==Garnish.RETURN_KEY||(t.preventDefault(),e.onTriggerClick())}))},onTriggerClick:function(){"true"===this.$trigger.attr("aria-expanded")?this.hideTarget(this._$target):this.showTarget(this._$target)},showTarget:function(t){var e=this;if(t&&t.length){this.showTarget._currentHeight=t.height(),t.removeClass("hidden"),this.$trigger.removeClass("collapsed").addClass("expanded").attr("aria-expanded","true");for(var n=0;n=this.settings.maxItems)){var e=$(t).appendTo(this.$tbody),n=e.find(".delete");this.settings.sortable&&this.sorter.addItems(e),this.$deleteBtns=this.$deleteBtns.add(n),this.addListener(n,"click","handleDeleteBtnClick"),this.totalItems++,this.updateUI()}},reorderItems:function(){var t=this;if(this.settings.sortable){for(var e=[],n=0;n=this.settings.maxItems?$(this.settings.newItemBtnSelector).addClass("hidden"):$(this.settings.newItemBtnSelector).removeClass("hidden"))}},{defaults:{tableSelector:null,noItemsSelector:null,newItemBtnSelector:null,idAttribute:"data-id",nameAttribute:"data-name",sortable:!1,allowDeleteAll:!0,minItems:0,maxItems:null,reorderAction:null,deleteAction:null,reorderSuccessMessage:Craft.t("app","New order saved."),reorderFailMessage:Craft.t("app","Couldn’t save new order."),confirmDeleteMessage:Craft.t("app","Are you sure you want to delete “{name}”?"),deleteSuccessMessage:Craft.t("app","“{name}” deleted."),deleteFailMessage:Craft.t("app","Couldn’t delete “{name}”."),onReorderItems:$.noop,onDeleteItem:$.noop}})},6872:function(){Craft.AssetImageEditor=Garnish.Modal.extend({$body:null,$footer:null,$imageTools:null,$buttons:null,$cancelBtn:null,$replaceBtn:null,$saveBtn:null,$focalPointBtn:null,$editorContainer:null,$straighten:null,$croppingCanvas:null,$spinner:null,$constraintContainer:null,$constraintRadioInputs:null,$customConstraints:null,canvas:null,image:null,viewport:null,focalPoint:null,focalPointInnerCircle:null,focalPointOuterCircle:null,focalPointPickedIndicator:null,grid:null,croppingCanvas:null,clipper:null,croppingRectangle:null,cropperHandles:null,cropperGrid:null,croppingShade:null,imageStraightenAngle:0,viewportRotation:0,originalWidth:0,originalHeight:0,imageVerticeCoords:null,zoomRatio:1,animationInProgress:!1,currentView:"",assetId:null,cacheBust:null,draggingCropper:!1,scalingCropper:!1,handleClicked:!1,draggingFocal:!1,focalPickedUp:!1,focalClicked:!1,cropperClicked:!1,previousMouseX:0,previousMouseY:0,shiftKeyHeld:!1,editorHeight:0,editorWidth:0,cropperState:!1,scaleFactor:1,flipData:{},focalPointState:!1,maxImageSize:null,lastLoadedDimensions:null,imageIsLoading:!1,mouseMoveEvent:null,croppingConstraint:!1,constraintOrientation:"landscape",showingCustomConstraint:!1,saving:!1,renderImage:null,renderCropper:null,_queue:null,init:function(t,e){var n=this;this._queue=new Craft.Queue,this.cacheBust=Date.now(),this.setSettings(e,Craft.AssetImageEditor.defaults),null===this.settings.allowDegreeFractions&&(this.settings.allowDegreeFractions=Craft.isImagick),Garnish.prefersReducedMotion()&&(this.settings.animationDuration=1),this.assetId=t,this.flipData={x:0,y:0},this.$container=$('').appendTo(Garnish.$bod),this.$body=$('
').appendTo(this.$container),this.$footer=$('