Skip to content

Commit

Permalink
Merge branch '5.4' into feature/cms-1336-add-inline-editing-support-f…
Browse files Browse the repository at this point in the history
…or-post-date-expiry-date-etc

# Conflicts:
#	src/web/assets/cp/dist/cp.js
#	src/web/assets/cp/dist/cp.js.map
  • Loading branch information
brandonkelly committed Aug 24, 2024
2 parents 0188628 + 41ff132 commit e0541cd
Show file tree
Hide file tree
Showing 21 changed files with 199 additions and 111 deletions.
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,22 @@

## Unreleased

- Fixed a bug where it wasn’t possible to override named transforms in GraphQL queries. ([#15572](https://github.com/craftcms/cms/issues/15572))

## 5.3.5 - 2024-08-21

- Updated jQuery UI to 1.13.3. ([#15558](https://github.com/craftcms/cms/issues/15558))
- Fixed a bug where `craft\helpers\App::env()` and `normalizeValue()` could return incorrect results for values that looked like floats. ([#15533](https://github.com/craftcms/cms/issues/15533))
- Fixed a bug where the `users/set-password` action wasn’t respecting `redirect` params. ([#15538](https://github.com/craftcms/cms/issues/15538))
- Fixed a bug where the “Default Values” Table field setting wasn’t escaping column headings. ([#15552](https://github.com/craftcms/cms/issues/15552))
- Fixed a bug where Craft couldn’t be installed with existing project config files, if any plugins specified their schema version via `composer.json`. ([#15559](https://github.com/craftcms/cms/issues/15559))
- Fixed a bug where Money fields’ min, max, and default values weren’t being set to the correct currency. ([#15565](https://github.com/craftcms/cms/issues/15565), [#15566](https://github.com/craftcms/cms/pull/15566))
- Fixed a bug where Money fields weren’t handling negative values correctly. ([#15565](https://github.com/craftcms/cms/issues/15565), [#15567](https://github.com/craftcms/cms/pull/15567))
- Fixed a bug where PHP-originated Craft Console API requests weren’t timing out if the API was down. ([#15571](https://github.com/craftcms/cms/pull/15571))
- Fixed a bug where admin tables weren’t displaying disabled statuses. ([#15540](https://github.com/craftcms/cms/pull/15540))
- Fixed a JavaScript error that occurred when adding a row to an editable table that didn’t allow reordering rows. ([#15543](https://github.com/craftcms/cms/issues/15543))
- Fixed an error that occurred when editing an element with a Link field previously set to a URL value, if the field no longer allows URLs. ([#15542](https://github.com/craftcms/cms/issues/15542))
- Fixed an error that could occru when upgrading to Craft 5. ([#15539](https://github.com/craftcms/cms/issues/15539), [#15555](https://github.com/craftcms/cms/issues/15555))

## 5.3.4 - 2024-08-13

Expand Down
18 changes: 9 additions & 9 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
"iframe-resizer": "^4.3.2",
"inputmask": "^5.0.9",
"jquery": "^3.6.0",
"jquery-ui": "^1.13.1",
"jquery-ui": "^1.13.3",
"jquery.payment": "^3.0.0",
"picturefill": "^3.0.3",
"punycode": "^2.3.1",
Expand Down
2 changes: 1 addition & 1 deletion src/base/Element.php
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ abstract class Element extends Component implements ElementInterface
public const EVENT_DEFINE_ADDITIONAL_BUTTONS = 'defineAdditionalButtons';

/**
* @event DefineMenuComponentEvent The event that is triggered when defining action menu items..
* @event DefineMenuItemsEvent The event that is triggered when defining action menu items..
* @see getActionMenuItems()
* @since 5.0.0
*/
Expand Down
2 changes: 1 addition & 1 deletion src/config/app.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
return [
'id' => 'CraftCMS',
'name' => 'Craft CMS',
'version' => '5.3.4',
'version' => '5.3.5',
'schemaVersion' => '5.3.0.2',
'minVersionRequired' => '4.5.0',
'basePath' => dirname(__DIR__), // Defines the @app alias
Expand Down
80 changes: 61 additions & 19 deletions src/fields/Link.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
use craft\fields\linktypes\Entry;
use craft\fields\linktypes\Phone;
use craft\fields\linktypes\Url as UrlType;
use craft\helpers\ArrayHelper;
use craft\helpers\Component;
use craft\helpers\Cp;
use craft\helpers\Html;
Expand Down Expand Up @@ -161,12 +162,30 @@ public function getLinkTypes(): array

private function resolveType(string $value): string
{
foreach ($this->getLinkTypes() as $id => $linkType) {
if ($id !== UrlType::id() && $linkType->supports($value)) {
$linkTypes = $this->getLinkTypes();

// check URL last, if it's selected
$urlType = ArrayHelper::remove($linkTypes, UrlType::id());
if ($urlType) {
$linkTypes[UrlType::id()] = $urlType;
}

foreach ($linkTypes as $id => $linkType) {
if ($linkType->supports($value)) {
return $id;
}
}

// See if any unselected types support it
foreach (self::types() as $typeId => $type) {
if (!isset($linkTypes[$typeId]) && $type !== UrlType::class) {
$linkType = Component::createComponent($type, BaseLinkType::class);
if ($linkType->supports($value)) {
return $linkType::id();
}
}
}

return UrlType::id();
}

Expand Down Expand Up @@ -311,23 +330,28 @@ public function normalizeValue(mixed $value, ?ElementInterface $element): mixed
$typeId = $value['type'] ?? UrlType::id();
$value = trim($value[$typeId]['value'] ?? '');

if (!isset($linkTypes[$typeId])) {
throw new InvalidArgumentException("Invalid link type: $typeId");
}

if (!$value) {
return null;
}

$linkType = $linkTypes[$typeId];
if (isset($linkTypes[$typeId])) {
$linkType = $linkTypes[$typeId];
} else {
$type = self::types()[$typeId] ?? null;
if (!$type) {
throw new InvalidArgumentException("Invalid link type: $typeId");
}
$linkType = Component::createComponent($type, BaseLinkType::class);
}

$value = $linkType->normalizeValue(str_replace(' ', '+', $value));
} else {
if (!$value) {
return null;
}

$typeId = $this->resolveType($value);
$linkType = $linkTypes[$typeId];
$linkType = $linkTypes[$typeId] ?? Component::createComponent(self::types()[$typeId], BaseLinkType::class);
}

return new LinkData($value, $linkType);
Expand All @@ -347,16 +371,26 @@ public function useFieldset(): bool
protected function inputHtml(mixed $value, ?ElementInterface $element, bool $inline): string
{
$linkTypes = $this->getLinkTypes();
$valueTypeId = null;

/** @var LinkData|null $value */
if ($value) {
$valueTypeId = $value->type;
} else {

if (!isset($linkTypes[$valueTypeId])) {
$type = self::types()[$valueTypeId] ?? null;
if ($type) {
$linkTypes[$valueTypeId] = Component::createComponent($type, BaseLinkType::class);
} else {
$value = null;
}
}
}

if (!$value) {
$valueTypeId = in_array(UrlType::id(), $this->types) ? UrlType::id() : reset($this->types);
}

$allowedTypeIds = in_array($valueTypeId, $this->types) ? $this->types : array_merge($this->types, [$valueTypeId]);
$allowedTypeIds = array_filter($allowedTypeIds, fn(string $typeId) => isset($linkTypes[$typeId]));
$id = $this->getInputId();

$view = Craft::$app->getView();
Expand All @@ -371,7 +405,7 @@ protected function inputHtml(mixed $value, ?ElementInterface $element, bool $inl

$typeInputName = "$this->handle[type]";

if (count($allowedTypeIds) === 1) {
if (count($linkTypes) === 1) {
$innerHtml = Html::hiddenInput($typeInputName, $valueTypeId);
} else {
$namespacedId = $view->namespaceInputId($id);
Expand All @@ -389,10 +423,10 @@ protected function inputHtml(mixed $value, ?ElementInterface $element, bool $inl
'id' => "$id-type",
'describedBy' => $this->describedBy,
'name' => $typeInputName,
'options' => array_map(fn(string $typeId) => [
'label' => $linkTypes[$typeId]::displayName(),
'value' => $linkTypes[$typeId]::id(),
], $allowedTypeIds),
'options' => array_map(fn(BaseLinkType $linkType) => [
'label' => $linkType::displayName(),
'value' => $linkType::id(),
], $linkTypes),
'value' => $valueTypeId,
'inputAttributes' => [
'aria' => [
Expand All @@ -404,12 +438,12 @@ protected function inputHtml(mixed $value, ?ElementInterface $element, bool $inl
]);
}

foreach ($allowedTypeIds as $typeId) {
foreach ($linkTypes as $typeId => $linkType) {
$containerId = "$id-$typeId";
$nsContainerId = $view->namespaceInputId($containerId);
$selected = $typeId === $valueTypeId;
$typeValue = $selected ? $value?->serialize() : null;
$isTextLink = is_subclass_of($linkTypes[$typeId], BaseTextLinkType::class);
$isTextLink = is_subclass_of($linkType, BaseTextLinkType::class);
$innerHtml .=
Html::beginTag('div', [
'id' => $containerId,
Expand All @@ -420,7 +454,7 @@ protected function inputHtml(mixed $value, ?ElementInterface $element, bool $inl
])),
]) .
$view->namespaceInputs(
fn() => $linkTypes[$typeId]->inputHtml($this, $typeValue, $nsContainerId),
fn() => $linkType->inputHtml($this, $typeValue, $nsContainerId),
"$this->handle[$typeId]",
) .
Html::endTag('div');
Expand Down Expand Up @@ -450,6 +484,14 @@ function(ElementInterface $element) {
/** @var LinkData $value */
$value = $element->getFieldValue($this->handle);
$linkTypes = $this->getLinkTypes();
if (!isset($linkTypes[$value->type])) {
$type = self::types()[$value->type] ?? null;
$element->addError("field:$this->handle", Craft::t('app', '{attribute} no longer allows {type} links.', [
'attribute' => $this->getUiLabel(),
'type' => is_subclass_of($type, BaseLinkType::class) ? $type::displayName() : $type,
]));
return;
}
$linkType = $linkTypes[$value->type];
$error = null;
if (!$linkType->validateValue($value->serialize(), $error)) {
Expand Down
19 changes: 12 additions & 7 deletions src/fields/Money.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,9 @@ public function __construct($config = [])
// Config normalization
foreach (['defaultValue', 'min', 'max'] as $name) {
if (isset($config[$name])) {
$config[$name] = $this->_normalizeNumber($config[$name]);
// at this point the currency property isn't set yet, so we need to explicitly pass it to the _normalizeNumber()
// see https://github.com/craftcms/cms/issues/15565 for more details
$config[$name] = $this->_normalizeNumber($config[$name], $config['currency'] ?? null);
}
}

Expand Down Expand Up @@ -212,10 +214,10 @@ public function normalizeValue(mixed $value, ?ElementInterface $element): mixed
}

// Fail-safe if the value is not in the correct format
// Try to normalize the value if there are any non-numeric characters
if (is_string($value) && !preg_match('/^\d+$/', $value)) {
// Try to normalize the value if there are any non-numeric characters (except minus sign at the start)
if (is_string($value) && !preg_match('/^(-?)\d+$/', $value)) {
try {
$value = MoneyHelper::normalizeString($value);
$value = MoneyHelper::normalizeString($value, new Currency($this->currency));
} catch (ParserException) {
// Catch a parse and return appropriately
if (isset($this->defaultValue) && $this->isFresh($element)) {
Expand Down Expand Up @@ -247,26 +249,29 @@ public function serializeValue(mixed $value, ElementInterface $element = null):

/**
* @param mixed $value
* @param string|null $currency
* @return string|null
*/
private function _normalizeNumber(mixed $value): ?string
private function _normalizeNumber(mixed $value, ?string $currency = null): ?string
{
if ($value === '') {
return null;
}

$currency ??= $this->currency;

// Was this submitted with a locale ID? (This means the data is coming from the settings form)
if (isset($value['locale'], $value['value'])) {
if ($value['value'] === '') {
return null;
}

$value['currency'] = $this->currency;
$value['currency'] = $currency;
$money = MoneyHelper::toMoney($value);
return $money ? $money->getAmount() : null;
}

$money = new MoneyLibrary($value, new Currency($this->currency));
$money = new MoneyLibrary($value, new Currency($currency));
return $money->getAmount();
}

Expand Down
11 changes: 4 additions & 7 deletions src/helpers/Gql.php
Original file line number Diff line number Diff line change
Expand Up @@ -385,15 +385,12 @@ public static function prepareTransformArguments(array $arguments): array|string
{
unset($arguments['immediately']);

if (!empty($arguments['handle'])) {
$transform = $arguments['handle'];
} elseif (!empty($arguments['transform'])) {
$transform = $arguments['transform'];
} else {
$transform = $arguments;
// Remap handle to transform to work with image transform normalization
if (isset($arguments['handle'])) {
$arguments = $arguments['handle'];
}

return $transform;
return $arguments;
}

/**
Expand Down
9 changes: 7 additions & 2 deletions src/migrations/Install.php
Original file line number Diff line number Diff line change
Expand Up @@ -1202,8 +1202,13 @@ private function _validateProjectConfig(string &$error = null): bool
return false;
}

$pluginRef = new ReflectionClass($pluginInfo['class']);
$schemaVersion = $pluginRef->getProperty('schemaVersion')->getDefaultValue();
if (isset($pluginInfo['schemaVersion'])) {
$schemaVersion = $pluginInfo['schemaVersion'];
} else {
$pluginRef = new ReflectionClass($pluginInfo['class']);
$schemaVersion = $pluginRef->getProperty('schemaVersion')->getDefaultValue();
}

$expectedSchemaVersion = $pluginConfig['schemaVersion'] ?? null;

if ($schemaVersion && $expectedSchemaVersion && $schemaVersion != $expectedSchemaVersion) {
Expand Down
1 change: 1 addition & 0 deletions src/services/Api.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public function init(): void
if (!isset($this->client)) {
$this->client = Craft::createGuzzleClient([
'base_uri' => Craft::$app->baseApiUrl,
'connect_timeout' => 15,
]);
}
}
Expand Down
Loading

0 comments on commit e0541cd

Please sign in to comment.