NullableField::headElements()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
c 0
b 0
f 0
rs 9.6666
cc 1
eloc 5
nc 1
nop 1
1
<?php
2
namespace rtens\domin\delivery\web\fields;
3
4
use rtens\domin\delivery\FieldRegistry;
5
use rtens\domin\Parameter;
6
use rtens\domin\delivery\web\Element;
7
use rtens\domin\delivery\web\HeadElements;
8
use rtens\domin\delivery\web\WebField;
9
use watoki\reflect\type\NullableType;
10
11
class NullableField implements WebField {
12
13
    const NULL_VALUE = '____IS_NULL____';
14
15
    /** @var FieldRegistry */
16
    private $fields;
17
18
    /**
19
     * @param FieldRegistry $fields
20
     */
21
    public function __construct(FieldRegistry $fields) {
22
        $this->fields = $fields;
23
    }
24
25
    /**
26
     * @param Parameter $parameter
27
     * @return bool
28
     */
29
    public function handles(Parameter $parameter) {
30
        return $parameter->getType() instanceof NullableType;
31
    }
32
33
    /**
34
     * @param Parameter $parameter
35
     * @param mixed $serialized
36
     * @return null|mixed
37
     */
38
    public function inflate(Parameter $parameter, $serialized) {
39
        if (is_null($serialized) || $serialized == self::NULL_VALUE) {
40
            return null;
41
        }
42
        $innerParameter = $this->getInnerParameter($parameter);
43
        return $this->fields->getField($innerParameter)
44
            ->inflate($innerParameter, $serialized);
45
    }
46
47
    /**
48
     * @param Parameter $parameter
49
     * @param mixed $value
50
     * @return string
51
     */
52
    public function render(Parameter $parameter, $value) {
53
        $id = str_replace(['[', ']'], '-', $parameter->getName());
54
55
        return implode("\n", [
56
            new Element('input', [
57
                'type' => 'hidden',
58
                'name' => $parameter->getName(),
59
                'value' => self::NULL_VALUE
60
            ]),
61
            new Element('input', array_merge([
62
                'type' => 'checkbox',
63
                'onchange' => "var control = $('#$id-control'); $(this).is(':checked') ? control.show().insertAfter($(this)) : control.hide().appendTo('body');"
64
            ], is_null($value) ? [] : [
65
                'checked' => 'checked'
66
            ])),
67
            new Element('div', array_merge([
68
                'id' => "$id-control"
69
            ], is_null($value) ? [
70
                'class' => 'null-nullable'
71
            ] : []), [
72
                $this->getInnerField($this->getInnerParameter($parameter))
73
                    ->render($this->getInnerParameter($parameter), $value)
74
            ])
75
        ]);
76
    }
77
78
    /**
79
     * @param Parameter $parameter
80
     * @return array|Element[]
81
     */
82
    public function headElements(Parameter $parameter) {
83
        $innerParameter = $this->getInnerParameter($parameter);
84
        return array_merge($this->getInnerField($innerParameter)->headElements($innerParameter), [
85
            HeadElements::jquery(),
86
            new Element('script', [], ["$(function () {
87
                    $('.null-nullable').hide().appendTo('body');
88
                });"])
89
        ]);
90
    }
91
92 View Code Duplication
    private function getInnerParameter(Parameter $parameter) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
93
        $type = $parameter->getType();
94
        if (!($type instanceof NullableType)) {
95
            throw new \InvalidArgumentException("[$type] is not a NullableType");
96
        }
97
98
        return new Parameter($parameter->getName(), $type->getType());
99
    }
100
101
    /**
102
     * @param Parameter $innerParameter
103
     * @return WebField
104
     */
105
    private function getInnerField(Parameter $innerParameter) {
106
        return $this->fields->getField($innerParameter);
107
    }
108
}