Skip to content
Open
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
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## 2.6.1 under development

- no changes in this release.
- Bug #817: Fix `UniqueIterable` comparing the whole iterable instead of its items (@CorvusSharp)

## 2.6.0 June 02, 2026

Expand Down
24 changes: 12 additions & 12 deletions src/Rule/UniqueIterableHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,22 +57,22 @@ public function validate(mixed $value, RuleInterface $rule, ValidationContext $c

$previousItem = $item;

if (!empty($stack) && count($stack) !== count(array_unique($stack, flags: SORT_REGULAR))) {
return (new Result())->addError($rule->getMessage(), [
'property' => $context->getTranslatedProperty(),
'Property' => $context->getCapitalizedTranslatedProperty(),
]);
}

if ($value instanceof Stringable) {
$stack[] = (string) $value;
} elseif ($value instanceof DateTimeInterface) {
$stack[] = $value->getTimestamp();
if ($item instanceof Stringable) {
$stack[] = (string) $item;
} elseif ($item instanceof DateTimeInterface) {
$stack[] = $item->getTimestamp();
} else {
$stack[] = $value;
$stack[] = $item;
}
}

if (count($stack) !== count(array_unique($stack, flags: SORT_REGULAR))) {
return (new Result())->addError($rule->getMessage(), [
'property' => $context->getTranslatedProperty(),
'Property' => $context->getCapitalizedTranslatedProperty(),
]);
}

return new Result();
}

Expand Down
71 changes: 71 additions & 0 deletions tests/Rule/UniqueIterableTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,40 @@ public function __toString()
[new DateTime('2024-04-10 14:05:01'), new DateTime('2024-04-10 14:05:02')],
new UniqueIterable(),
],
'more than two unique strings' => [['a', 'b', 'c'], new UniqueIterable()],
'more than two unique integers' => [[1, 2, 3, 4], new UniqueIterable()],
'more than two unique floats' => [[1.5, 2.5, 3.5], new UniqueIterable()],
'more than two unique stringable values' => [
[
new class implements Stringable {
public function __toString()
{
return 'a';
}
},
new class implements Stringable {
public function __toString()
{
return 'b';
}
},
new class implements Stringable {
public function __toString()
{
return 'c';
}
},
],
new UniqueIterable(),
],
'more than two unique datetime values' => [
[
new DateTime('2024-04-10 14:05:01'),
new DateTime('2024-04-10 14:05:02'),
new DateTime('2024-04-10 14:05:03'),
],
new UniqueIterable(),
],
'using as attribute' => [
new class {
#[UniqueIterable]
Expand Down Expand Up @@ -213,6 +247,43 @@ public function getRules(): array
null,
['data' => ['"Данные" - в списке есть недопустимое значение.']],
],
'two equal strings' => [['a', 'a'], new UniqueIterable(), ['' => [$message]]],
'duplicate loses to a later disallowed item' => [
[1, 1, []],
new UniqueIterable(),
['' => [$incorrectItemValueMessage]],
],
'duplicate loses to a later type mismatch' => [
['data' => [1, 1, 'a']],
['data' => new UniqueIterable()],
['data' => ['All iterable items of data must have the same type.']],
],
'two equal integers' => [[1, 1], new UniqueIterable(), ['' => [$message]]],
'two equal floats' => [[1.5, 1.5], new UniqueIterable(), ['' => [$message]]],
'two equal boolean values' => [[true, true], new UniqueIterable(), ['' => [$message]]],
'two equal stringable values' => [
[
new class implements Stringable {
public function __toString()
{
return 'a';
}
},
new class implements Stringable {
public function __toString()
{
return 'a';
}
},
],
new UniqueIterable(),
['' => [$message]],
],
'two equal datetime values' => [
[new DateTime('2024-04-10 14:05:01'), new DateTime('2024-04-10 14:05:01')],
new UniqueIterable(),
['' => [$message]],
],
'strings' => [['a', 'b', 'a', 'c'], new UniqueIterable(), ['' => [$message]]],
'integers' => [[1, 2, 1, 3], new UniqueIterable(), ['' => [$message]]],
'floats' => [[1.5, 2.5, 1.5, 3.5], new UniqueIterable(), ['' => [$message]]],
Expand Down
Loading