diff --git a/.github/ISSUE_TEMPLATE/BUG-REPORT-V3.yml b/.github/ISSUE_TEMPLATE/BUG-REPORT-V3.yml index 56c0f66b57b..7c3e24a96d8 100644 --- a/.github/ISSUE_TEMPLATE/BUG-REPORT-V3.yml +++ b/.github/ISSUE_TEMPLATE/BUG-REPORT-V3.yml @@ -1,4 +1,4 @@ -name: Bug Report – Craft 3 +name: 'Bug Report: Craft 3' description: Report an issue or unexpected behavior pertaining to Craft 3 title: '[3.x]: ' labels: diff --git a/.github/ISSUE_TEMPLATE/BUG-REPORT-V4.yml b/.github/ISSUE_TEMPLATE/BUG-REPORT-V4.yml index 71fab5a13b1..26657d2b371 100644 --- a/.github/ISSUE_TEMPLATE/BUG-REPORT-V4.yml +++ b/.github/ISSUE_TEMPLATE/BUG-REPORT-V4.yml @@ -1,4 +1,4 @@ -name: Bug Report – Craft 4 +name: 'Bug Report: Craft 4' description: Report an issue or unexpected behavior pertaining to Craft 4 title: '[4.x]: ' labels: diff --git a/.github/ISSUE_TEMPLATE/BUG-REPORT-V5.yml b/.github/ISSUE_TEMPLATE/BUG-REPORT-V5.yml index 79ef6efce80..03d6484c666 100644 --- a/.github/ISSUE_TEMPLATE/BUG-REPORT-V5.yml +++ b/.github/ISSUE_TEMPLATE/BUG-REPORT-V5.yml @@ -1,4 +1,4 @@ -name: Bug Report – Craft 5 +name: 'Bug Report: Craft 5' description: Report an issue or unexpected behavior pertaining to Craft 5 title: '[5.x]: ' labels: diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 4703d4c8f3f..4c8880f1d0e 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,20 +1,41 @@ blank_issues_enabled: false contact_links: - - name: Feature Request - url: https://github.com/craftcms/cms/discussions/new?category=ideas - about: Start a new discussion about your idea - name: Documentation - url: https://docs.craftcms.com/ + url: https://craftcms.com/docs about: Read the official documentation - name: Knowledge Base url: https://craftcms.com/knowledge-base - about: Find answers to common problems + about: Find official answers to common problems - name: Developer Support Services url: https://craftcms.com/support-services about: Priority developer support from the team that makes Craft - name: Craft Discord url: https://craftcms.com/discord about: Meet the community - - name: Stack Exchange + - name: Craft Stack Exchange url: https://craftcms.stackexchange.com/ about: Get help and help others + - name: 'Feature Request: Craft CMS' + url: https://github.com/craftcms/cms/discussions/new?category=ideas + about: Make a feature request or enhancement for Craft CMS + - name: 'Feature Request: Craft Console / Plugin Store' + url: https://github.com/craftcms/console/discussions/new?category=ideas + about: Make a feature request or enhancement for Craft Console or the Plugin Store + - name: 'Feature Request: Craft Cloud' + url: https://github.com/craftcms/cloud/discussions/new?category=ideas + about: Make a feature request or enhancement for Craft Cloud + - name: 'Feature Request: Craft Commerce' + url: https://github.com/craftcms/commerce/discussions/new?category=ideas + about: Make a feature request or enhancement for Craft Commerce + - name: 'Bug Report: Craft CMS' + url: https://github.com/craftcms/cms/issues/new/choose + about: Create a bug report for Craft CMS + - name: 'Bug Report: Craft Console / Plugin Store' + url: https://github.com/craftcms/console/issues/new/choose + about: Create a bug report for Craft Console or the Plugin Store + - name: 'Bug Report: Craft Cloud' + url: https://craftcms.com/contact + about: Create a bug report for Craft Cloud + - name: 'Bug Report: Craft Commerce' + url: https://github.com/craftcms/commerce/issues/new/choose + about: Create a bug report for Craft Commerce diff --git a/CHANGELOG.md b/CHANGELOG.md index ff489ae15bd..86f9fcfc9ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Release Notes for Craft CMS 4 +## 4.7.3 - 2024-02-15 + +- Updated the bundled `composer.phar` to Composer 2.7.1. ([CVE-2024-24821](https://github.com/advisories/GHSA-7c6p-848j-wh5h)) +- Fixed a bug where read/write splitting was always getting disabled for GraphQL POST requests. ([#14324](https://github.com/craftcms/cms/issues/14324)) +- Fixed a bug where GraphQL schema edit pages could include empty category headings. +- Fixed a bug where asset slideouts weren’t showing validation errors on the Filename field. ([#14329](https://github.com/craftcms/cms/issues/14329)) +- Fixed a bug where element slideouts would open when long-pressing on an element’s “Remove” button within an element select input. +- Fixed a bug where relations weren’t getting deleted when an element was deleted for a site. ([#14347](https://github.com/craftcms/cms/issues/14347)) +- Fixed a SQL error that occurred when saving a Number field with Decimals set to more than 30 on MySQL. ([#14370](https://github.com/craftcms/cms/issues/14370)) + ## 4.7.2.1 - 2024-02-08 - Craft now requires Composer ^2.7.0. ([CVE-2024-24821](https://github.com/advisories/GHSA-7c6p-848j-wh5h)) diff --git a/lib/composer.phar b/lib/composer.phar index d39c3e6df0d..bd5bab8c1f5 100755 Binary files a/lib/composer.phar and b/lib/composer.phar differ diff --git a/src/config/app.php b/src/config/app.php index ff8abb5bf66..0cbdcce00a9 100644 --- a/src/config/app.php +++ b/src/config/app.php @@ -3,7 +3,7 @@ return [ 'id' => 'CraftCMS', 'name' => 'Craft CMS', - 'version' => '4.7.2.1', + 'version' => '4.7.3', 'schemaVersion' => '4.5.3.0', 'minVersionRequired' => '3.7.11', 'basePath' => dirname(__DIR__), // Defines the @app alias diff --git a/src/elements/Asset.php b/src/elements/Asset.php index 6aac6001e35..e172eb3c1fe 100644 --- a/src/elements/Asset.php +++ b/src/elements/Asset.php @@ -2540,7 +2540,7 @@ public function getPreviewHtml(): string Html::tag('div', $this->getPreviewThumbImg(350, 190), [ 'class' => 'preview-thumb', ]) . - Html::endTag('div'); // .preview-thumb-container; + Html::endTag('div'); // .preview-thumb-container if ($previewable || $editable) { $isMobile = Craft::$app->getRequest()->isMobileBrowser(true); @@ -2557,6 +2557,7 @@ public function getPreviewHtml(): string $imageButtonHtml .= Html::button(Craft::t('app', 'Preview'), [ 'id' => 'preview-btn', 'class' => ['btn', 'preview-btn'], + 'aria-label' => Craft::t('app', 'Preview'), ]); $previewBtnId = $view->namespaceInputId('preview-btn'); @@ -2666,6 +2667,7 @@ protected function metaFieldsHtml(bool $static): string return implode("\n", [ Cp::textFieldHtml([ 'label' => Craft::t('app', 'Filename'), + 'attribute' => 'newLocation', 'id' => 'new-filename', 'name' => 'newFilename', 'value' => $this->_filename, diff --git a/src/fields/BaseRelationField.php b/src/fields/BaseRelationField.php index ac0092780b8..221e6f17006 100644 --- a/src/fields/BaseRelationField.php +++ b/src/fields/BaseRelationField.php @@ -1013,6 +1013,22 @@ public function afterElementSave(ElementInterface $element, bool $isNew): void parent::afterElementSave($element, $isNew); } + /** + * @inheritdoc + */ + public function afterElementDeleteForSite(ElementInterface $element): void + { + if ($this->localizeRelations) { + Db::delete(DbTable::RELATIONS, [ + 'fieldId' => $this->id, + 'sourceSiteId' => $element->siteId, + 'sourceId' => $element->id, + ]); + } + + parent::afterElementDeleteForSite($element); + } + /** * Normalizes the available sources into select input options. * diff --git a/src/fields/Number.php b/src/fields/Number.php index 3b5e9829434..8fce41a62be 100644 --- a/src/fields/Number.php +++ b/src/fields/Number.php @@ -130,6 +130,11 @@ protected function defineRules(): array $rules = parent::defineRules(); $rules[] = [['defaultValue', 'min', 'max'], 'number']; $rules[] = [['decimals', 'size'], 'integer']; + + if ($this->decimals && Craft::$app->getDb()->getIsMysql()) { + $rules[] = [['decimals'], 'integer', 'max' => 30]; + } + $rules[] = [ ['max'], 'compare', diff --git a/src/templates/graphql/schemas/_edit.twig b/src/templates/graphql/schemas/_edit.twig index 46a64675d1e..64c6bdd3570 100644 --- a/src/templates/graphql/schemas/_edit.twig +++ b/src/templates/graphql/schemas/_edit.twig @@ -85,7 +85,7 @@ {% set schemaComponents = craft.app.gql.getAllSchemaComponents %} - {% for category, catPermissions in schemaComponents.queries %} + {% for category, catPermissions in schemaComponents.queries|filter %}

