SelectField::renderInput()   B
last analyzed

Complexity

Conditions 5
Paths 12

Size

Total Lines 39
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 23
CRAP Score 5

Importance

Changes 0
Metric Value
dl 0
loc 39
ccs 23
cts 23
cp 1
rs 8.439
c 0
b 0
f 0
cc 5
eloc 23
nc 12
nop 3
crap 5
1
<?php
2
3
namespace mindplay\kissform\Fields;
4
5
use mindplay\kissform\Field;
6
use mindplay\kissform\InputModel;
7
use mindplay\kissform\InputRenderer;
8
use mindplay\kissform\Validators\CheckSelected;
9
10
/**
11
 * This class provides information about a <select> input and available options.
12
 */
13
class SelectField extends Field
14
{
15
    /**
16
     * @var string[] map where option values map to option labels
17
     */
18
    protected $options;
19
20
    /**
21
     * @var string label of disabled first option (often directions or a description)
22
     */
23
    public $disabled;
24
25
    /**
26
     * @param string   $name    field name
27
     * @param string[] $options map where option values map to option labels
28
     */
29 5
    public function __construct($name, array $options)
30
    {
31 5
        parent::__construct($name);
32
33 5
        $this->options = $options;
34 5
    }
35
36
    /**
37
     * @inheritdoc
38
     */
39 2
    public function createValidators()
40
    {
41 2
        return [new CheckSelected(array_keys($this->options))];
42
    }
43
44
    /**
45
     * {@inheritdoc}
46
     */
47 2
    public function renderInput(InputRenderer $renderer, InputModel $model, array $attr)
48
    {
49 2
        $selected = $model->getInput($this);
50
51 2
        $values = array_map('strval', array_keys($this->options));
52
53 2
        if (! in_array($selected, $values, true)) {
54 2
            $selected = null; // selected value isn't present in the list of options
55
        }
56
57 2
        $html = '';
58
59 2
        if ($this->disabled !== null) {
60 2
            $html .= '<option' . $renderer->attrs(['disabled' => true, 'selected' => ($selected == '')]) . '>'
61 2
                . $renderer->escape($this->disabled) . '</option>';
62
        }
63
64 2
        foreach ($this->options as $value => $label) {
65 2
            $equal = is_numeric($selected)
66 2
                ? $value == $selected // loose comparison works well for NULLs and numbers
67 2
                : $value === $selected; // strict comparison for everything else
68
69 2
            $html .= '<option' . $renderer->attrs(['value' => $value, 'selected' => $equal]) . '>'
70 2
                . $renderer->escape($label) . '</option>';
71
        }
72
73 2
        return $renderer->tag(
74 2
            'select',
75 2
            $renderer->mergeAttrs(
76
                [
77 2
                    'name' => $renderer->getName($this),
78 2
                    'id' => $renderer->getId($this),
79 2
                    'class' => $renderer->input_class,
80
                ],
81 2
                $attr
82
            ),
83 2
            $html
84
        );
85
    }
86
}
87