Completed
Push — master ( 924f63...450060 )
by Derek Stephen
02:44
created

FormRenderer   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 166
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 21
lcom 1
cbo 3
dl 0
loc 166
ccs 75
cts 75
cp 1
rs 10
c 0
b 0
f 0

11 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A render() 0 11 1
A setFormAttributes() 0 14 1
A getMethod() 0 4 2
A getId() 0 4 2
A getAction() 0 4 2
A getEncType() 0 4 2
A processFields() 0 11 2
A createFieldDOM() 0 20 3
A createHelpBlock() 0 19 4
A createChildElement() 0 12 1
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 FormInterface $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 = $this->getMethod($form);
57 4
        $id = $this->getId($form);
58 4
        $action = $this->getAction($form);
59 4
        $encType = $this->getEncType($form);
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
    /**
70
     * @param FormInterface $form
71
     * @return string
72
     */
73 4
    private function getMethod(FormInterface $form)
74
    {
75 4
        return $form->getMethod() ?: AbstractForm::METHOD_POST;
76
    }
77
78
    /**
79
     * @param FormInterface $form
80
     * @return string
81
     */
82 4
    private function getId(FormInterface $form)
83
    {
84 4
        return $form->getId() ?: $this->form->getAttribute('name');
85
    }
86
87
    /**
88
     * @param FormInterface $form
89
     * @return string
90
     */
91 4
    private function getAction(FormInterface $form)
92
    {
93 4
        return $form->getAction() ?: $this->form->getAttribute('action');
94
    }
95
96
    /**
97
     * @param FormInterface $form
98
     * @return string
99
     */
100 4
    private function getEncType(FormInterface $form)
101
    {
102 4
        return $form->getEncType() ?: $this->form->getAttribute('enc-type');
103
    }
104
105 4
    private function processFields(FieldCollection $fields)
106
    {
107 4
        $fields->rewind();
108 4
        while ($fields->valid()) {
109 3
            $current = $fields->current();
110 3
            $child = $this->createFieldDOM($current);
111 3
            $this->form->appendChild($child);
112 3
            $fields->next();
113
        }
114 4
        $fields->rewind();
115 4
    }
116
117
    /**
118
     * @param FieldInterface $field
119
     * @return DOMElement
120
     */
121 3
    private function createFieldDOM(FieldInterface $field)
122
    {
123 3
        $formGroup = $this->dom->createElement('div');
124 3
        $formGroup->setAttribute('class', 'form-group');
125
126 3
        $label = $this->dom->createElement('label');
127 3
        $label->setAttribute('for', $field->getId());
128 3
        $label->textContent = $field->getLabel();
129
130 3
        $formField = $this->createChildElement($field);
131
132 3
        $formGroup->appendChild($label);
133 3
        $formGroup->appendChild($formField);
134
135 3
        if (!$field->isValid() && $this->displayErrors === true) {
136 1
            $formGroup = $this->createHelpBlock($formGroup, $field->getMessages());
137
        }
138
139 3
        return $formGroup;
140
    }
141
142 1
    private function createHelpBlock(DOMElement $formGroup, array $messages)
143
    {
144 1
        $formGroup->setAttribute('class', 'form-group has-error');
145 1
        $helpBlock = $this->dom->createElement('span');
146 1
        $helpBlock->setAttribute('class', 'help-block');
147 1
        $errorMessages = '';
148 1
        foreach ($messages as $message) {
149 1
            if(is_array($message)) {
150 1
                foreach ($message as $m) {
151 1
                    $errorMessages .= $m."\n";
152
                }
153
            } else {
154 1
                $errorMessages .= $message."\n";
155
            }
156
        }
157 1
        $helpBlock->textContent = $errorMessages;
158 1
        $formGroup->appendChild($helpBlock);
159 1
        return $formGroup;
160
    }
161
162
163
164
    /**
165
     * @param FieldInterface $field
166
     * @return DOMElement
167
     */
168 3
    private function createChildElement(FieldInterface $field)
169
    {
170 3
        $child = $this->dom->createElement($field->getTag());
171
172 3
        $child->setAttribute('type', $field->getTagType());
173 3
        $child->setAttribute('name', $field->getName());
174 3
        $child->setAttribute('id', $field->getId());
175 3
        $child->setAttribute('value', $field->getValue());
176 3
        $child->setAttribute('class', $field->getClass());
177
178 3
        return $child;
179
    }
180
}