{{ category }}

@@ -97,7 +97,7 @@

{{ 'Choose the available mutations for this schema:'|t('app') }}

- {% for category, catPermissions in schemaComponents.mutations %} + {% for category, catPermissions in schemaComponents.mutations|filter %}

{{ category }}

diff --git a/src/web/Application.php b/src/web/Application.php index 3fa72bf9169..8dae1f2ff4a 100644 --- a/src/web/Application.php +++ b/src/web/Application.php @@ -161,7 +161,7 @@ public function handleRequest($request, bool $skipSpecialHandling = false): Resp // Process resource requests before anything else $this->_processResourceRequest($request); - // Disable read/write splitting for POST requests + // Disable read/write splitting for most POST requests if ( $request->getIsPost() && !in_array($request->getActionSegments(), [ @@ -171,7 +171,9 @@ public function handleRequest($request, bool $skipSpecialHandling = false): Resp ['element-indexes', 'get-elements'], ['element-indexes', 'get-more-elements'], ['element-indexes', 'get-source-tree-html'], - ]) + ['graphql', 'api'], + ]) && + !$request->getIsGraphql() ) { $this->getDb()->enableReplicas = false; } diff --git a/src/web/Request.php b/src/web/Request.php index 7ecf672b05b..08b28dfc532 100644 --- a/src/web/Request.php +++ b/src/web/Request.php @@ -30,7 +30,6 @@ /** * @inheritdoc * @property string $fullPath The full requested path, including the control panel trigger and pagination info. - * @property string $path The requested path, sans control panel trigger and pagination info. * @property array $segments The segments of the requested path. * @property int $pageNum The requested page number. * @property string $token The token submitted with the request, if there is one. diff --git a/src/web/assets/cp/dist/cp.js b/src/web/assets/cp/dist/cp.js index 7eceab91e12..69aba9489fa 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 i=t.keyCode;i!==Garnish.SPACE_KEY&&i!==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 i=0;i .address-card");for(var s=0;s=this.settings.maxItems)){var e=$(t).appendTo(this.$tbody),i=e.find(".delete");this.settings.sortable&&this.sorter.addItems(e),this.$deleteBtns=this.$deleteBtns.add(i),this.addListener(i,"click","handleDeleteBtnClick"),this.totalItems++,this.updateUI()}},reorderItems:function(){var t=this;if(this.settings.sortable){for(var e=[],i=0;i=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 i=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=$('