Completed
Push — master ( e3df42...7db57b )
by Nikolas
03:09
created

ActionField::makeFormGroup()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 25
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 25
rs 8.5806
cc 4
eloc 14
nc 4
nop 2
1
<?php
2
namespace rtens\domin\delivery\web\fields;
3
4
use rtens\domin\Action;
5
use rtens\domin\ActionRegistry;
6
use rtens\domin\delivery\FieldRegistry;
7
use rtens\domin\delivery\web\Element;
8
use rtens\domin\delivery\web\WebField;
9
use rtens\domin\Parameter;
10
use watoki\reflect\type\ClassType;
11
12
class ActionField implements WebField {
13
14
    /** @var FieldRegistry */
15
    private $fields;
16
17
    /** @var ActionRegistry */
18
    private $actions;
19
20
    public function __construct(FieldRegistry $fields, ActionRegistry $actions) {
21
        $this->fields = $fields;
22
        $this->actions = $actions;
23
    }
24
25
    /**
26
     * @param Parameter $parameter
27
     * @return bool
28
     */
29
    public function handles(Parameter $parameter) {
30
        $type = $parameter->getType();
31
        return $type instanceof ClassType && is_subclass_of($type->getClass(), Action::class);
0 ignored issues
show
Bug introduced by
Due to PHP Bug #53727, is_subclass_of might return inconsistent results on some PHP versions if \rtens\domin\Action::class can be an interface. If so, you could instead use ReflectionClass::implementsInterface.
Loading history...
32
    }
33
34
    /**
35
     * @param Parameter $parameter
36
     * @param mixed[] $values
37
     * @return string
38
     * @throws \Exception
39
     */
40
    public function render(Parameter $parameter, $values) {
41
        $action = $this->actions->getAction($parameter->getName());
42
        $values = $action->fill($values);
43
44
        $body = [];
45
46
        if ($action->description()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $action->description() of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
47
            $body[] = new Element('div', ['class' => 'well'], [
48
                $action->description()
49
            ]);
50
        }
51
52
        foreach ($action->parameters() as $parameter) {
53
            $value = null;
54
            if (isset($values[$parameter->getName()])) {
55
                $value = $values[$parameter->getName()];
56
            }
57
58
            $body[] = new Element('div', ['class' => 'form-group'],
59
                $this->makeFormGroup($parameter, $value));
60
        }
61
62
        return $body ? (string)new Element('div', [], $body) : '';
63
    }
64
65
    private function makeFormGroup(Parameter $parameter, $value) {
66
        $formGroup = [
67
            new Element('label', [], [
68
                $this->makeLabel($parameter) . ($parameter->isRequired() ? '*' : '')
69
            ])
70
        ];
71
72
        if ($parameter->getDescription()) {
73
            $formGroup[] = new Element('a', ['class' => 'description'], [
74
                new Element('span', ['class' => 'glyphicon glyphicon-question-sign'])
75
            ]);
76
            $formGroup[] = new Element('div', ['class' => 'description-content sr-only'], [
77
                $parameter->getDescription()
78
            ]);
79
        }
80
81
        $field = $this->fields->getField($parameter);
82
83
        if (!($field instanceof WebField)) {
84
            throw new \Exception("[$parameter] is not a WebField");
85
        }
86
87
        $formGroup[] = $field->render($parameter, $value);
88
        return $formGroup;
89
    }
90
91
    /**
92
     * @param $parameter
93
     * @return mixed
94
     */
95
    protected function makeLabel(Parameter $parameter) {
96
        return ucfirst(preg_replace('/(.)([A-Z0-9])/', '$1 $2', $parameter->getName()));
97
    }
98
99
    /**
100
     * @param Parameter $parameter
101
     * @param string $serialized
102
     * @return mixed
103
     */
104
    public function inflate(Parameter $parameter, $serialized) {
105
        return null;
106
    }
107
108
    /**
109
     * @param Parameter $parameter
110
     * @return array|\rtens\domin\delivery\web\Element[]
111
     */
112
    public function headElements(Parameter $parameter) {
113
        $action = $this->actions->getAction($parameter->getName());
114
115
        $headElements = [
116
            self::descriptionCode()
117
        ];
118
119
        foreach ($action->parameters() as $parameter) {
120
            $field = $this->fields->getField($parameter);
121
            if ($field instanceof WebField) {
122
                $headElements = array_merge($headElements, $field->headElements($parameter));
123
            }
124
        }
125
        return $headElements;
126
    }
127
128
    private static function descriptionCode() {
129
        return new Element('script', [], ["
130
                $(function () {
131
                    $('.description').popover({
132
                        trigger: 'hover',
133
                        delay: {show: 100, hide: 1000},
134
                        html: true,
135
                        placement: 'auto top',
136
                        content: function () {
137
                            return $(this).siblings('.description-content').html();
138
                        }
139
                    });
140
                });"
141
        ]);
142
    }
143
}