Completed
Push — master ( 30f23d...c3cbe9 )
by Derek Stephen
05:45
created

AbstractFormRenderer   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 155
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
dl 0
loc 155
c 0
b 0
f 0
wmc 18
lcom 1
cbo 6
ccs 66
cts 66
cp 1
rs 10

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A resetDom() 0 5 1
A render() 0 13 1
A setFormAttributes() 0 14 2
A getMethod() 0 4 2
A getId() 0 4 2
A processFields() 0 15 3
A renderError() 0 9 3
A createLabelElement() 0 9 2
A addRequiredAsterisk() 0 9 1
1
<?php
2
/**
3
 * User: delboy1978uk
4
 * Date: 07/12/2016
5
 * Time: 01:54
6
 */
7
8
namespace Del\Form\Renderer;
9
10
use Del\Form\Collection\FieldCollection;
11
use Del\Form\AbstractForm;
12
use Del\Form\Field\FieldInterface;
13
use Del\Form\FormInterface;
14
use Del\Form\Renderer\Error\DefaultErrorRender;
15
use Del\Form\Renderer\Error\ErrorRendererInterface;
16
use DOMDocument;
17
use DomElement;
18
use DOMText;
19
20
abstract class AbstractFormRenderer implements FormRendererInterface
21
{
22
    /** @var DOMDocument $dom */
23
    protected $dom;
24
25
    /** @var DomElement $form */
26
    protected $form;
27
28
    /** @var bool $displayErrors */
29
    protected $displayErrors;
30
31
    /** @var ErrorRendererInterface $errorRenderer */
32
    protected $errorRenderer;
33
34
    /** @var DomElement $label The label element*/
35
    protected $label;
36
37
    /** @var DomElement $element the field element */
38
    protected $element;
39
40
    /** @var DomElement $errors The error block html*/
41
    protected $errors;
42
43
    /** @var DomElement $block The containing html block */
44
    protected $block;
45
46
    /** @var FieldInterface $field The current field being processed */
47
    protected $field;
48
49 40
    public function __construct()
50
    {
51 40
        $this->resetDom();
52 40
        $this->errorRenderer = new DefaultErrorRender($this->dom);
53 40
    }
54
55
    /**
56
     *  resets dom
57
     */
58 40
    private function resetDom()
59
    {
60 40
        $this->dom = new DOMDocument();
61 40
        $this->form = $this->dom->createElement('form');
62 40
    }
63
64
    /**
65
     * @param FormInterface $form
66
     * @param bool $displayErrors
67
     * @return string
68
     */
69 23
    public function render(FormInterface $form, $displayErrors = true)
70
    {
71 23
        $this->displayErrors = $displayErrors;
72 23
        $this->setFormAttributes($form);
73
74 23
        $fields = $form->getFields();
75 23
        $this->processFields($fields);
76
77 18
        $this->dom->appendChild($this->form);
78 18
        $html = $this->dom->saveHTML();
79 18
        $this->resetDom();
80 18
        return $html;
81
    }
82
83
    /**
84
     * @param FormInterface $form
85
     */
86 23
    private function setFormAttributes(FormInterface $form)
87
    {
88 23
        $attributes = $form->getAttributes();
89 23
        foreach ($attributes as $key => $value) {
90 23
            $this->form->setAttribute($key, $value);
91 23
        }
92
93
        // set Id as name or method as post if not set
94 23
        $method = $this->getMethod($form);
95 23
        $id = $this->getId($form);
96
97 23
        $this->form->setAttribute('id', $id);
98 23
        $this->form->setAttribute('method', $method);
99 23
    }
100
101
    /**
102
     * @param FormInterface $form
103
     * @return string
104
     */
105 23
    private function getMethod(FormInterface $form)
106
    {
107 23
        return $form->getMethod() ?: AbstractForm::METHOD_POST;
108
    }
109
110
    /**
111
     * @param FormInterface $form
112
     * @return string
113
     */
114 23
    private function getId(FormInterface $form)
115
    {
116 23
        return $form->getId() ?: $this->form->getAttribute('name');
117
    }
118
119 23
    private function processFields(FieldCollection $fields)
120
    {
121 23
        $fields->rewind();
122 23
        while ($fields->valid()) {
123 21
            $this->block = $this->dom->createElement('div');
124 21
            $this->field = $fields->current();
125 21
            $this->label = $this->renderFieldLabel();
126 21
            $this->element = $this->field->getRenderer()->render($this->dom, $this->field);
127 16
            $this->errors = $this->field->isValid() ? null : $this->renderError();
128 16
            $this->block = $this->renderFieldBlock();
129 16
            $this->form->appendChild($this->block);
130 16
            $fields->next();
131 16
        }
132 18
        $fields->rewind();
133 18
    }
134
135
136
137
    /**
138
     * @return \DOMElement|null
139
     */
140 3
    public function renderError()
141
    {
142 3
        $errorBlock = null;
143 3
        if ($this->errorRenderer->shouldRender($this->field) && $this->displayErrors === true) {
144 3
            $this->block->setAttribute('class', 'has-error ');
145 3
            $errorBlock = $this->errorRenderer->render($this->field);
146 3
        }
147 3
        return $errorBlock;
148
    }
149
150
    /**
151
     * @return \DOMElement
152
     */
153 21
    protected function createLabelElement()
154
    {
155 21
        $label = $this->dom->createElement('label');
156 21
        $label->setAttribute('for', $this->field->getId());
157 21
        if ($this->field->isRequired()) {
158 3
            $label = $this->addRequiredAsterisk($label);
159 3
        }
160 21
        return $label;
161
    }
162
163
164 3
    public function addRequiredAsterisk(DomElement $label)
165
    {
166 3
        $span = $this->dom->createElement('span');
167 3
        $span->setAttribute('class', 'text-danger');
168 3
        $text = new DOMText('* ');
169 3
        $span->appendChild($text);
170 3
        $label->appendChild($span);
171 3
        return $label;
172
    }
173
174
}