Skip to content

Commit fcc975d

Browse files
committed
Added validation for ItemTemplateProps
1 parent a7e0eb6 commit fcc975d

File tree

1 file changed

+59
-35
lines changed

1 file changed

+59
-35
lines changed

src/lib/Twig/Components/OverflowList.php

Lines changed: 59 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
namespace Ibexa\DesignSystemTwig\Twig\Components;
1010

1111
use InvalidArgumentException;
12+
use Symfony\Component\OptionsResolver\Options;
1213
use Symfony\Component\OptionsResolver\OptionsResolver;
1314
use Symfony\UX\TwigComponent\Attribute\AsTwigComponent;
1415
use Symfony\UX\TwigComponent\Attribute\ExposeInTemplate;
@@ -17,14 +18,10 @@
1718
#[AsTwigComponent('ibexa:overflow_list')]
1819
final class OverflowList
1920
{
20-
/**
21-
* @var list<array>
22-
*/
21+
/** @var list<array> */
2322
public array $items = [];
2423

25-
/**
26-
* @var array<string>
27-
*/
24+
/** @var list<string> */
2825
public array $itemTemplateProps = [];
2926

3027
/**
@@ -41,31 +38,12 @@ public function validate(array $props): array
4138
->define('items')
4239
->allowedTypes('array')
4340
->default([])
44-
->normalize(static function ($options, $value): array {
45-
if (!is_array($value) || !array_is_list($value)) {
46-
throw new InvalidArgumentException('Property "items" must be a list (sequential array).');
47-
}
48-
49-
foreach ($value as $i => $item) {
50-
if (!is_array($item)) {
51-
throw new InvalidArgumentException(sprintf('items[%d] must be an array, %s given.', $i, get_debug_type($item)));
52-
}
53-
foreach (array_keys($item) as $key) {
54-
if (!is_string($key)) {
55-
throw new InvalidArgumentException(sprintf('items[%d] must use string keys.', $i));
56-
}
57-
if (!preg_match('/^[A-Za-z_][A-Za-z0-9_]*$/', $key)) {
58-
throw new InvalidArgumentException(sprintf('Invalid key "%s" in items[%d].', $key, $i));
59-
}
60-
}
61-
}
62-
63-
return $value;
64-
});
41+
->normalize(self::normalizeItems(...));
6542
$resolver
6643
->define('itemTemplateProps')
6744
->allowedTypes('array')
68-
->default([]);
45+
->default([])
46+
->normalize(self::normalizeItemTemplateProps(...));
6947

7048
return $resolver->resolve($props) + $props;
7149
}
@@ -76,20 +54,66 @@ public function validate(array $props): array
7654
#[ExposeInTemplate('item_template_props')]
7755
public function getItemTemplateProps(): array
7856
{
79-
if (empty($this->items)) {
57+
if (empty($this->itemTemplateProps)) {
8058
return [];
8159
}
8260

83-
$allKeys = [];
84-
foreach ($this->items as $item) {
85-
$allKeys = array_unique([...$allKeys, ...array_keys($item)]);
86-
}
87-
8861
$props = [];
89-
foreach ($allKeys as $name) {
62+
foreach ($this->itemTemplateProps as $name) {
9063
$props[$name] = '{{ ' . $name . ' }}';
9164
}
9265

9366
return $props;
9467
}
68+
69+
/**
70+
* @param Options<array<string, mixed>> $options
71+
* @param array<int, mixed> $value
72+
*
73+
* @return list<array<string, mixed>>
74+
*/
75+
private static function normalizeItems(Options $options, array $value): array
76+
{
77+
if (!array_is_list($value)) {
78+
throw new InvalidArgumentException('Property "items" must be a list (sequential array).');
79+
}
80+
81+
foreach ($value as $i => $item) {
82+
if (!is_array($item)) {
83+
throw new InvalidArgumentException(sprintf('items[%d] must be an array, %s given.', $i, get_debug_type($item)));
84+
}
85+
foreach (array_keys($item) as $key) {
86+
if (!is_string($key)) {
87+
throw new InvalidArgumentException(sprintf('items[%d] must use string keys.', $i));
88+
}
89+
if (!preg_match('/^[A-Za-z_][A-Za-z0-9_]*$/', $key)) {
90+
throw new InvalidArgumentException(sprintf('Invalid key "%s" in items[%d].', $key, $i));
91+
}
92+
}
93+
}
94+
95+
return $value;
96+
}
97+
98+
/**
99+
* @param Options<array<string, mixed>> $options
100+
* @param array<int|string, mixed> $value
101+
*
102+
* @return array<int, string>
103+
*/
104+
private static function normalizeItemTemplateProps(Options $options, array $value): array
105+
{
106+
foreach ($value as $key => $prop) {
107+
if (!is_string($prop)) {
108+
$index = is_int($key) ? (string) $key : sprintf('"%s"', $key);
109+
throw new InvalidArgumentException(sprintf('itemTemplateProps[%s] must be a string, %s given.', $index, get_debug_type($prop)));
110+
}
111+
112+
if (!preg_match('/^[A-Za-z_][A-Za-z0-9_]*$/', $prop)) {
113+
throw new InvalidArgumentException(sprintf('Invalid itemTemplateProps value "%s".', $prop));
114+
}
115+
}
116+
117+
return array_values($value);
118+
}
95119
}

0 commit comments

Comments
 (0)