-
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathAbstractForm.php
More file actions
140 lines (117 loc) · 3.69 KB
/
AbstractForm.php
File metadata and controls
140 lines (117 loc) · 3.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
<?php
declare(strict_types=1);
namespace PHPForge\Html\FormControl\Base;
use PHPForge\Html\{
Attribute\Custom\HasAttributes,
Attribute\Custom\HasContent,
Attribute\Custom\HasCsrf,
Attribute\HasClass,
Attribute\HasId,
Attribute\HasLang,
Attribute\HasStyle,
Attribute\HasTitle,
Attribute\Input\HasAccept,
Attribute\Input\HasAutocomplete,
Attribute\Input\HasName,
Attribute\Tag\CanBeNoValidate,
Attribute\Tag\HasAction,
Attribute\Tag\HasEnctype,
Attribute\Tag\HasMethod,
Attribute\Tag\HasRel,
FormControl\Input\Hidden,
HtmlBuilder
};
use PHPForge\Widget\Block;
use function explode;
use function implode;
use function strpos;
use function substr;
use function urldecode;
/**
* Provides a foundation for creating HTML `form` elements with various attributes and content.
*/
abstract class AbstractForm extends Block
{
use CanBeNoValidate;
use HasAccept;
use HasAction;
use HasAttributes;
use HasAutocomplete;
use HasClass;
use HasContent;
use HasCsrf;
use HasEnctype;
use HasId;
use HasLang;
use HasMethod;
use HasName;
use HasRel;
use HasStyle;
use HasTitle;
protected array $attributes = [];
/**
* Begin rendering the block element.
*
* @return string The opening tag of the block element.
*/
public function begin(): string
{
parent::begin();
$hiddenInputs = $this->renderHiddenInput();
$attributes = $this->attributes;
$attributes['id'] = $this->id;
$html = HtmlBuilder::begin('form', $attributes);
if ($hiddenInputs !== '') {
$html .= "\n$hiddenInputs";
}
return "$html$this->content";
}
/**
* Generate the HTML representation of the element.
*
* @return string The HTML representation of the element.
*/
protected function run(): string
{
if ($this->isBeginExecuted() === false) {
$hiddenInputs = $this->renderHiddenInput();
$attributes = $this->attributes;
$attributes['id'] = $this->id;
$html = '';
if ($hiddenInputs !== '') {
$html = "$hiddenInputs\n";
}
return HtmlBuilder::create('form', $html . $this->content, $attributes);
}
return HtmlBuilder::end('form');
}
private function renderHiddenInput(): string
{
/** @var string $action */
$action = $this->attributes['action'] ?? '';
$hiddenInputs = [];
$method = $this->attributes['method'] ?? '';
if ($this->csrfToken !== '' && $method === 'POST') {
$hiddenInputs[] = Hidden::widget()->id(null)->name($this->csrfName)->value($this->csrfToken)->render();
}
if ($method === 'GET' && ($pos = strpos($action, '?')) !== false) {
/**
* Query parameters in the action are ignored for GET method we use hidden fields to add them back.
*/
foreach (explode('&', substr($action, $pos + 1)) as $pair) {
$pos1 = strpos($pair, '=');
if ($pos1 !== false) {
$hiddenInputs[] = Hidden::widget()
->id(null)
->name(urldecode(substr($pair, 0, $pos1)))
->value(urldecode(substr($pair, $pos1 + 1)))
->render();
} else {
$hiddenInputs[] = Hidden::widget()->id(null)->name(urldecode($pair))->render();
}
}
$this->attributes['action'] = substr($action, 0, $pos);
}
return $hiddenInputs !== [] ? implode(PHP_EOL, $hiddenInputs) : '';
}
}