1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
declare(strict_types=1); |
4
|
|
|
|
5
|
|
|
namespace LAG\AdminBundle\Field; |
6
|
|
|
|
7
|
|
|
use LAG\AdminBundle\Exception\Exception; |
8
|
|
|
use LAG\AdminBundle\Field\View\FieldView; |
9
|
|
|
use LAG\AdminBundle\Field\View\View; |
10
|
|
|
use Symfony\Component\OptionsResolver\Options; |
11
|
|
|
use Symfony\Component\OptionsResolver\OptionsResolver; |
12
|
|
|
|
13
|
|
|
use function Symfony\Component\String\u; |
14
|
|
|
|
15
|
|
|
abstract class AbstractField implements Field |
16
|
|
|
{ |
17
|
|
|
private string $name; |
18
|
|
|
private string $type; |
19
|
|
|
private array $options = []; |
20
|
|
|
private bool $frozen = false; |
21
|
|
|
|
22
|
11 |
|
public function __construct(string $name, string $type) |
23
|
|
|
{ |
24
|
11 |
|
if (class_exists($type)) { |
25
|
|
|
$type = u($type)->afterLast('\\')->lower()->toString(); |
26
|
|
|
} |
27
|
11 |
|
$this->name = $name; |
28
|
11 |
|
$this->type = $type; |
29
|
11 |
|
} |
30
|
|
|
|
31
|
6 |
|
public function configureDefaultOptions(OptionsResolver $resolver): void |
32
|
|
|
{ |
33
|
|
|
$resolver |
34
|
6 |
|
->setDefaults([ |
35
|
6 |
|
'attr' => [], |
36
|
|
|
'header_attr' => [], |
37
|
|
|
'label' => null, |
38
|
|
|
'mapped' => false, |
39
|
6 |
|
'property_path' => $this->getName(), |
40
|
6 |
|
'template' => '@LAGAdmin/fields/auto.html.twig', |
41
|
|
|
'translation' => false, // Most of the fields are values from database and should not be translated |
42
|
6 |
|
'translation_domain' => 'admin', |
43
|
|
|
'sortable' => true, |
44
|
|
|
]) |
45
|
6 |
|
->setAllowedTypes('attr', ['array', 'null']) |
46
|
6 |
|
->setAllowedTypes('header_attr', ['array', 'null']) |
47
|
6 |
|
->setAllowedTypes('label', ['string', 'null', 'boolean']) |
48
|
6 |
|
->setAllowedTypes('mapped', ['boolean']) |
49
|
6 |
|
->setAllowedTypes('property_path', ['string', 'null']) |
50
|
6 |
|
->setAllowedTypes('template', ['string']) |
51
|
6 |
|
->setAllowedTypes('translation', ['boolean']) |
52
|
6 |
|
->setAllowedTypes('translation_domain', ['string', 'null']) |
53
|
6 |
|
->setAllowedTypes('sortable', ['boolean']) |
54
|
6 |
|
->addNormalizer('attr', function (Options $options, $value) { |
55
|
6 |
|
if ($value === null) { |
56
|
|
|
$value = []; |
57
|
|
|
} |
58
|
|
|
|
59
|
6 |
|
if (!\array_key_exists('class', $value)) { |
60
|
6 |
|
$value['class'] = ''; |
61
|
|
|
} |
62
|
6 |
|
$value['class'] .= ' admin-field admin-field-'.$this->getType(); |
63
|
6 |
|
$value['class'] = trim($value['class']); |
64
|
|
|
|
65
|
6 |
|
return $value; |
66
|
6 |
|
}) |
67
|
6 |
|
->addNormalizer('header_attr', function (Options $options, $value) { |
68
|
6 |
|
if ($value === null) { |
69
|
|
|
$value = []; |
70
|
|
|
} |
71
|
|
|
|
72
|
6 |
|
if (!\array_key_exists('class', $value)) { |
73
|
6 |
|
$value['class'] = ''; |
74
|
|
|
} |
75
|
6 |
|
$value['class'] .= ' admin-header admin-header-'.$this->getType(); |
76
|
6 |
|
$value['class'] = trim($value['class']); |
77
|
|
|
|
78
|
6 |
|
return $value; |
79
|
6 |
|
}) |
80
|
6 |
|
->setNormalizer('mapped', function (Options $options, $mapped) { |
81
|
6 |
|
if (u($this->getName())->startsWith('_')) { |
82
|
|
|
return true; |
83
|
|
|
} |
84
|
|
|
|
85
|
6 |
|
return $mapped; |
86
|
6 |
|
}) |
87
|
6 |
|
->setNormalizer('property_path', function (Options $options, $propertyPath) { |
88
|
6 |
|
if (u($this->getName())->startsWith('_')) { |
89
|
|
|
return null; |
90
|
|
|
} |
91
|
|
|
|
92
|
6 |
|
return $propertyPath; |
93
|
6 |
|
}) |
94
|
|
|
; |
95
|
6 |
|
} |
96
|
|
|
|
97
|
1 |
|
public function configureOptions(OptionsResolver $resolver): void |
98
|
|
|
{ |
99
|
1 |
|
} |
100
|
|
|
|
101
|
10 |
|
public function setOptions(array $options): void |
102
|
|
|
{ |
103
|
10 |
|
if ($this->frozen) { |
104
|
1 |
|
throw new Exception('The options for the field "'.$this->name.'" have already been configured'); |
105
|
|
|
} |
106
|
10 |
|
$this->options = $options; |
107
|
10 |
|
$this->frozen = true; |
108
|
10 |
|
} |
109
|
|
|
|
110
|
2 |
|
public function createView(): View |
111
|
|
|
{ |
112
|
2 |
|
return new FieldView( |
113
|
2 |
|
$this->name, |
114
|
2 |
|
$this->getOption('template'), |
115
|
2 |
|
$this->getOptions(), |
116
|
2 |
|
$this->getDataTransformer(), |
|
|
|
|
117
|
|
|
); |
118
|
|
|
} |
119
|
|
|
|
120
|
6 |
|
public function getParent(): ?string |
121
|
|
|
{ |
122
|
6 |
|
return null; |
123
|
|
|
} |
124
|
|
|
|
125
|
2 |
|
public function getDataTransformer(): ?\Closure |
126
|
|
|
{ |
127
|
2 |
|
return null; |
128
|
|
|
} |
129
|
|
|
|
130
|
6 |
|
public function getName(): string |
131
|
|
|
{ |
132
|
6 |
|
return $this->name; |
133
|
|
|
} |
134
|
|
|
|
135
|
8 |
|
public function getLabel(): string |
136
|
|
|
{ |
137
|
8 |
|
return $this->options['label']; |
138
|
|
|
} |
139
|
|
|
|
140
|
5 |
|
public function getOptions(): array |
141
|
|
|
{ |
142
|
5 |
|
return $this->options; |
143
|
1 |
|
} |
144
|
|
|
|
145
|
|
|
public function getOption(string $name): mixed |
146
|
4 |
|
{ |
147
|
|
|
if (!\array_key_exists($name, $this->options)) { |
148
|
|
|
throw new Exception('Invalid option "'.$name.'" for field "'.$this->name.'"'); |
149
|
6 |
|
} |
150
|
|
|
|
151
|
6 |
|
return $this->options[$name]; |
152
|
|
|
} |
153
|
|
|
|
154
|
|
|
public function getType(): string |
155
|
|
|
{ |
156
|
|
|
return $this->type; |
157
|
|
|
} |
158
|
|
|
|
159
|
|
|
// TODO remove |
160
|
|
|
public function isSortable(): bool |
161
|
|
|
{ |
162
|
|
|
return true; |
163
|
|
|
} |
164
|
|
|
} |
165
|
|
|
|
This check looks for function or method calls that always return null and whose return value is used.
The method
getObject()
can return nothing but null, so it makes no sense to use the return value.The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.