ResourceFormBuilder   A
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 108
Duplicated Lines 0 %

Importance

Changes 6
Bugs 1 Features 0
Metric Value
wmc 12
eloc 37
c 6
b 1
f 0
dl 0
loc 108
rs 10

8 Methods

Rating   Name   Duplication   Size   Complexity  
A createPropertyPath() 0 10 2
A __construct() 0 4 1
A getResourceGroup() 0 12 2
A buildForm() 0 11 2
A buildResourceName() 0 3 1
A normalizeKey() 0 3 1
A build() 0 13 1
A createFormData() 0 13 2
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\ResourceRepositoryBundle\Form\Type\ResourceType;
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\Extension\Core\Type\FormType;
13
use Symfony\Component\Form\FormBuilderInterface;
14
use Symfony\Component\Form\FormFactoryInterface;
15
use Symfony\Component\Form\FormInterface;
16
use Symfony\Component\PropertyAccess\PropertyAccess;
17
18
class ResourceFormBuilder
19
{
20
    /**
21
     * @var FormFactoryInterface
22
     */
23
    protected $formFactory;
24
25
    /**
26
     * @var MapBuilder
27
     */
28
    protected $mapBuilder;
29
30
    public function __construct(FormFactoryInterface $formFactory, MapBuilder $mapBuilder)
31
    {
32
        $this->formFactory = $formFactory;
33
        $this->mapBuilder = $mapBuilder;
34
    }
35
36
    public function build(Element $element): FormInterface
37
    {
38
        $resources = $this->getResourceGroup($element->getKey());
39
40
        $builder = $this->formFactory->createBuilder(
41
            FormType::class,
42
            $this->createFormData($element, $element->getResourceValueRepository(), $resources),
43
            $element->getResourceFormOptions()
44
        );
45
46
        $this->buildForm($element, $builder, $resources);
47
48
        return $builder->getForm();
49
    }
50
51
    private function getResourceGroup(string $key): array
52
    {
53
        $map = $this->mapBuilder->getMap();
54
        $propertyPath = $this->createPropertyPath($key);
55
        $accessor = PropertyAccess::createPropertyAccessor();
56
57
        $resources = $accessor->getValue($map, $propertyPath);
58
        if (!is_array($resources)) {
59
            throw new RuntimeException(sprintf('%s its not a resource group key', $key));
60
        }
61
62
        return $resources;
63
    }
64
65
    private function createPropertyPath(string $key): string
66
    {
67
        $parts = explode('.', $key);
68
        $propertyPath = '';
69
70
        foreach ($parts as $part) {
71
            $propertyPath .= sprintf('[%s]', $part);
72
        }
73
74
        return $propertyPath;
75
    }
76
77
    /**
78
     * @param Element $element
79
     * @param ResourceValueRepository $valueRepository
80
     * @param ResourceInterface[] $resources
81
     * @return array
82
     */
83
    private function createFormData(
84
        Element $element,
85
        ResourceValueRepository $valueRepository,
86
        array $resources
87
    ): array {
88
        $data = [];
89
90
        foreach ($resources as $resourceKey => $resource) {
91
            $resourceName = $this->buildResourceName($element, $resourceKey);
92
            $data[$this->normalizeKey($resourceName)] = $valueRepository->get($resource->getName());
93
        }
94
95
        return $data;
96
    }
97
98
    /**
99
     * @param Element $element
100
     * @param FormBuilderInterface $builder
101
     * @param ResourceInterface[] $resources
102
     */
103
    private function buildForm(
104
        Element $element,
105
        FormBuilderInterface $builder,
106
        array $resources
107
    ): void {
108
        foreach ($resources as $resourceKey => $resource) {
109
            $resourceName = $this->buildResourceName($element, $resourceKey);
110
            $builder->add(
111
                $this->normalizeKey($resourceName),
112
                ResourceType::class,
113
                ['resource_key' => $resourceName]
114
            );
115
        }
116
    }
117
118
    private function normalizeKey(string $key): string
119
    {
120
        return str_replace('.', '_', $key);
121
    }
122
123
    private function buildResourceName(Element $element, string $resourceKey): string
124
    {
125
        return sprintf('%s.%s', $element->getKey(), $resourceKey);
126
    }
127
}
128