Passed
Push — v2 ( a6d212...5d15db )
by Daniel
04:43
created

Form::initFormView()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
eloc 7
nc 3
nop 2
dl 0
loc 9
ccs 0
cts 8
cp 0
crap 12
rs 10
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of the Silverback API Component Bundle Project
5
 *
6
 * (c) Daniel West <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Silverback\ApiComponentBundle\Dto;
15
16
use Doctrine\Common\Collections\ArrayCollection;
17
use Doctrine\Common\Collections\Collection;
18
use Symfony\Component\Form\FormInterface;
19
use Symfony\Component\Form\FormView as SymfonyFormView;
20
21
/**
22
 * @author Daniel West <[email protected]>
23
 */
24
final class Form
25
{
26
    private const ARRAY_OUTPUT_VARS = [
27
        'choices',
28
        'preferred_choices',
29
        'errors',
30
        'is_selected',
31
    ];
32
33
    private const OUTPUT_VARS = [
34
        'action',
35
        'api_request',
36
        'attr',
37
        'block_prefixes',
38
        'checked',
39
        'disabled',
40
        'expanded',
41
        'full_name',
42
        'help',
43
        'id',
44
        'is_selected',
45
        'label',
46
        'label_attr',
47
        'multiple',
48
        'name',
49
        'placeholder',
50
        'placeholder_in_choices',
51
        'post_app_proxy',
52
        'realtime_validate',
53
        'required',
54
        'submitted',
55
        'unique_block_prefix',
56
        'valid',
57
        'value',
58
    ];
59
60
    private array $vars;
61
    private Collection $children;
62
    private bool $rendered;
63
    private bool $methodRendered;
64
    private FormInterface $rootForm;
65
66
    public function __construct(FormInterface $rootForm, SymfonyFormView $formView = null, bool $children = true)
67
    {
68
        $this->setRootForm($rootForm, $formView, $children);
69
    }
70
71
    public function getVars(): array
72
    {
73
        return $this->vars;
74
    }
75
76
    public function getChildren(): Collection
77
    {
78
        return $this->children;
79
    }
80
81
    public function isRendered(): bool
82
    {
83
        return $this->rendered;
84
    }
85
86
    public function isMethodRendered(): bool
87
    {
88
        return $this->methodRendered;
89
    }
90
91
    public function getRootForm(): FormInterface
92
    {
93
        return $this->rootForm;
94
    }
95
96
    public function setRootForm(FormInterface $rootForm, SymfonyFormView $formView = null, bool $children = true): self
97
    {
98
        if (!$this->rootForm->isRoot()) {
99
            throw new \InvalidArgumentException('The $rootForm cannot be set. The supplied Form is not the root.');
100
        }
101
        $this->rootForm = $rootForm;
102
        if (!$formView) {
103
            $formView = $rootForm->createView();
104
        }
105
        $this->initFormView($formView, $children);
106
107
        return $this;
108
    }
109
110
    private function processViewVars(SymfonyFormView $formView): void
111
    {
112
        $outputVars = array_merge(self::ARRAY_OUTPUT_VARS, self::OUTPUT_VARS);
113
        foreach ($outputVars as $var) {
114
            if (isset($formView->vars[$var])) {
115
                $this->vars[$var] = $formView->vars[$var];
116
                $this->convertVarToArray($var);
117
            }
118
        }
119
    }
120
121
    private function convertVarToArray($var): void
122
    {
123
        if (\in_array($var, self::ARRAY_OUTPUT_VARS, true)) {
124
            /** @var iterable $choices */
125
            $choices = $this->vars[$var];
126
            $this->vars[$var] = [];
127
            foreach ($choices as $choice) {
128
                if (method_exists($choice, 'getMessage')) {
129
                    $this->vars[$var][] = $choice->getMessage();
130
                } else {
131
                    $this->vars[$var][] = (array) $choice;
132
                }
133
            }
134
        }
135
    }
136
137
    private function addChild(SymfonyFormView $formViews): void
138
    {
139
        $formView = new self($this->rootForm, $formViews);
140
        $this->children->add($formView);
141
    }
142
143
    private function initFormView(SymfonyFormView $formView, bool $children = true): void
144
    {
145
        $this->rendered = $formView->isRendered();
146
        $this->methodRendered = $formView->isMethodRendered();
147
        $this->processViewVars($formView);
148
        if ($children) {
149
            $this->children = new ArrayCollection();
150
            foreach ($formView->getIterator() as $view) {
151
                $this->addChild($view);
152
            }
153
        }
154
    }
155
}
156