Skip to content
Closed
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 #816: Fix `UniqueIterable` comparing the whole iterable instead of its items (@CorvusSharp)

## 2.6.0 June 02, 2026

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

$previousItem = $item;

if (!empty($stack) && count($stack) !== count(array_unique($stack, flags: SORT_REGULAR))) {
if ($item instanceof DateTimeInterface) {
$stack[] = $item->getTimestamp();
} elseif ($item instanceof Stringable) {
$stack[] = (string) $item;
} else {
$stack[] = $item;
}

if (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();
} else {
$stack[] = $value;
}
}

return new Result();
Expand Down
61 changes: 61 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,33 @@ public function getRules(): array
null,
['data' => ['"Данные" - в списке есть недопустимое значение.']],
],
'two equal strings' => [['a', 'a'], new UniqueIterable(), ['' => [$message]]],
'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