Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG-WIP.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
- Matrix fields no longer have “Duplicate” and “Delete” field-level actions. ([#18561](https://github.com/craftcms/cms/pull/18561))
- Number fields now show their selected currency beside their input, if their Preview Format setting is set to “As currency values”. ([#18498](https://github.com/craftcms/cms/pull/18498))
- Color field previews are now blank for fields without a value. ([#18614](https://github.com/craftcms/cms/issues/18614))
- Text condition rules now have “does not equal” operators.
- Text condition rules now have “does not equal”, “is one of” and “is not one of” operators.
- Numeric condition rules now have “is one of” and “is not one of” operators. ([#18734](https://github.com/craftcms/cms/pull/18734))
- Editable table columns now set `min-width` styles based on their configured widths, if set. ([#18534](https://github.com/craftcms/cms/issues/18534))
- Entry post dates are no longer automatically set until the entry is fully saved as enabled. ([#18642](https://github.com/craftcms/cms/pull/18642))
- Element edit screens now have a “Save as a new draft” action when editing an explicitly-created draft. ([#18722](https://github.com/craftcms/cms/pull/18722))
Expand Down
4 changes: 3 additions & 1 deletion src/base/conditions/BaseNumberConditionRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ protected function operators(): array
self::OPERATOR_BETWEEN,
self::OPERATOR_NOT_EMPTY,
self::OPERATOR_EMPTY,
self::OPERATOR_IN,
self::OPERATOR_NOT_IN,
];
}

Expand Down Expand Up @@ -128,7 +130,7 @@ protected function inputHtml(): string
/**
* @inheritdoc
*/
protected function paramValue(): ?string
protected function paramValue(): string|array|null
{
if ($this->operator === self::OPERATOR_BETWEEN) {
if (empty($this->value) && empty($this->maxValue)) {
Expand Down
70 changes: 63 additions & 7 deletions src/base/conditions/BaseTextConditionRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

namespace craft\base\conditions;

use craft\helpers\ArrayHelper;
use craft\helpers\Cp;
use craft\helpers\Db;
use craft\helpers\Html;
use craft\helpers\Json;
use craft\helpers\StringHelper;
use yii\base\InvalidConfigException;

Expand Down Expand Up @@ -41,6 +43,20 @@ public function getConfig(): array
]);
}

public function __set($name, $value)
{
if (
$name === 'attributes' &&
isset($value['operator'], $value['value']) &&
in_array($value['operator'], [self::OPERATOR_IN, self::OPERATOR_NOT_IN]) &&
is_array($value['value'])
) {
$value['value'] = Json::encode($value['value']);
}

parent::__set($name, $value);
}

/**
* Returns the operators that should be allowed for this rule.
*
Expand All @@ -56,6 +72,8 @@ protected function operators(): array
self::OPERATOR_CONTAINS,
self::OPERATOR_NOT_EMPTY,
self::OPERATOR_EMPTY,
self::OPERATOR_IN,
self::OPERATOR_NOT_IN,
];
}

Expand All @@ -78,6 +96,11 @@ protected function inputHtml(): string
if ($this->operator === self::OPERATOR_EMPTY || $this->operator === self::OPERATOR_NOT_EMPTY) {
return '';
}

if (in_array($this->operator, [self::OPERATOR_IN, self::OPERATOR_NOT_IN])) {
return Cp::selectizeHtml($this->inputOptions());
}

return
Html::hiddenLabel(Html::encode($this->getLabel()), 'value') .
Cp::textHtml($this->inputOptions());
Expand All @@ -91,14 +114,37 @@ protected function inputHtml(): string
*/
protected function inputOptions(): array
{
return [
'type' => $this->inputType(),
'id' => 'value',
$defaults = [
'id' => 'value' . mt_rand(),
'name' => 'value',
'value' => $this->value,
'autocomplete' => false,
'class' => 'flex-grow flex-shrink',
];

if (in_array($this->operator, [self::OPERATOR_IN, self::OPERATOR_NOT_IN])) {
$values = Json::decodeIfJson($this->value);
$values = is_array($values) ? array_values($values) : [];

return [...$defaults, ...[
'values' => $values,
'options' => array_map(fn($v) => ['value' => $v, 'label' => $v], $values),
'multi' => true,
'allowEmptyOption' => true,
'selectizeOptions' => [
'create' => true,
'persist' => false,
'createOnBlur' => true,
],
]];
}

return [
...$defaults,
...[
'type' => $this->inputType(),
'value' => $this->value,
'autocomplete' => false,
],
];
}

/**
Expand All @@ -114,15 +160,23 @@ protected function defineRules(): array
/**
* Returns the rule’s value, prepped for [[Db::parseParam()]] based on the selected operator.
*
* @return string|null
* @return array|string|null
*/
protected function paramValue(): ?string
protected function paramValue(): string|array|null
{
switch ($this->operator) {
case self::OPERATOR_EMPTY:
return ':empty:';
case self::OPERATOR_NOT_EMPTY:
return 'not :empty:';
case self::OPERATOR_IN:
return Json::decodeIfJson($this->value);
case self::OPERATOR_NOT_IN:
$value = Json::decodeIfJson($this->value);
$value = is_array($value) ? $value : [];
ArrayHelper::prependOrAppend($value, 'not', true);

return $value;
}

if ($this->value === '') {
Expand Down Expand Up @@ -168,6 +222,8 @@ protected function matchValue(mixed $value): bool
self::OPERATOR_BEGINS_WITH => is_string($value) && StringHelper::startsWith($value, $this->value, false),
self::OPERATOR_ENDS_WITH => is_string($value) && StringHelper::endsWith($value, $this->value, false),
self::OPERATOR_CONTAINS => is_string($value) && StringHelper::contains($value, $this->value, false),
self::OPERATOR_IN => in_array($value, Json::decodeIfJson($this->value)),
self::OPERATOR_NOT_IN => !in_array($value, Json::decodeIfJson($this->value)),
default => throw new InvalidConfigException("Invalid operator: $this->operator"),
};
}
Expand Down
12 changes: 12 additions & 0 deletions src/fields/conditions/MoneyFieldConditionRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,18 @@ class MoneyFieldConditionRule extends BaseNumberConditionRule implements FieldCo
{
use FieldConditionRuleTrait;

/**
* @inerhitdoc
*/
protected function operators(): array
{
return array_filter(
parent::operators(),
// Remove IN/NOT IN operators as they don't fit with the implementation of money inputs
fn(string $operator) => !in_array($operator, [self::OPERATOR_IN, self::OPERATOR_NOT_IN])
);
}

/**
* @inheritdoc
*/
Expand Down
2 changes: 1 addition & 1 deletion src/fields/conditions/NumberFieldConditionRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class NumberFieldConditionRule extends BaseNumberConditionRule implements FieldC
/**
* @inheritdoc
*/
protected function elementQueryParam(): ?string
protected function elementQueryParam(): string|array|null
{
return $this->paramValue();
}
Expand Down