Completed
Branch dev-master (8ff17a)
by Derek Stephen
01:52
created

AbstractFormRenderer::createLabelElement()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 4
cts 4
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 0
crap 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
19
abstract class AbstractFormRenderer implements FormRendererInterface
20
{
21
    /** @var DOMDocument $dom */
22
    protected $dom;
23
24
    /** @var DomElement $form */
25
    protected $form;
26
27
    /** @var bool $displayErrors */
28
    protected $displayErrors;
29
30
    /** @var ErrorRendererInterface $errorRenderer */
31
    protected $errorRenderer;
32
33
    /** @var DomElement $label The label element*/
34
    protected $label;
35
36
    /** @var DomElement $element the field element */
37
    protected $element;
38
39
    /** @var DomElement $errors The error block html*/
40
    protected $errors;
41
42
    /** @var DomElement $block The containing html block */
43
    protected $block;
44
45
    /** @var FieldInterface $field The current field being processed */
46
    protected $field;
47
48 23
    public function __construct()
49
    {
50 23
        $this->dom = new DOMDocument();
51 23
        $this->form = $this->dom->createElement('form');
52 23
        $this->errorRenderer = new DefaultErrorRender($this->dom);
53 23
    }
54
55
    /**
56
     * @param FormInterface $form
57
     * @param bool $displayErrors
58
     * @return string
59
     */
60 10
    public function render(FormInterface $form, $displayErrors = true)
61
    {
62 10
        $this->displayErrors = $displayErrors;
63 10
        $this->setFormAttributes($form);
64
65 10
        $fields = $form->getFields();
66 10
        $this->processFields($fields);
67
68 9
        $this->dom->appendChild($this->form);
69 9
        return $this->dom->saveHTML();
70
    }
71
72
    /**
73
     * @param FormInterface $form
74
     */
75 10
    private function setFormAttributes(FormInterface $form)
76
    {
77 10
        $attributes = $form->getAttributes();
78 10
        foreach ($attributes as $key => $value) {
79 10
            $this->form->setAttribute($key, $value);
80
        }
81
82
        // set Id as name or method as post if not set
83 10
        $method = $this->getMethod($form);
84 10
        $id = $this->getId($form);
85
86 10
        $this->form->setAttribute('id', $id);
87 10
        $this->form->setAttribute('method', $method);
88 10
    }
89
90
    /**
91
     * @param FormInterface $form
92
     * @return string
93
     */
94 10
    private function getMethod(FormInterface $form)
95
    {
96 10
        return $form->getMethod() ?: AbstractForm::METHOD_POST;
97
    }
98
99
    /**
100
     * @param FormInterface $form
101
     * @return string
102
     */
103 10
    private function getId(FormInterface $form)
104
    {
105 10
        return $form->getId() ?: $this->form->getAttribute('name');
106
    }
107
108 10
    private function processFields(FieldCollection $fields)
109
    {
110 10
        $fields->rewind();
111 10
        while ($fields->valid()) {
112 9
            $this->block = $this->dom->createElement('div');
113 9
            $this->field = $fields->current();
114 9
            $this->label = $this->renderFieldLabel();
115 9
            $this->element = $this->field->getRenderer()->render($this->dom, $this->field);
116 8
            $this->errors = $this->field->isValid() ? null : $this->renderError();
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->field->isValid() ... : $this->renderError() can also be of type object<Del\Form\Renderer\DOMElement>. However, the property $errors is declared as type object<DOMElement>. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
117 8
            $this->block = $this->renderFieldBlock();
118 8
            $this->form->appendChild($this->block);
119 8
            $fields->next();
120
        }
121 9
        $fields->rewind();
122 9
    }
123
124
125
126
    /**
127
     * @return DOMElement|null
128
     */
129 5
    public function renderError()
130
    {
131 5
        $errorBlock = null;
132 5
        if (!$this->field->isValid() && $this->displayErrors === true) {
133 3
            $this->block->setAttribute('class', 'has-error ');
134 3
            $errorBlock = $this->errorRenderer->render($this->field);
135
        }
136 5
        return $errorBlock;
137
    }
138
139
    /**
140
     * @return DOMElement
141
     */
142 9
    protected function createLabelElement()
143
    {
144 9
        $label = $this->dom->createElement('label');
145 9
        $label->setAttribute('for', $this->field->getId());
146 9
        return $label;
147
    }
148
149
}