Issues (26)

src/formdata/FormDataRenderer.php (2 issues)

1
<?php declare(strict_types = 1);
2
namespace Templado\Engine;
3
4
use DOMElement;
5
use DOMXPath;
6
7
class FormDataRenderer {
8
9
    /**
10
     * @throws FormDataRendererException
11
     */
12 45
    public function render(DOMElement $context, FormData $form): void {
13
        try {
14 45
            $formElement = $this->findFormElement($context, $form->getIdentifier());
15
16 39
            $this->processInputElements($form, $formElement);
17 36
            $this->processSelectElements($form, $formElement);
18 36
            $this->processTextareaElement($form, $formElement);
19 9
        } catch (FormDataException $e) {
20 3
            throw new FormDataRendererException(
21 3
                $e->getMessage()
22
            );
23
        }
24 36
    }
25
26 21
    private function setInputValue(DOMElement $input, string $value): void {
27 21
        $type = $input->getAttribute('type');
28
29 21
        switch ($type) {
30 21
            case 'file':
31 18
            case 'password':
32 6
                return;
33 15
            case 'radio':
34 12
            case 'checkbox':
35 6
                $this->toggleInput($input, $value);
36
37 6
                return;
38
            default:
39 9
                $input->setAttribute('value', $value);
40
        }
41 9
    }
42
43 6
    private function toggleInput(DOMElement $input, string $value): void {
44 6
        $actualValue = $input->getAttribute('value');
45
46 6
        if ($actualValue === $value) {
47 6
            $input->setAttribute('checked', 'checked');
48
49 6
            return;
50
        }
51 3
        $input->removeAttribute('checked');
52 3
    }
53
54 3
    private function setSelectValue(DOMElement $select, string $value): void {
55 3
        foreach ($select->getElementsByTagName('option') as $option) {
56
            /** @var DOMElement $option */
57 3
            if ($option->getAttribute('value') === $value) {
58 3
                $option->setAttribute('selected', 'selected');
59
60 3
                continue;
61
            }
62 3
            $option->removeAttribute('selected');
63
        }
64 3
    }
65
66
    /**
67
     * @throws FormDataRendererException
68
     */
69 45
    private function findFormElement(DOMElement $context, string $identifier): DOMElement {
70 45
        $xp     = new DOMXPath($context->ownerDocument);
0 ignored issues
show
It seems like $context->ownerDocument can also be of type null; however, parameter $document of DOMXPath::__construct() does only seem to accept DOMDocument, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

70
        $xp     = new DOMXPath(/** @scrutinizer ignore-type */ $context->ownerDocument);
Loading history...
71 45
        $result = $xp->query(
72 45
            \sprintf('.//*[local-name() = "form" and (@id = "%1$s" or @name = "%1$s")]', $identifier),
73 15
            $context
74
        );
75
76 45
        switch ($result->length) {
77 45
            case 1: {
78
                /** @psalm-var DOMElement */
79 39
                return $result->item(0);
80
            }
81 6
            case 0: {
82 3
                throw new FormDataRendererException(
83 3
                    \sprintf('No form with name or id "%s" found', $identifier)
84
                );
85
            }
86
            default: {
87 3
                throw new FormDataRendererException(
88 3
                    \sprintf('Multiple forms found with name or id "%s"', $identifier)
89
                );
90
91
            }
92
        }
93
    }
94
95
    /**
96
     * @throws FormDataException
97
     */
98 39
    private function processInputElements(FormData $form, DOMElement $formElement): void {
99 39
        foreach ($formElement->getElementsByTagName('input') as $input) {
100
            /** @var DOMElement $input */
101 27
            $name = $input->getAttribute('name');
102
103 27
            if (!$form->hasKey($name)) {
104 3
                continue;
105
            }
106 24
            $this->setInputValue(
107 24
                $input,
108 24
                $form->getValue(
109 24
                    $name
110
                )
111
            );
112
        }
113 36
    }
114
115
    /**
116
     * @throws FormDataException
117
     */
118 36
    private function processSelectElements(FormData $form, DOMElement $formElement): void {
119 36
        foreach ($formElement->getElementsByTagName('select') as $select) {
120
            /** @var DOMElement $select */
121 6
            $name = $select->getAttribute('name');
122
123 6
            if (!$form->hasKey($name)) {
124 3
                continue;
125
            }
126 3
            $this->setSelectValue(
127 3
                $select,
128 3
                $form->getValue(
129 3
                    $select->getAttribute('name')
130
                )
131
            );
132
        }
133 36
    }
134
135
    /**
136
     * @throws FormDataException
137
     */
138 36
    private function processTextareaElement(FormData $form, DOMElement $formElement): void {
139 36
        foreach ($formElement->getElementsByTagName('textarea') as $textarea) {
140
            /** @var DOMElement $textarea */
141 6
            $name = $textarea->getAttribute('name');
142
143 6
            if (!$form->hasKey($name)) {
144 3
                continue;
145
            }
146 3
            $textarea->nodeValue = '';
147 3
            $textarea->appendChild(
148 3
                $textarea->ownerDocument->createTextNode(
0 ignored issues
show
The method createTextNode() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

148
                $textarea->ownerDocument->/** @scrutinizer ignore-call */ 
149
                                          createTextNode(

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
149 3
                    $form->getValue(
150 3
                        $textarea->getAttribute('name')
151
                    )
152
                )
153
            );
154
        }
155 36
    }
156
}
157