Passed
Push — develop ( 8f9d97...72aae6 )
by Freddie
02:16
created

AbstractBuilder::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
c 1
b 0
f 0
nc 1
nop 3
dl 0
loc 5
rs 10
1
<?php
2
3
namespace FlexPHP\Inputs\Builder;
4
5
use Exception;
6
use Symfony\Component\Form\Extension\Core\Type\FormType;
7
use Symfony\Component\Form\FormBuilderInterface;
8
use Symfony\Component\Form\Forms;
9
use Symfony\Component\Form\FormInterface;
10
11
abstract class AbstractBuilder implements BuilderInterface
12
{
13
    private $name;
14
    private $properties;
15
    private $options;
16
    protected $build = null;
17
18
    public function __construct(string $name, array $properties, array $options)
19
    {
20
        $this->name = $name;
21
        $this->properties = $properties;
22
        $this->options = $options;
23
    }
24
25
    abstract protected function getType(): string;
26
27
    public function getName(): string
28
    {
29
        return str_replace(' ', '_', $this->name);
30
    }
31
32
    public function getProperties(): array
33
    {
34
        return $this->properties;
35
    }
36
37
    public function getOptions(): array
38
    {
39
        return $this->options;
40
    }
41
42
    public function build(): FormInterface
43
    {
44
        return $this->factory()
45
            ->add(
46
                $this->getName(),
47
                $this->getType(),
48
                array_merge_recursive(
49
                    $this->parseProperties($this->getProperties()),
50
                    $this->getDefaultOptions($this->getOptions())
51
                )
52
            )
53
            ->getForm();
54
    }
55
56
    public function render(): string
57
    {
58
        return $this->twig()->createTemplate(\sprintf('{{ form_row(form.%1$s) }}', $this->getName()))->render([
59
            'form' => $this->build()->createView(),
60
        ]);
61
    }
62
63
    protected function factory(): FormBuilderInterface
64
    {
65
        return Forms::createFormFactory()->createBuilder(FormType::class, null);
66
    }
67
68
    protected function getDefaultOptions(array $options = []): array
69
    {
70
        return [
71
            'mapped' => false,
72
            'required' => false,
73
            'trim' => false,
74
        ] + $options;
75
    }
76
77
    private function parseProperties(array $properties): array
78
    {
79
        $options = [];
80
81
        $properties = array_filter($properties, function ($var) {
82
            return !is_null($var);
83
        });
84
85
        foreach ($properties as $property => $value) {
86
            switch ($property) {
87
                case 'Label':
88
                    $options['label'] = $value;
89
                    break;
90
                case 'Default':
91
                    $options['data'] = $value;
92
                    break;
93
                case 'Constraints':
94
                    $attributes = \json_decode($value, true);
95
96
                    if ((\json_last_error() !== JSON_ERROR_NONE)) {
97
                        $attributes = [$value];
98
                    }
99
100
                    foreach ($attributes as $attribute => $_value) {
101
                        if ($attribute == 'required' || $_value == 'required') {
102
                            $options['required'] = true;
103
                        } else {
104
                            $options['attr'][$attribute] = $_value;
105
                        }
106
                    }
107
                    break;
108
                case 'InputHelp':
109
                    $options['help'] = $value;
110
                    break;
111
            }
112
        }
113
114
        return $options;
115
    }
116
117
    private function twig()
118
    {
119
        $appVariableReflection = new \ReflectionClass('\Symfony\Bridge\Twig\AppVariable');
120
        $vendorTwigBridgeDirectory = dirname((string)$appVariableReflection->getFileName());
121
122
        $loader = new \Twig\Loader\FilesystemLoader([
123
            $vendorTwigBridgeDirectory . '/Resources/views/Form',
124
        ]);
125
126
        $twig = new \Twig\Environment($loader);
127
        $twig->addExtension(new \Symfony\Bridge\Twig\Extension\FormExtension());
128
        $twig->addExtension(new \Symfony\Bridge\Twig\Extension\TranslationExtension(
129
            new \Symfony\Component\Translation\Translator('en')
130
        ));
131
132
        $formEngine = new \Symfony\Bridge\Twig\Form\TwigRendererEngine(['bootstrap_4_layout.html.twig'], $twig);
133
        $twig->addRuntimeLoader(new \Twig\RuntimeLoader\FactoryRuntimeLoader([
134
            \Symfony\Component\Form\FormRenderer::class => function () use ($formEngine) {
135
                return new \Symfony\Component\Form\FormRenderer($formEngine);
136
            },
137
        ]));
138
139
        return $twig;
140
    }
141
}
142