Skip to content

Commit

Permalink
Merge branch 'release/4.0.1' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
brandonkelly committed May 6, 2022
2 parents e345638 + d0b54f5 commit d4f2f5f
Show file tree
Hide file tree
Showing 28 changed files with 159 additions and 82 deletions.
4 changes: 2 additions & 2 deletions .github/ISSUE_TEMPLATE/BUG-REPORT-V4.yml
@@ -1,5 +1,5 @@
name: Bug Report – Craft 4 Beta
description: Report an issue or unexpected behavior pertaining to Craft 4 Beta
name: Bug Report – Craft 4
description: Report an issue or unexpected behavior pertaining to Craft 4
title: '[4.x]: '
labels:
- bug
Expand Down
11 changes: 11 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,16 @@
# Release Notes for Craft CMS 4

## 4.0.1 - 2022-05-06

### Fixed
- Fixed a bug where Money field labels’ `for` attributes weren’t referencing the correct input ID. ([#11016](https://github.com/craftcms/cms/pull/11016))
- Fixed a bug where Money field inputs weren’t getting `aria-describedby` attributes. ([#11016](https://github.com/craftcms/cms/pull/11016))
- Fixed an error that occurred when loading an edit screen for an element type that didn’t have a field layout. ([#11110](https://github.com/craftcms/cms/pull/11110))
- Fixed a bug where condition rules they weren’t selectable (per `isSelectable()`) were still visible in the rule dropdown menu. ([#11104](https://github.com/craftcms/cms/pull/11104))
- Fixed a bug where element edit pages could reload themselves immediately after saving the element. ([#11084](https://github.com/craftcms/cms/issues/11084))
- Fixed a bug where tabs weren’t interactive after changing an entry’s type. ([#11093](https://github.com/craftcms/cms/issues/11093))
- Fixed a bug where Twig syntax errors weren’t being handled properly. ([#11108](https://github.com/craftcms/cms/issues/11108))

## 4.0.0.1 - 2022-05-04

### Changed
Expand Down
6 changes: 5 additions & 1 deletion src/base/Element.php
Expand Up @@ -4721,7 +4721,11 @@ protected function fieldByHandle(string $handle): ?FieldInterface
*/
protected function fieldLayoutFields(bool $visibleOnly = false): array
{
$fieldLayout = $this->getFieldLayout();
try {
$fieldLayout = $this->getFieldLayout();
} catch (InvalidConfigException $e) {
return [];
}

if ($fieldLayout) {
return $visibleOnly ? $fieldLayout->getVisibleCustomFields($this) : $fieldLayout->getCustomFields();
Expand Down
13 changes: 9 additions & 4 deletions src/base/conditions/BaseCondition.php
Expand Up @@ -150,10 +150,15 @@ public function getSelectableConditionRules(): array
*/
protected function isConditionRuleSelectable(ConditionRuleInterface $rule): bool
{
return (
$rule->isSelectable() &&
!$this->forProjectConfig || $rule::supportsProjectConfig()
);
if (!$rule->isSelectable()) {
return false;
}

if ($this->forProjectConfig && !$rule::supportsProjectConfig()) {
return false;
}

return true;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/config/app.php
Expand Up @@ -3,7 +3,7 @@
return [
'id' => 'CraftCMS',
'name' => 'Craft CMS',
'version' => '4.0.0.1',
'version' => '4.0.1',
'schemaVersion' => '4.0.0.9',
'minVersionRequired' => '3.7.11',
'basePath' => dirname(__DIR__), // Defines the @app alias
Expand Down
2 changes: 1 addition & 1 deletion src/controllers/ElementsController.php
Expand Up @@ -719,7 +719,7 @@ private function _prepareEditor(

/** @var Response|CpScreenResponseBehavior $response */
$response
->tabs($form?->getTabMenu())
->tabs($form?->getTabMenu() ?? [])
->content($contentFn($form))
->sidebar($sidebarFn($form));

Expand Down
9 changes: 8 additions & 1 deletion src/elements/GlobalSet.php
Expand Up @@ -16,6 +16,7 @@
use craft\records\GlobalSet as GlobalSetRecord;
use craft\validators\HandleValidator;
use craft\validators\UniqueValidator;
use yii\base\InvalidConfigException;

/**
* GlobalSet represents a global set element.
Expand Down Expand Up @@ -281,7 +282,13 @@ public function beforeDelete(): bool
return false;
}

if (($fieldLayout = $this->getFieldLayout()) !== null) {
try {
$fieldLayout = $this->getFieldLayout();
} catch (InvalidConfigException $e) {
$fieldLayout = null;
}

if ($fieldLayout !== null) {
Craft::$app->getFields()->deleteLayout($fieldLayout);
}

Expand Down
8 changes: 8 additions & 0 deletions src/elements/conditions/entries/AuthorGroupConditionRule.php
Expand Up @@ -36,6 +36,14 @@ public function getExclusiveQueryParams(): array
return ['authorGroup', 'authorGroupId'];
}

/**
* @inheritdoc
*/
public static function isSelectable(): bool
{
return !empty(Craft::$app->getUserGroups()->getAllGroups());
}

/**
* @inheritdoc
*/
Expand Down
11 changes: 10 additions & 1 deletion src/elements/db/ElementQuery.php
Expand Up @@ -29,6 +29,7 @@
use craft\helpers\StringHelper;
use craft\models\Site;
use ReflectionClass;
use ReflectionException;
use ReflectionProperty;
use yii\base\ArrayableTrait;
use yii\base\Exception;
Expand Down Expand Up @@ -1351,7 +1352,15 @@ public function prepare($builder): Query

// If an element table was never joined in, explicitly filter based on the element type
if (!$this->_joinedElementTable && $this->elementType) {
$this->subQuery->andWhere(['elements.type' => $this->elementType]);
try {
$ref = new ReflectionClass($this->elementType);
} catch (ReflectionException) {
$ref = null;
}
/** @var ReflectionClass|null $ref */
if ($ref && !$ref->isAbstract()) {
$this->subQuery->andWhere(['elements.type' => $this->elementType]);
}
}

$this->_applyUniqueParam($builder->db);
Expand Down
3 changes: 1 addition & 2 deletions src/fields/Money.php
Expand Up @@ -17,7 +17,6 @@
use craft\gql\types\Money as MoneyType;
use craft\helpers\Db;
use craft\helpers\ElementHelper;
use craft\helpers\Html;
use craft\helpers\MoneyHelper;
use craft\validators\MoneyValidator;
use GraphQL\Type\Definition\Type;
Expand Down Expand Up @@ -248,7 +247,7 @@ protected function inputHtml(mixed $value, ?ElementInterface $element = null): s
]);
}

$id = Html::id($this->handle);
$id = $this->getInputId();
$namespacedId = $view->namespaceInputId($id);

$js = <<<JS
Expand Down
50 changes: 24 additions & 26 deletions src/services/Elements.php
Expand Up @@ -2799,36 +2799,34 @@ private function _saveElementInternal(ElementInterface $element, bool $runValida
$fieldLayout = $element->getFieldLayout();
$dirtyFields = $fieldLayout ? $element->getDirtyFields() : null;

Craft::$app->on(Application::EVENT_AFTER_REQUEST, function() use ($element, $fieldLayout, $dirtyAttributes, $dirtyFields) {
$userId = Craft::$app->getUser()->getId();
$timestamp = Db::prepareDateForDb(new DateTime());
$userId = Craft::$app->getUser()->getId();
$timestamp = Db::prepareDateForDb(new DateTime());

foreach ($dirtyAttributes as $attributeName) {
Db::upsert(Table::CHANGEDATTRIBUTES, [
'elementId' => $element->id,
'siteId' => $element->siteId,
'attribute' => $attributeName,
'dateUpdated' => $timestamp,
'propagated' => $element->propagating,
'userId' => $userId,
]);
}
foreach ($dirtyAttributes as $attributeName) {
Db::upsert(Table::CHANGEDATTRIBUTES, [
'elementId' => $element->id,
'siteId' => $element->siteId,
'attribute' => $attributeName,
'dateUpdated' => $timestamp,
'propagated' => $element->propagating,
'userId' => $userId,
]);
}

if ($fieldLayout) {
foreach ($dirtyFields as $fieldHandle) {
if (($field = $fieldLayout->getFieldByHandle($fieldHandle)) !== null) {
Db::upsert(Table::CHANGEDFIELDS, [
'elementId' => $element->id,
'siteId' => $element->siteId,
'fieldId' => $field->id,
'dateUpdated' => $timestamp,
'propagated' => $element->propagating,
'userId' => $userId,
]);
}
if ($fieldLayout) {
foreach ($dirtyFields as $fieldHandle) {
if (($field = $fieldLayout->getFieldByHandle($fieldHandle)) !== null) {
Db::upsert(Table::CHANGEDFIELDS, [
'elementId' => $element->id,
'siteId' => $element->siteId,
'fieldId' => $field->id,
'dateUpdated' => $timestamp,
'propagated' => $element->propagating,
'userId' => $userId,
]);
}
}
});
}
}

// Fire an 'afterSaveElement' event
Expand Down
3 changes: 2 additions & 1 deletion src/templates/_components/fieldtypes/Money/input.twig
@@ -1,7 +1,7 @@
{% import '_includes/forms' as forms %}

{{ forms.money({
id: field.handle|id,
id: id ?? field.getInputId(),
name: field.handle,
value: value ?? '',
size: field.size,
Expand All @@ -10,4 +10,5 @@
showCurrency: showCurrency,
decimals: decimals,
size: field.size,
describedBy: field.describedBy,
}) }}
2 changes: 1 addition & 1 deletion src/templates/_includes/forms/money.twig
@@ -1,7 +1,7 @@
{% import '_includes/forms' as forms %}
{% do view.registerAssetBundle("craft\\web\\assets\\money\\MoneyAsset") %}

{% set id = (id ?? "money#{random()}") ~ '-money' -%}
{% set id = id ?? "money#{random()}" -%}
{% set decimals = decimals ?? 2 %}
{% set name = name ?? null -%}
{% set value = not (value ?? false) ? null : value -%}
Expand Down
20 changes: 10 additions & 10 deletions src/translations/nl/app.php

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 18 additions & 3 deletions src/utilities/Upgrade.php
Expand Up @@ -53,12 +53,27 @@ public static function contentHtml(): string
$view = Craft::$app->getView();
$view->registerAssetBundle(UpgradeAsset::class);

$pluginsService = Craft::$app->getPlugins();
$allPlugins = [];
foreach ($pluginsService->getAllPluginInfo() as $handle => $info) {
$allPlugins[] = [
'name' => $info['name'],
'handle' => $handle,
'developerName' => $info['developer'] ?? null,
'developerUrl' => $info['developerUrl'] ?? null,
'icon' => $pluginsService->getPluginIconSvg($handle),
'isInstalled' => $info['isInstalled'],
];
}

$version = (int)Craft::$app->version + 1;
$view->registerJsWithVars(function($version) {
$view->registerJsWithVars(function($args) {
return <<<JS
new Craft.UpgradeUtility($version);
window.upgardeUtility = new Craft.UpgradeUtility(...$args);
JS;
}, [$version]);
}, [
[$version, $allPlugins],
]);

return $view->renderTemplate('_components/utilities/Upgrade');
}
Expand Down
4 changes: 2 additions & 2 deletions src/web/TemplateResponseFormatter.php
Expand Up @@ -11,7 +11,7 @@
use craft\helpers\FileHelper;
use craft\helpers\StringHelper;
use craft\web\assets\iframeresizer\ContentWindowAsset;
use Twig\Error\RuntimeError;
use Twig\Error\Error as TwigError;
use yii\base\Component;
use yii\base\ExitException;
use yii\base\InvalidConfigException;
Expand Down Expand Up @@ -50,7 +50,7 @@ public function format($response)
// Render and return the template
try {
$response->content = $view->renderPageTemplate($behavior->template, $behavior->variables, $behavior->templateMode);
} catch (RuntimeError $e) {
} catch (TwigError $e) {
if (!$e->getPrevious() instanceof ExitException) {
// Bail on the template response
$response->format = Response::FORMAT_HTML;
Expand Down
2 changes: 1 addition & 1 deletion src/web/assets/cp/dist/cp.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/web/assets/cp/dist/cp.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/web/assets/cp/src/js/Craft.js
Expand Up @@ -403,7 +403,7 @@ $.extend(Craft, {
* @return string
*/
formatInputId: function (inputName) {
return this.rtrim(inputName.replace(/[^\w]+/g, '-'), '-');
return this.rtrim(inputName.replace(/[^\w\-]+/g, '-'), '-');
},

/**
Expand Down
8 changes: 2 additions & 6 deletions src/web/assets/cp/src/js/ElementEditor.js
Expand Up @@ -178,12 +178,8 @@ Craft.ElementEditor = Garnish.Base.extend(
});

if (this.isFullPage && Craft.messageReceiver) {
Craft.messageReceiver.addEventListener('message', (ev) => {
// Ignore broadcasts from this page
if (ev.data.pageId === Craft.pageId) {
return;
}

// Listen on Craft.broadcaster to ignore any messages sent by this very page
Craft.broadcaster.addEventListener('message', (ev) => {
if (
(ev.data.event === 'saveDraft' &&
ev.data.canonicalId === this.settings.canonicalId &&
Expand Down

0 comments on commit d4f2f5f

Please sign in to comment.