|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
declare(strict_types=1); |
|
4
|
|
|
|
|
5
|
|
|
namespace FSi\Bundle\AdminBundle\Admin\ResourceRepository; |
|
6
|
|
|
|
|
7
|
|
|
use FSi\Bundle\AdminBundle\Exception\RuntimeException; |
|
8
|
|
|
use FSi\Bundle\AdminBundle\Form\TypeSolver; |
|
9
|
|
|
use FSi\Bundle\ResourceRepositoryBundle\Model\ResourceValueRepository; |
|
10
|
|
|
use FSi\Bundle\ResourceRepositoryBundle\Repository\MapBuilder; |
|
11
|
|
|
use FSi\Bundle\ResourceRepositoryBundle\Repository\Resource\Type\ResourceInterface; |
|
12
|
|
|
use Symfony\Component\Form\FormFactoryInterface; |
|
13
|
|
|
use Symfony\Component\Form\FormBuilderInterface; |
|
14
|
|
|
use Symfony\Component\Form\FormInterface; |
|
15
|
|
|
use Symfony\Component\PropertyAccess\PropertyAccess; |
|
16
|
|
|
use Symfony\Component\Form\Extension\Core\Type\FormType; |
|
17
|
|
|
use FSi\Bundle\ResourceRepositoryBundle\Form\Type\ResourceType; |
|
18
|
|
|
|
|
19
|
|
|
class ResourceFormBuilder |
|
20
|
|
|
{ |
|
21
|
|
|
/** |
|
22
|
|
|
* @var FormFactoryInterface |
|
23
|
|
|
*/ |
|
24
|
|
|
protected $formFactory; |
|
25
|
|
|
|
|
26
|
|
|
/** |
|
27
|
|
|
* @var MapBuilder |
|
28
|
|
|
*/ |
|
29
|
|
|
protected $mapBuilder; |
|
30
|
|
|
|
|
31
|
|
|
public function __construct(FormFactoryInterface $formFactory, MapBuilder $mapBuilder) |
|
32
|
|
|
{ |
|
33
|
|
|
$this->formFactory = $formFactory; |
|
34
|
|
|
$this->mapBuilder = $mapBuilder; |
|
35
|
|
|
} |
|
36
|
|
|
|
|
37
|
|
|
public function build(Element $element): FormInterface |
|
38
|
|
|
{ |
|
39
|
|
|
$resources = $this->getResourceGroup($element->getKey()); |
|
40
|
|
|
|
|
41
|
|
|
$builder = $this->formFactory->createBuilder( |
|
42
|
|
|
TypeSolver::getFormType(FormType::class, 'form'), |
|
|
|
|
|
|
43
|
|
|
$this->createFormData($element, $element->getResourceValueRepository(), $resources), |
|
44
|
|
|
$element->getResourceFormOptions() |
|
45
|
|
|
); |
|
46
|
|
|
|
|
47
|
|
|
$this->buildForm($element, $builder, $resources); |
|
48
|
|
|
|
|
49
|
|
|
return $builder->getForm(); |
|
50
|
|
|
} |
|
51
|
|
|
|
|
52
|
|
|
private function getResourceGroup(string $key): array |
|
53
|
|
|
{ |
|
54
|
|
|
$map = $this->mapBuilder->getMap(); |
|
55
|
|
|
$propertyPath = $this->createPropertyPath($key); |
|
56
|
|
|
$accessor = PropertyAccess::createPropertyAccessor(); |
|
57
|
|
|
|
|
58
|
|
|
$resources = $accessor->getValue($map, $propertyPath); |
|
59
|
|
|
if (!is_array($resources)) { |
|
60
|
|
|
throw new RuntimeException(sprintf('%s its not a resource group key', $key)); |
|
61
|
|
|
} |
|
62
|
|
|
|
|
63
|
|
|
return $resources; |
|
64
|
|
|
} |
|
65
|
|
|
|
|
66
|
|
|
private function createPropertyPath(string $key): string |
|
67
|
|
|
{ |
|
68
|
|
|
$parts = explode('.', $key); |
|
69
|
|
|
$propertyPath = ''; |
|
70
|
|
|
|
|
71
|
|
|
foreach ($parts as $part) { |
|
72
|
|
|
$propertyPath .= sprintf('[%s]', $part); |
|
73
|
|
|
} |
|
74
|
|
|
|
|
75
|
|
|
return $propertyPath; |
|
76
|
|
|
} |
|
77
|
|
|
|
|
78
|
|
|
/** |
|
79
|
|
|
* @param Element $element |
|
80
|
|
|
* @param ResourceValueRepository $valueRepository |
|
81
|
|
|
* @param ResourceInterface[] $resources |
|
82
|
|
|
* @return array |
|
83
|
|
|
*/ |
|
84
|
|
|
private function createFormData( |
|
85
|
|
|
Element $element, |
|
86
|
|
|
ResourceValueRepository $valueRepository, |
|
87
|
|
|
array $resources |
|
88
|
|
|
): array { |
|
89
|
|
|
$data = []; |
|
90
|
|
|
|
|
91
|
|
|
foreach ($resources as $resourceKey => $resource) { |
|
92
|
|
|
$resourceName = $this->buildResourceName($element, $resourceKey); |
|
93
|
|
|
$data[$this->normalizeKey($resourceName)] = $valueRepository->get($resource->getName()); |
|
94
|
|
|
} |
|
95
|
|
|
|
|
96
|
|
|
return $data; |
|
97
|
|
|
} |
|
98
|
|
|
|
|
99
|
|
|
/** |
|
100
|
|
|
* @param Element $element |
|
101
|
|
|
* @param \Symfony\Component\Form\FormBuilderInterface $builder |
|
102
|
|
|
* @param ResourceInterface[] $resources |
|
103
|
|
|
*/ |
|
104
|
|
|
private function buildForm( |
|
105
|
|
|
Element $element, |
|
106
|
|
|
FormBuilderInterface $builder, |
|
107
|
|
|
array $resources |
|
108
|
|
|
): void { |
|
109
|
|
|
foreach ($resources as $resourceKey => $resource) { |
|
110
|
|
|
$resourceName = $this->buildResourceName($element, $resourceKey); |
|
111
|
|
|
$builder->add( |
|
112
|
|
|
$this->normalizeKey($resourceName), |
|
113
|
|
|
TypeSolver::getFormType(ResourceType::class, 'resource'), |
|
|
|
|
|
|
114
|
|
|
['resource_key' => $resourceName] |
|
115
|
|
|
); |
|
116
|
|
|
} |
|
117
|
|
|
} |
|
118
|
|
|
|
|
119
|
|
|
private function normalizeKey(string $key): string |
|
120
|
|
|
{ |
|
121
|
|
|
return str_replace('.', '_', $key); |
|
122
|
|
|
} |
|
123
|
|
|
|
|
124
|
|
|
private function buildResourceName(Element $element, string $resourceKey): string |
|
125
|
|
|
{ |
|
126
|
|
|
return sprintf('%s.%s', $element->getKey(), $resourceKey); |
|
127
|
|
|
} |
|
128
|
|
|
} |
|
129
|
|
|
|
This check looks at variables that are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.