CheckboxRender::renderBlock()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 26
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 4

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 12
c 2
b 0
f 0
dl 0
loc 26
ccs 13
cts 13
cp 1
rs 9.8666
cc 4
nc 4
nop 2
crap 4
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Del\Form\Renderer\Field;
6
7
use Del\Form\Field\FieldInterface;
8
use Del\Form\Field\CheckBox;
9
use DOMDocumentFragment;
10
use DOMElement;
11
use DOMNode;
12
use InvalidArgumentException;
13
use LogicException;
14
15
class CheckboxRender extends AbstractFieldRender
16
{
17
    private DOMDocumentFragment $fragment;
18
    private bool $isMultiCheckbox = false;
19
    private int $counter = 0;
20
21 9
    public function renderBlock(FieldInterface $field, DOMElement $element): DOMNode
22
    {
23
        // We don't really want a containing div, so we'll ignore $element
24
        // and instead create a DOMDocumentFragment
25 9
        $this->fragment = $this->getDom()->createDocumentFragment();
26
27
        // Make sure the FieldInterface is actually a Radio
28 9
        if (!$field instanceof CheckBox) {
29 1
            throw new InvalidArgumentException('Must be a Del\Form\Field\Checkbox');
30
        }
31
32 8
        $inline = $field->isRenderInline();
33
34 8
        $options = $field->getOptions();
35 8
        if (empty($options)) {
36 1
            throw new LogicException('You must set at least one option.');
37
        }
38
39
        // Loop through each checkbox element (the options)
40 7
        $this->isMultiCheckbox = count($options) > 1;
41 7
        foreach ($options as $value => $label) {
42 7
            $radio = $this->processOption($field, $value, $label, $inline);
43 7
            $this->fragment->appendChild($radio);
44
        }
45
46 7
        return $this->fragment;
47
    }
48
49 7
    private function processOption(CheckBox $field, $value, $labelText, $inline): DOMElement
50
    {
51 7
        return $this->renderCheckbox($field, $value, $labelText, $inline);
52
    }
53
54 7
    private function renderCheckbox(CheckBox $field, $value, $labelText, $inline): DOMElement
55
    {
56 7
        $div = $this->getDom()->createElement('div');
57 7
        $class = $inline ? 'form-check-inline' : 'form-check';
58 7
        $div->setAttribute('class', $class);
59 7
        $checkbox = $this->renderCheckboxInline($field, $value);
60 7
        $div->appendChild($checkbox);
61 7
        $div->appendChild($this->getLabel($field, $labelText));
62
63 7
        return $div;
64
    }
65
66 7
    private function getLabel(FieldInterface $field, string $labelText): DOMElement
67
    {
68 7
        $this->counter ++;
69 7
        $label = $this->getDom()->createElement('label');
70 7
        $label->setAttribute('for', $field->getId() . $this->counter);
71 7
        $label->setAttribute('class', 'form-check-label');
72 7
        $text = $this->createText($labelText);
73 7
        $label->appendChild($text);
74
75 7
        return $label;
76
    }
77
78 7
    private function renderCheckboxInline(FieldInterface $field, $value): DOMElement
79
    {
80 7
        $checkbox = $this->getDom()->createElement('input');
81 7
        $checkbox->setAttribute('class', 'form-check-input');
82 7
        $checkbox->setAttribute('type', 'checkbox');
83 7
        $fieldName = $this->isMultiCheckbox ? $field->getName() . '[]' : $field->getName();
84 7
        $checkbox->setAttribute('name', $fieldName);
85 7
        $checkbox->setAttribute('value', (string) $value);
86 7
        $fieldValue = $field->getValue();
87
88 7
        if ($fieldValue === true || $fieldValue == $value || (is_array($fieldValue) && in_array($value, $fieldValue, true))) {
89 3
            $checkbox->setAttribute('checked', 'checked');
90
        }
91
92 7
        return $checkbox;
93
    }
94
}
95