Passed
Branch master (3daac1)
by Vincent
07:53
created

SimpleFieldHtmlRenderer   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 79
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 10
eloc 29
c 1
b 0
f 0
dl 0
loc 79
ccs 21
cts 21
cp 1
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A instance() 0 7 2
A constraintsToAttributes() 0 17 6
A render() 0 12 2
1
<?php
2
3
namespace Bdf\Form\Leaf\View;
4
5
use Bdf\Form\Csrf\CsrfElement;
6
use Bdf\Form\Leaf\IntegerElement;
7
use Bdf\Form\Phone\PhoneElement;
8
use Bdf\Form\View\FieldViewInterface;
9
use Bdf\Form\View\FieldViewRendererInterface;
10
use Bdf\Form\View\HtmlRenderer;
11
use Symfony\Component\Validator\Constraints\GreaterThanOrEqual;
12
use Symfony\Component\Validator\Constraints\Length;
13
use Symfony\Component\Validator\Constraints\LessThanOrEqual;
14
use Symfony\Component\Validator\Constraints\PositiveOrZero;
15
16
/**
17
 * Default render for @see SimpleElementView
18
 */
19
final class SimpleFieldHtmlRenderer implements FieldViewRendererInterface
20
{
21
    /**
22
     * @var SimpleFieldHtmlRenderer|null
23
     */
24
    private static $instance;
25
26
    /**
27
     * Map constraint class name to mapped attributes in form :
28
     * $constraintMapping[$constraintClassName][$constraintAttributeName] = $htmlAttribute
29
     *
30
     * @var string[][]
31
     */
32
    private $constraintMapping = [
33
        Length::class => ['min' => 'minlength', 'max' => 'maxlength'],
34
        LessThanOrEqual::class => ['value' => 'max'],
35
        GreaterThanOrEqual::class => ['value' => 'min'],
36
        PositiveOrZero::class => ['value' => 'min'],
37
    ];
38
39
    /**
40
     * Map element type to html5 input type
41
     *
42
     * @var string[]
43
     */
44
    private $typesMapping = [
45
        IntegerElement::class => 'number',
46
        PhoneElement::class => 'tel',
47
        CsrfElement::class => 'hidden',
48
    ];
49
50
    /**
51
     * {@inheritdoc}
52
     */
53 50
    public function render(FieldViewInterface $view, array $attributes): string
54
    {
55 50
        if (!isset($attributes['type'])) {
56 50
            $attributes['type'] = $this->typesMapping[$view->type()] ?? 'text';
57
        }
58
59 50
        $attributes['name'] = $view->name();
60 50
        $attributes['value'] = $view->value();
61 50
        $attributes['required'] = $view->required();
62 50
        $attributes += $this->constraintsToAttributes($view->constraints());
63
64 50
        return HtmlRenderer::element('input', $attributes);
65
    }
66
67 50
    private function constraintsToAttributes(array $constraints): array
68
    {
69 50
        $attributes = [];
70
71 50
        foreach ($constraints as $type => $values) {
72 23
            if (!isset($this->constraintMapping[$type])) {
73 11
                continue;
74
            }
75
76 19
            foreach ($this->constraintMapping[$type] as $from => $to) {
77 19
                if (isset($values[$from]) && $values[$from] !== '') {
78 19
                    $attributes[$to] = $values[$from];
79
                }
80
            }
81
        }
82
83 50
        return $attributes;
84
    }
85
86
    /**
87
     * Get the renderer instance
88
     *
89
     * @return self
90
     */
91 36
    public static function instance(): self
92
    {
93 36
        if (self::$instance) {
94 35
            return self::$instance;
95
        }
96
97 1
        return self::$instance = new self;
98
    }
99
}
100