Completed
Branch master (7150c8)
by Derek Stephen
01:56
created

FormRenderer::getAction()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 1
b 0
f 0
cc 2
eloc 2
nc 2
nop 1
crap 2
1
<?php
2
/**
3
 * User: delboy1978uk
4
 * Date: 29/11/2016
5
 * Time: 19:44
6
 */
7
8
namespace Del\Form\Renderer;
9
10
use Del\Form\Collection\FieldCollection;
11
use Del\Form\Field\FieldInterface;
12
use Del\Form\AbstractForm;
13
use Del\Form\FormInterface;
14
use DOMDocument;
15
use DOMElement;
16
use DOMText;
17
18
class FormRenderer
19
{
20
    /** @var DOMDocument $dom */
21
    private $dom;
22
23
    /** @var DomElement $form */
24
    private $form;
25
26
    /** @var bool $displayErrors */
27
    private $displayErrors;
28
29 17
    public function __construct($name)
30
    {
31 17
        $this->dom = new DOMDocument();
32 17
        $form = $this->dom->createElement('form');
33 17
        $form->setAttribute('name', $name);
34 17
        $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\Renderer\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...
35 17
    }
36
37
    /**
38
     * @param FormInterface $form
39
     * @param bool $displayErrors
40
     * @return string
41
     */
42 5
    public function render(FormInterface $form, $displayErrors = true)
43
    {
44 5
        $this->displayErrors = $displayErrors;
45 5
        $this->setFormAttributes($form);
46
47 5
        $fields = $form->getFields();
48 5
        $this->processFields($fields);
49
50 5
        $this->dom->appendChild($this->form);
51 5
        return $this->dom->saveHTML();
52
    }
53
54
    /**
55
     * @param FormInterface $form
56
     */
57 5
    private function setFormAttributes(FormInterface $form)
58
    {
59 5
        $method = $this->getMethod($form);
60 5
        $id = $this->getId($form);
61 5
        $action = $this->getAction($form);
62 5
        $encType = $this->getEncType($form);
63 5
        $class = $form->getClass();
64
65 5
        $this->form->setAttribute('id', $id);
66 5
        $this->form->setAttribute('method', $method);
67 5
        $this->form->setAttribute('class', $class);
68 5
        $this->form->setAttribute('action', $action);
69 5
        $this->form->setAttribute('enctype', $encType);
70 5
    }
71
72
    /**
73
     * @param FormInterface $form
74
     * @return string
75
     */
76 5
    private function getMethod(FormInterface $form)
77
    {
78 5
        return $form->getMethod() ?: AbstractForm::METHOD_POST;
79
    }
80
81
    /**
82
     * @param FormInterface $form
83
     * @return string
84
     */
85 5
    private function getId(FormInterface $form)
86
    {
87 5
        return $form->getId() ?: $this->form->getAttribute('name');
88
    }
89
90
    /**
91
     * @param FormInterface $form
92
     * @return string
93
     */
94 5
    private function getAction(FormInterface $form)
95
    {
96 5
        return $form->getAction() ?: $this->form->getAttribute('action');
97
    }
98
99
    /**
100
     * @param FormInterface $form
101
     * @return string
102
     */
103 5
    private function getEncType(FormInterface $form)
104
    {
105 5
        return $form->getEncType() ?: $this->form->getAttribute('enc-type');
106
    }
107
108 5
    private function processFields(FieldCollection $fields)
109
    {
110 5
        $fields->rewind();
111 5
        while ($fields->valid()) {
112 4
            $current = $fields->current();
113 4
            $child = $this->createFieldDOM($current);
114 4
            $this->form->appendChild($child);
115 4
            $fields->next();
116
        }
117 5
        $fields->rewind();
118 5
    }
119
120
    /**
121
     * @param FieldInterface $field
122
     * @return DOMElement
123
     */
124 4
    private function createFieldDOM(FieldInterface $field)
125
    {
126 4
        $formGroup = $this->dom->createElement('div');
127 4
        $formGroup->setAttribute('class', 'form-group');
128
129 4
        $label = $this->dom->createElement('label');
130 4
        $label->setAttribute('for', $field->getId());
131 4
        $label->textContent = $field->getLabel();
132
133 4
        $formField = $this->createChildElement($field);
134
135 4
        $formGroup->appendChild($label);
136 4
        $formGroup->appendChild($formField);
137
138 4
        if (!$field->isValid() && $this->displayErrors === true) {
139 2
            $formGroup = $this->createHelpBlock($formGroup, $field);
140
        }
141
142 4
        return $formGroup;
143
    }
144
145
    /**
146
     * @param DOMElement $formGroup
147
     * @param FieldInterface $field
148
     * @return DOMElement]
0 ignored issues
show
Documentation introduced by
The doc-type DOMElement] could not be parsed: Expected "|" or "end of type", but got "]" at position 10. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
149
     */
150 2
    private function createHelpBlock(DOMElement $formGroup, FieldInterface $field)
151
    {
152 2
        $formGroup->setAttribute('class', 'form-group has-error');
153 2
        $helpBlock = $this->dom->createElement('span');
154 2
        $helpBlock->setAttribute('class', 'help-block');
155
156 2
        if ($field->hasCustomErrorMessage()) {
157 1
            $helpBlock = $this->addCustomErrorMessage($helpBlock, $field);
158
        } else {
159 1
            $helpBlock = $this->addErrorMessages($helpBlock, $field);
160
        }
161 2
        $formGroup->appendChild($helpBlock);
162 2
        return $formGroup;
163
    }
164
165
    /**
166
     * @param DOMElement $helpBlock
167
     * @param FieldInterface $field
168
     * @return DOMElement
169
     */
170 1
    private function addCustomErrorMessage(DOMElement $helpBlock, FieldInterface $field)
171
    {
172 1
        $message = $field->getCustomErrorMessage();
173 1
        $text = new DOMText($message);
174 1
        $helpBlock->appendChild($text);
175 1
        return $helpBlock;
176
    }
177
178
    /**
179
     * @param DOMElement $helpBlock
180
     * @param FieldInterface $field
181
     * @return DOMElement]
0 ignored issues
show
Documentation introduced by
The doc-type DOMElement] could not be parsed: Expected "|" or "end of type", but got "]" at position 10. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
182
     */
183 1
    private function addErrorMessages(DOMElement $helpBlock, FieldInterface $field)
184
    {
185 1
        $messages = $field->getMessages();
186
187 1
        foreach ($messages as $message) {
188 1
            $helpBlock = $this->appendMessage($helpBlock, $message);
189
        }
190 1
        return $helpBlock;
191
    }
192
193
    /**
194
     * @param DOMElement $helpBlock
195
     * @param $message
196
     * @return DOMElement
197
     */
198 1
    private function appendMessage(DOMElement $helpBlock, $message)
199
    {
200 1
        $text = new DOMText($message);
201 1
        $br = $this->dom->createElement('br');
202 1
        $helpBlock->appendChild($text);
203 1
        $helpBlock->appendChild($br);
204 1
        return $helpBlock;
205
    }
206
207
    /**
208
     * @param FieldInterface $field
209
     * @return DOMElement
210
     */
211 4
    private function createChildElement(FieldInterface $field)
212
    {
213 4
        $child = $this->dom->createElement($field->getTag());
214
215 4
        $child->setAttribute('type', $field->getTagType());
216 4
        $child->setAttribute('name', $field->getName());
217 4
        $child->setAttribute('id', $field->getId());
218 4
        $child->setAttribute('value', $field->getValue());
219 4
        $child->setAttribute('class', $field->getClass());
220
221 4
        return $child;
222
    }
223
}