Passed
Push — master ( acf3f9...98cfe3 )
by Derek Stephen
03:04
created

CheckboxRender   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 111
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 14
eloc 41
c 2
b 0
f 0
dl 0
loc 111
ccs 42
cts 42
cp 1
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A getLabel() 0 10 1
A renderBlock() 0 26 4
A renderCheckboxInline() 0 15 6
A renderCheckbox() 0 10 2
A processOption() 0 3 1
1
<?php
2
/**
3
 * User: delboy1978uk
4
 * Date: 04/12/2016
5
 * Time: 22:33
6
 */
7
8
namespace Del\Form\Renderer\Field;
9
10
use Del\Form\Field\FieldInterface;
11
use Del\Form\Field\CheckBox;
12
use DOMDocumentFragment;
13
use DOMElement;
14
use DOMNode;
15
use DOMText;
16
use InvalidArgumentException;
17
use LogicException;
18
19
class CheckboxRender extends AbstractFieldRender implements FieldRendererInterface
20
{
21
    /** @var DOMDocumentFragment $div */
22
    private $fragment;
23
24
    /** @var bool $isMultiCheckbox */
25
    private $isMultiCheckbox = false;
26
27
    private $counter = 0;
28
29
    /**
30
     * @param FieldInterface $field
31
     * @param DOMElement $element
32
     * @return DOMNode
33
     */
34 9
    public function renderBlock(FieldInterface $field, DOMElement $element)
35
    {
36
        // We don't really want a containing div, so we'll ignore $element
37
        // and instead create a DOMDocumentFragment
38 9
        $this->fragment = $this->getDom()->createDocumentFragment();
39
40
        // Make sure the FieldInterface is actually a Radio
41 9
        if (!$field instanceof CheckBox) {
42 1
            throw new InvalidArgumentException('Must be a Del\Form\Field\Checkbox');
43
        }
44
45 8
        $inline = $field->isRenderInline();
46
47 8
        $options = $field->getOptions();
48 8
        if (empty($options)) {
49 1
            throw new LogicException('You must set at least one option.');
50
        }
51
52
        // Loop through each checkbox element (the options)
53 7
        $this->isMultiCheckbox = count($options) > 1;
54 7
        foreach ($options as $value => $label) {
55 7
            $radio = $this->processOption($field, $value, $label, $inline);
56 7
            $this->fragment->appendChild($radio);
57
        }
58
59 7
        return $this->fragment;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->fragment returns the type DOMDocumentFragment which is incompatible with the return type mandated by Del\Form\Renderer\Field\...ldRender::renderBlock() of DOMElement.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
60
    }
61
62
63
    /**
64
     * @param FieldInterface $field
65
     * @param $value
66
     * @param $labelText
67
     * @return DOMElement
68
     */
69 7
    private function processOption(FieldInterface $field, $value, $labelText, $inline)
70
    {
71 7
        return $this->renderCheckbox($field, $value, $labelText, $inline);
72
    }
73
74
    /**
75
     * @param CheckBox $field
76
     * @param $value
77
     * @param $labelText
78
     * @return DOMElement
79
     */
80 7
    private function renderCheckbox(CheckBox $field, $value, $labelText, $inline)
81
    {
82 7
        $div = $this->getDom()->createElement('div');
83 7
        $class = $inline ? 'form-check-inline' : 'form-check';
84 7
        $div->setAttribute('class', $class);
85 7
        $checkbox = $this->renderCheckboxInline($field, $value);
86 7
        $div->appendChild($checkbox);
87 7
        $div->appendChild($this->getLabel($field, $labelText));
88
89 7
        return $div;
90
    }
91
92
    /**
93
     * @param FieldInterface $field
94
     * @param string $labelText
95
     * @return DOMElement
96
     */
97 7
    private function getLabel(FieldInterface $field, string $labelText): DOMElement
98
    {
99 7
        $this->counter ++;
100 7
        $label = $this->getDom()->createElement('label');
101 7
        $label->setAttribute('for', $field->getId() . $this->counter);
102 7
        $label->setAttribute('class', 'form-check-label');
103 7
        $text = $this->createText($labelText);
104 7
        $label->appendChild($text);
105
106 7
        return $label;
107
    }
108
109
    /**
110
     * @param FieldInterface $field
111
     * @param $value
112
     * @param $labelText
113
     * @return DOMElement
114
     */
115 7
    private function renderCheckboxInline(FieldInterface $field, $value)
116
    {
117 7
        $checkbox = $this->getDom()->createElement('input');
118 7
        $checkbox->setAttribute('class', 'form-check-input');
119 7
        $checkbox->setAttribute('type', 'checkbox');
120 7
        $fieldName = $this->isMultiCheckbox ? $field->getName() . '[]' : $field->getName();
121 7
        $checkbox->setAttribute('name', $fieldName);
122 7
        $checkbox->setAttribute('value', $value);
123 7
        $fieldValue = $field->getValue();
124
125 7
        if ($fieldValue === true || $fieldValue == $value || (is_array($fieldValue) && in_array($value, $fieldValue, true))) {
126 3
            $checkbox->setAttribute('checked', 'checked');
127
        }
128
129 7
        return $checkbox;
130
    }
131
}
132