From d6f8edfedd952ec04ca0213fd1a63330f851dabd Mon Sep 17 00:00:00 2001 From: Iwona Just Date: Mon, 30 Sep 2024 15:54:30 +0100 Subject: [PATCH 01/23] anchor summary error to field for nested matrix "blocks" --- src/fields/Matrix.php | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/fields/Matrix.php b/src/fields/Matrix.php index 7595f9ad885..adf3e76ebce 100644 --- a/src/fields/Matrix.php +++ b/src/fields/Matrix.php @@ -1012,7 +1012,21 @@ private function validateEntries(ElementInterface $element): void // we only want to show the nested entries errors when the matrix field is in blocks view mode; if ($this->viewMode === self::VIEW_MODE_BLOCKS) { $key = $entry->uid ?? sprintf('new%s', ++$new); - $element->addModelErrors($entry, sprintf('%s[%s]', $this->handle, $key)); + + // we have to do it "manually" instead of relying on Model->addModelErrors() + // because we should only have one prefix in case of multiple nested matrix fields; + // see https://github.com/craftcms/cms/issues/15797 for details + foreach ($entry->getErrors() as $attribute => $errors) { + foreach ($errors as $error) { + // if there's already a prefix - we're done; + $attrPrefix = ''; + // otherwise - add it + if (!str_contains($attribute, '].')) { + $attrPrefix = rtrim(sprintf('%s[%s]', $this->handle, $key), '.') . '.'; + } + $element->addError($attrPrefix . $attribute, $error); + } + } } $invalidEntryIds[] = $entry->id; } From 422bc814427f1d0dabc1cd3a1d4ce75d3fd977a6 Mon Sep 17 00:00:00 2001 From: Iwona Just Date: Tue, 8 Oct 2024 14:46:07 +0100 Subject: [PATCH 02/23] Revert "anchor summary error to field for nested matrix "blocks"" This reverts commit d6f8edfedd952ec04ca0213fd1a63330f851dabd. --- src/fields/Matrix.php | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/src/fields/Matrix.php b/src/fields/Matrix.php index adf3e76ebce..7595f9ad885 100644 --- a/src/fields/Matrix.php +++ b/src/fields/Matrix.php @@ -1012,21 +1012,7 @@ private function validateEntries(ElementInterface $element): void // we only want to show the nested entries errors when the matrix field is in blocks view mode; if ($this->viewMode === self::VIEW_MODE_BLOCKS) { $key = $entry->uid ?? sprintf('new%s', ++$new); - - // we have to do it "manually" instead of relying on Model->addModelErrors() - // because we should only have one prefix in case of multiple nested matrix fields; - // see https://github.com/craftcms/cms/issues/15797 for details - foreach ($entry->getErrors() as $attribute => $errors) { - foreach ($errors as $error) { - // if there's already a prefix - we're done; - $attrPrefix = ''; - // otherwise - add it - if (!str_contains($attribute, '].')) { - $attrPrefix = rtrim(sprintf('%s[%s]', $this->handle, $key), '.') . '.'; - } - $element->addError($attrPrefix . $attribute, $error); - } - } + $element->addModelErrors($entry, sprintf('%s[%s]', $this->handle, $key)); } $invalidEntryIds[] = $entry->id; } From 2d6ab9b7728d10f4b501d95b4a9cfca03358ea3d Mon Sep 17 00:00:00 2001 From: Iwona Just Date: Tue, 8 Oct 2024 14:48:51 +0100 Subject: [PATCH 03/23] match summary error key with field error key for nested matrix "blocks" --- src/controllers/ElementsController.php | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/controllers/ElementsController.php b/src/controllers/ElementsController.php index f524dafa89d..80de1546e6f 100644 --- a/src/controllers/ElementsController.php +++ b/src/controllers/ElementsController.php @@ -22,6 +22,7 @@ use craft\events\DefineElementEditorHtmlEvent; use craft\events\DraftEvent; use craft\fieldlayoutelements\BaseField; +use craft\fieldlayoutelements\CustomField; use craft\fields\Matrix; use craft\helpers\ArrayHelper; use craft\helpers\Component; @@ -1046,6 +1047,9 @@ private function _errorSummary(ElementInterface $element): string $errorItem .= $error; $errorItem .= Html::endTag('li'); } else { + // is the error for multi-nested field (e.g. matrix in a matrix in a blocks mode) + $multiNested = substr_count($key, '.') > 1; + // get tab uid for this error $tabUid = null; $bracketPos = strpos($key, '['); @@ -1054,7 +1058,21 @@ private function _errorSummary(ElementInterface $element): string foreach ($tab->getElements() as $layoutElement) { if ($layoutElement instanceof BaseField && $layoutElement->attribute() === $fieldKey) { $tabUid = $tab->uid; - continue 2; + if (!$multiNested) { + continue 2; + } + } + // if it's a multi-nested error key for matrix in blocks mode + // manipulate the key to only reference the matrix field, entry and inner field + if ($multiNested && $layoutElement instanceof CustomField) { + if ( + $layoutElement->getField() instanceof Matrix && + $layoutElement->getField()->viewMode === Matrix::VIEW_MODE_BLOCKS + ) { + $keyParts = explode('.', $key); + $key = implode('.', array_splice($keyParts, -2)); + unset($keyParts); + } } } } From 2e1dbd553f6871b1aa7cfbaeccabb066499c7bfb Mon Sep 17 00:00:00 2001 From: Iwona Just Date: Thu, 10 Oct 2024 10:11:17 +0100 Subject: [PATCH 04/23] fixes inline padding for the colour input --- src/web/assets/cp/dist/cp.js | 2 +- src/web/assets/cp/dist/cp.js.map | 2 +- src/web/assets/cp/dist/css/cp.css | 2 +- src/web/assets/cp/dist/css/cp.css.map | 2 +- src/web/assets/cp/src/css/_main.scss | 6 +++++- 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/web/assets/cp/dist/cp.js b/src/web/assets/cp/dist/cp.js index deadbe851f7..735f324cac7 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,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,draggingFocal:!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=$('