1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace GeminiLabs\SiteReviews\Modules\Html; |
4
|
|
|
|
5
|
|
|
use GeminiLabs\SiteReviews\Defaults\BuilderDefaults; |
6
|
|
|
use GeminiLabs\SiteReviews\Helper; |
7
|
|
|
use GeminiLabs\SiteReviews\Modules\Html\Attributes; |
8
|
|
|
|
9
|
|
|
class Builder |
10
|
|
|
{ |
11
|
|
|
const INPUT_TYPES = [ |
12
|
|
|
'button', 'checkbox', 'date', 'datetime-local', 'email', 'file', 'hidden', 'image', 'month', |
13
|
|
|
'number', 'password', 'radio', 'range', 'reset', 'search', 'submit', 'tel', 'text', 'time', |
14
|
|
|
'url', 'week', |
15
|
|
|
]; |
16
|
|
|
|
17
|
|
|
const TAGS_FORM = [ |
18
|
|
|
'input', 'select', 'textarea', |
19
|
|
|
]; |
20
|
|
|
|
21
|
|
|
const TAGS_STRUCTURE = [ |
22
|
|
|
'div', 'form', 'nav', 'ol', 'section', 'ul', |
23
|
|
|
]; |
24
|
|
|
|
25
|
|
|
const TAGS_TEXT = [ |
26
|
|
|
'a', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'i', 'label', 'li', 'option', 'p', 'pre', 'small', |
27
|
|
|
'span', |
28
|
|
|
]; |
29
|
|
|
|
30
|
|
|
/** |
31
|
|
|
* @var array |
32
|
|
|
*/ |
33
|
|
|
public $args = []; |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* @var array |
37
|
|
|
*/ |
38
|
|
|
public $globals = []; |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* @var bool |
42
|
|
|
*/ |
43
|
|
|
public $render = false; |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* @var string |
47
|
|
|
*/ |
48
|
|
|
public $tag; |
49
|
|
|
|
50
|
7 |
|
public function __construct( array $globals = [] ) |
51
|
|
|
{ |
52
|
7 |
|
$this->globals = $globals; |
53
|
7 |
|
} |
54
|
|
|
|
55
|
|
|
/** |
56
|
|
|
* @param string $method |
57
|
|
|
* @param array $args |
58
|
|
|
* @return string|void |
59
|
|
|
*/ |
60
|
7 |
|
public function __call( $method, $args ) |
61
|
|
|
{ |
62
|
7 |
|
$instance = new static( $this->globals ); |
63
|
7 |
|
$instance->setTagFromMethod( $method ); |
64
|
7 |
|
call_user_func_array( [$instance, 'normalize'], $args += ['',''] ); |
65
|
7 |
|
$tags = array_merge( static::TAGS_FORM, static::TAGS_STRUCTURE, static::TAGS_TEXT ); |
66
|
7 |
|
$generatedTag = in_array( $instance->tag, $tags ) |
67
|
7 |
|
? $instance->buildTag() |
68
|
7 |
|
: $instance->buildCustomField(); |
69
|
7 |
|
if( !$this->render ) { |
70
|
7 |
|
return $generatedTag; |
71
|
|
|
} |
72
|
|
|
echo $generatedTag; |
73
|
|
|
} |
74
|
|
|
|
75
|
|
|
/** |
76
|
|
|
* @param string $property |
77
|
|
|
* @param mixed $value |
78
|
|
|
* @return void |
79
|
|
|
*/ |
80
|
|
|
public function __set( $property, $value ) |
81
|
|
|
{ |
82
|
|
|
$properties = [ |
83
|
|
|
'args' => 'is_array', |
84
|
|
|
'globals' => 'is_array', |
85
|
|
|
'render' => 'is_bool', |
86
|
|
|
'tag' => 'is_string', |
87
|
|
|
]; |
88
|
|
|
if( !isset( $properties[$property] ) |
89
|
|
|
|| empty( array_filter( [$value], $properties[$property] )) |
90
|
|
|
)return; |
91
|
|
|
$this->$property = $value; |
92
|
|
|
} |
93
|
|
|
|
94
|
|
|
/** |
95
|
|
|
* @return string |
96
|
|
|
*/ |
97
|
7 |
|
public function getClosingTag() |
98
|
|
|
{ |
99
|
7 |
|
return '</'.$this->tag.'>'; |
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
/** |
103
|
|
|
* @return string |
104
|
|
|
*/ |
105
|
7 |
|
public function getOpeningTag() |
106
|
|
|
{ |
107
|
7 |
|
$attributes = glsr( Attributes::class )->{$this->tag}( $this->args )->toString(); |
108
|
7 |
|
return '<'.trim( $this->tag.' '.$attributes ).'>'; |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
/** |
112
|
|
|
* @return string|void |
113
|
|
|
*/ |
114
|
|
|
protected function buildCustomField() |
115
|
|
|
{ |
116
|
|
|
$className = glsr( Helper::class )->buildClassName( $this->tag, __NAMESPACE__.'\Fields' ); |
117
|
|
|
if( !class_exists( $className )) { |
118
|
|
|
glsr_log()->error( 'Field missing: '.$className ); |
119
|
|
|
return; |
120
|
|
|
} |
121
|
|
|
return (new $className( $this ))->build(); |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
/** |
125
|
|
|
* @return string|void |
126
|
|
|
*/ |
127
|
7 |
|
protected function buildDefaultTag( $text = '' ) |
128
|
|
|
{ |
129
|
7 |
|
if( empty( $text )) { |
130
|
7 |
|
$text = $this->args['text']; |
131
|
|
|
} |
132
|
7 |
|
return $this->getOpeningTag().$text.$this->getClosingTag(); |
133
|
|
|
} |
134
|
|
|
|
135
|
|
|
/** |
136
|
|
|
* @return string|void |
137
|
|
|
*/ |
138
|
|
|
protected function buildFieldDescription() |
139
|
|
|
{ |
140
|
|
|
if( empty( $this->args['description'] ))return; |
141
|
|
|
if( !empty( $this->globals['is_widget'] )) { |
142
|
|
|
return $this->small( $this->args['description'] ); |
143
|
|
|
} |
144
|
|
|
return $this->p( $this->args['description'], ['class' => 'description'] ); |
145
|
|
|
} |
146
|
|
|
|
147
|
|
|
/** |
148
|
|
|
* @return string|void |
149
|
|
|
*/ |
150
|
|
|
protected function buildFormInput() |
151
|
|
|
{ |
152
|
|
|
if( !in_array( $this->args['type'], ['checkbox', 'radio'] )) { |
153
|
|
|
return $this->buildFormLabel().$this->getOpeningTag(); |
154
|
|
|
} |
155
|
|
|
return empty( $this->args['options'] ) |
156
|
|
|
? $this->buildFormInputChoice() |
157
|
|
|
: $this->buildFormInputMultiChoice(); |
158
|
|
|
} |
159
|
|
|
|
160
|
|
|
/** |
161
|
|
|
* @return string|void |
162
|
|
|
*/ |
163
|
|
|
protected function buildFormInputChoice() |
164
|
|
|
{ |
165
|
|
|
return $this->label( $this->getOpeningTag().' '.$this->args['text'] ); |
166
|
|
|
} |
167
|
|
|
|
168
|
|
|
/** |
169
|
|
|
* @return string|void |
170
|
|
|
*/ |
171
|
|
|
protected function buildFormInputMultiChoice() |
172
|
|
|
{ |
173
|
|
|
if( $this->args['type'] == 'checkbox' ) { |
174
|
|
|
$this->args['name'].= '[]'; |
175
|
|
|
} |
176
|
|
|
// glsr_log( $this->args ); |
|
|
|
|
177
|
|
|
$options = array_reduce( array_keys( $this->args['options'] ), function( $carry, $key ) { |
178
|
|
|
return $carry.$this->li( $this->{$this->args['type']}([ |
179
|
|
|
'checked' => in_array( $key, (array)$this->args['value'] ), |
180
|
|
|
'name' => $this->args['name'], |
181
|
|
|
'text' => $this->args['options'][$key], |
182
|
|
|
'value' => $key, |
183
|
|
|
])); |
184
|
|
|
}); |
185
|
|
|
return $this->ul( $options, [ |
|
|
|
|
186
|
|
|
'class' => $this->args['class'], |
187
|
|
|
'id' => $this->args['id'], |
188
|
|
|
]); |
189
|
|
|
} |
190
|
|
|
|
191
|
|
|
/** |
192
|
|
|
* @return void|string |
193
|
|
|
*/ |
194
|
|
|
protected function buildFormLabel() |
195
|
|
|
{ |
196
|
|
|
if( empty( $this->args['label'] ) || $this->args['type'] == 'hidden' )return; |
197
|
|
|
return $this->label([ |
198
|
|
|
'for' => $this->args['id'], |
199
|
|
|
'text' => $this->args['label'], |
200
|
|
|
]); |
201
|
|
|
} |
202
|
|
|
|
203
|
|
|
/** |
204
|
|
|
* @return string|void |
205
|
|
|
*/ |
206
|
|
|
protected function buildFormSelect() |
207
|
|
|
{ |
208
|
|
|
return $this->buildFormLabel().$this->buildDefaultTag( $this->buildFormSelectOptions() ); |
209
|
|
|
} |
210
|
|
|
|
211
|
|
|
/** |
212
|
|
|
* @return string|void |
213
|
|
|
*/ |
214
|
|
|
protected function buildFormSelectOptions() |
215
|
|
|
{ |
216
|
|
|
return array_reduce( array_keys( $this->args['options'] ), function( $carry, $key ) { |
217
|
|
|
return $carry.$this->option([ |
218
|
|
|
'selected' => $this->args['value'] == $key, |
219
|
|
|
'text' => $this->args['options'][$key], |
220
|
|
|
'value' => $key, |
221
|
|
|
]); |
222
|
|
|
}); |
223
|
|
|
} |
224
|
|
|
|
225
|
|
|
/** |
226
|
|
|
* @return string|void |
227
|
|
|
*/ |
228
|
|
|
protected function buildFormTextarea() |
229
|
|
|
{ |
230
|
|
|
return $this->buildFormLabel().$this->buildDefaultTag( $this->args['value'] ); |
231
|
|
|
} |
232
|
|
|
|
233
|
|
|
/** |
234
|
|
|
* @return string|void |
235
|
|
|
*/ |
236
|
7 |
|
protected function buildTag() |
237
|
|
|
{ |
238
|
7 |
|
if( !in_array( $this->tag, static::TAGS_FORM )) { |
239
|
7 |
|
return $this->buildDefaultTag(); |
240
|
|
|
} |
241
|
|
|
return call_user_func( [$this, 'buildForm'.ucfirst( $this->tag )] ).$this->buildFieldDescription(); |
242
|
|
|
} |
243
|
|
|
|
244
|
|
|
/** |
245
|
|
|
* @param string|array ...$params |
246
|
|
|
* @return void |
247
|
|
|
*/ |
248
|
7 |
|
protected function normalize( ...$params ) |
249
|
|
|
{ |
250
|
7 |
|
if( is_string( $params[0] ) || is_numeric( $params[0] )) { |
251
|
7 |
|
$this->setNameOrTextAttributeForTag( $params[0] ); |
252
|
|
|
} |
253
|
7 |
|
if( is_array( $params[0] )) { |
254
|
|
|
$this->args += $params[0]; |
255
|
|
|
} |
256
|
7 |
|
else if( is_array( $params[1] )) { |
257
|
7 |
|
$this->args += $params[1]; |
258
|
|
|
} |
259
|
7 |
|
$this->args = glsr( BuilderDefaults::class )->merge( $this->args ); |
260
|
7 |
|
} |
261
|
|
|
|
262
|
|
|
/** |
263
|
|
|
* @param string $value |
264
|
|
|
* @return void |
265
|
|
|
*/ |
266
|
7 |
|
protected function setNameOrTextAttributeForTag( $value ) |
267
|
|
|
{ |
268
|
7 |
|
$attribute = in_array( $this->tag, static::TAGS_FORM ) |
269
|
|
|
? 'name' |
270
|
7 |
|
: 'text'; |
271
|
7 |
|
$this->args[$attribute] = $value; |
272
|
7 |
|
} |
273
|
|
|
|
274
|
|
|
/** |
275
|
|
|
* @param string $method |
276
|
|
|
* @return void |
277
|
|
|
*/ |
278
|
7 |
|
protected function setTagFromMethod( $method ) |
279
|
|
|
{ |
280
|
7 |
|
$this->tag = strtolower( $method ); |
281
|
7 |
|
if( in_array( $this->tag, static::INPUT_TYPES )) { |
282
|
|
|
$this->args['type'] = $this->tag; |
283
|
|
|
$this->tag = 'input'; |
284
|
|
|
} |
285
|
7 |
|
} |
286
|
|
|
} |
287
|
|
|
|
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.