generated from ibexa/bundle-template
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathAbstractField.php
More file actions
100 lines (82 loc) · 2.94 KB
/
AbstractField.php
File metadata and controls
100 lines (82 loc) · 2.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
<?php
/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);
namespace Ibexa\DesignSystemTwig\Twig\Components;
use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException;
use Symfony\Component\OptionsResolver\Options;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\UX\TwigComponent\Attribute\ExposeInTemplate;
use Symfony\UX\TwigComponent\Attribute\PreMount;
/**
* @phpstan-type AttrMap array<string, scalar>
*/
abstract class AbstractField
{
/** @var non-empty-string */
public string $name;
/** @var AttrMap */
#[ExposeInTemplate(name: 'label_extra', getter: 'getLabelExtra')]
public array $labelExtra = [];
/** @var AttrMap */
#[ExposeInTemplate('helper_text_extra')]
public array $helperTextExtra = [];
public bool $required = false;
/**
* @param array<string, mixed> $props
*
* @return array<string, mixed>
*/
#[PreMount]
public function validate(array $props): array
{
$resolver = new OptionsResolver();
$resolver->setIgnoreUndefined();
$resolver->setDefaults([
'labelExtra' => [],
'helperTextExtra' => [],
'required' => false,
]);
$resolver->setRequired(['name']);
$resolver->setAllowedTypes('name', 'string');
$resolver->setAllowedTypes('labelExtra', 'array');
$resolver->setAllowedTypes('helperTextExtra', 'array');
$resolver->setAllowedTypes('required', 'bool');
$resolver->setNormalizer('labelExtra', static function (Options $options, array $attributes) {
return self::assertForbidden($attributes, ['for', 'required'], 'labelExtra');
});
$this->configurePropsResolver($resolver);
return array_replace_recursive($resolver->resolve($props), $props);
}
/**
* @return AttrMap
*/
public function getLabelExtra(): array
{
return $this->labelExtra + ['required' => $this->required];
}
/**
* @param array<string, scalar> $attributes
* @param list<string> $forbidden
* @param non-empty-string $optionName
*
* @return array<string, scalar>
*
* @throws \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException
*/
protected static function assertForbidden(array $attributes, array $forbidden, string $optionName): array
{
$disallowedKeys = array_intersect(array_keys($attributes), $forbidden);
if ($disallowedKeys) {
throw new InvalidOptionsException(sprintf(
'Option "%s" cannot contain the following keys: %s.',
$optionName,
implode(', ', $disallowedKeys)
));
}
return $attributes;
}
abstract protected function configurePropsResolver(OptionsResolver $resolver): void;
}