Completed
Push — master ( ba72b8...924f63 )
by Derek Stephen
03:34
created

FormRenderer::setFormAttributes()   B

Complexity

Conditions 5
Paths 16

Size

Total Lines 14
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 5

Importance

Changes 0
Metric Value
dl 0
loc 14
ccs 12
cts 12
cp 1
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 11
nc 16
nop 1
crap 5
1
<?php
2
/**
3
 * User: delboy1978uk
4
 * Date: 29/11/2016
5
 * Time: 19:44
6
 */
7
8
namespace Del\Form;
9
10
use Del\Form\Collection\FieldCollection;
11
use Del\Form\Field\FieldInterface;
12
use DOMDocument;
13
use DOMElement;
14
15
class FormRenderer
16
{
17
    /** @var DOMDocument $dom */
18
    private $dom;
19
20
    /** @var DomElement $form */
21
    private $form;
22
23
    /** @var bool $displayErrors */
24
    private $displayErrors;
25
26 16
    public function __construct($name)
27
    {
28 16
        $this->dom = new DOMDocument();
29 16
        $form = $this->dom->createElement('form');
30 16
        $form->setAttribute('name', $name);
31 16
        $this->form = $form;
0 ignored issues
show
Documentation Bug introduced by
It seems like $form of type object<DOMElement> is incompatible with the declared type object<Del\Form\DomElement> of property $form.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
32 16
    }
33
34
    /**
35
     * @param AbstractForm $form
36
     * @param bool $displayErrors
37
     * @return string
38
     */
39 4
    public function render(FormInterface $form, $displayErrors = true)
40
    {
41 4
        $this->displayErrors = $displayErrors;
42 4
        $this->setFormAttributes($form);
43
44 4
        $fields = $form->getFields();
45 4
        $this->processFields($fields);
46
47 4
        $this->dom->appendChild($this->form);
48 4
        return $this->dom->saveHTML();
49
    }
50
51
    /**
52
     * @param FormInterface $form
53
     */
54 4
    private function setFormAttributes(FormInterface $form)
55
    {
56 4
        $method = $form->getMethod() ?: AbstractForm::METHOD_POST;
57 4
        $id = $form->getId() ?: $this->form->getAttribute('name');
58 4
        $action = $form->getAction() ?: $this->form->getAttribute('action');
59 4
        $encType = $form->getEncType() ?: $this->form->getAttribute('enc-type');
60 4
        $class = $form->getClass();
61
62 4
        $this->form->setAttribute('id', $id);
63 4
        $this->form->setAttribute('method', $method);
64 4
        $this->form->setAttribute('class', $class);
65 4
        $this->form->setAttribute('action', $action);
66 4
        $this->form->setAttribute('enctype', $encType);
67 4
    }
68
69 4
    private function processFields(FieldCollection $fields)
70
    {
71 4
        $fields->rewind();
72 4
        while ($fields->valid()) {
73 3
            $current = $fields->current();
74 3
            $child = $this->createFieldDOM($current);
75 3
            $this->form->appendChild($child);
76 3
            $fields->next();
77 3
        }
78 4
        $fields->rewind();
79 4
    }
80
81
    /**
82
     * @param FieldInterface $field
83
     * @return DOMElement
84
     */
85 3
    private function createFieldDOM(FieldInterface $field)
86
    {
87 3
        $formGroup = $this->dom->createElement('div');
88 3
        $formGroup->setAttribute('class', 'form-group');
89
90 3
        $label = $this->dom->createElement('label');
91 3
        $label->setAttribute('for', $field->getId());
92 3
        $label->textContent = $field->getLabel();
93
94 3
        $formField = $this->createChildElement($field);
95
96 3
        $formGroup->appendChild($label);
97 3
        $formGroup->appendChild($formField);
98
99 3
        if (!$field->isValid() && $this->displayErrors == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
100 1
            $formGroup = $this->createHelpBlock($formGroup, $field->getMessages());
101 1
        }
102
103 3
        return $formGroup;
104
    }
105
106 1
    private function createHelpBlock(DOMElement $formGroup, array $messages)
107
    {
108 1
        $formGroup->setAttribute('class', 'form-group has-error');
109 1
        $helpBlock = $this->dom->createElement('span');
110 1
        $helpBlock->setAttribute('class', 'help-block');
111 1
        $errorMessages = '';
112 1
        foreach ($messages as $message) {
113 1
            if(is_array($message)) {
114 1
                foreach ($message as $m) {
115 1
                    $errorMessages .= $m."\n";
116 1
                }
117 1
            } else {
118
                $errorMessages .= $message."\n";
119
            }
120 1
        }
121 1
        $helpBlock->textContent = $errorMessages;
122 1
        $formGroup->appendChild($helpBlock);
123 1
        return $formGroup;
124
    }
125
126
127
128
    /**
129
     * @param FieldInterface $field
130
     * @return DOMElement
131
     */
132 3
    private function createChildElement(FieldInterface $field)
133
    {
134 3
        $child = $this->dom->createElement($field->getTag());
135
136 3
        $child->setAttribute('type', $field->getTagType());
137 3
        $child->setAttribute('name', $field->getName());
138 3
        $child->setAttribute('id', $field->getId());
139 3
        $child->setAttribute('value', $field->getValue());
140 3
        $child->setAttribute('class', $field->getClass());
141
142 3
        return $child;
143
    }
144
}