This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | declare(strict_types=1); |
||
4 | |||
5 | namespace Arcanedev\LaravelHtml; |
||
6 | |||
7 | use Arcanedev\Html\Elements\{Button, File, Form, Input, Label, Select, Textarea}; |
||
8 | use Arcanedev\LaravelHtml\Contracts\FormBuilder as FormBuilderContract; |
||
9 | use DateTime; |
||
10 | use Illuminate\Contracts\Routing\UrlGenerator; |
||
11 | use Illuminate\Contracts\Session\Session; |
||
12 | use Illuminate\Support\{Arr, Collection, HtmlString, Str}; |
||
13 | |||
14 | /** |
||
15 | * Class FormBuilder |
||
16 | * |
||
17 | * @author ARCANEDEV <[email protected]> |
||
18 | */ |
||
19 | class FormBuilder extends AbstractBuilder implements FormBuilderContract |
||
20 | { |
||
21 | /* ----------------------------------------------------------------- |
||
22 | | Properties |
||
23 | | ----------------------------------------------------------------- |
||
24 | */ |
||
25 | |||
26 | /** |
||
27 | * The HTML builder instance. |
||
28 | * |
||
29 | * @var \Arcanedev\LaravelHtml\Contracts\HtmlBuilder |
||
30 | */ |
||
31 | protected $html; |
||
32 | |||
33 | /** |
||
34 | * The URL generator instance. |
||
35 | * |
||
36 | * @var \Illuminate\Contracts\Routing\UrlGenerator |
||
37 | */ |
||
38 | protected $url; |
||
39 | |||
40 | /** |
||
41 | * The CSRF token used by the form builder. |
||
42 | * |
||
43 | * @var string |
||
44 | */ |
||
45 | protected $csrfToken; |
||
46 | |||
47 | /** |
||
48 | * The session store implementation. |
||
49 | * |
||
50 | * @var \Illuminate\Contracts\Session\Session|\Illuminate\Session\Store |
||
51 | */ |
||
52 | protected $session; |
||
53 | |||
54 | /** |
||
55 | * The current model instance for the form. |
||
56 | * |
||
57 | * @var \Illuminate\Database\Eloquent\Model|null |
||
58 | */ |
||
59 | protected $model; |
||
60 | |||
61 | /** |
||
62 | * An array of label names we've created. |
||
63 | * |
||
64 | * @var array |
||
65 | */ |
||
66 | protected $labels = []; |
||
67 | |||
68 | /** |
||
69 | * The reserved form open attributes. |
||
70 | * |
||
71 | * @var array |
||
72 | */ |
||
73 | protected $reserved = ['method', 'url', 'route', 'action', 'files']; |
||
74 | |||
75 | /** |
||
76 | * The form methods that should be spoofed, in uppercase. |
||
77 | * |
||
78 | * @var array |
||
79 | */ |
||
80 | protected $spoofedMethods = ['DELETE', 'PATCH', 'PUT']; |
||
81 | |||
82 | /** |
||
83 | * The types of inputs to not fill values on by default. |
||
84 | * |
||
85 | * @var array |
||
86 | */ |
||
87 | protected $skipValueTypes = ['file', 'password', 'checkbox', 'radio']; |
||
88 | |||
89 | /* ----------------------------------------------------------------- |
||
90 | | Constructor |
||
91 | | ----------------------------------------------------------------- |
||
92 | */ |
||
93 | |||
94 | /** |
||
95 | * Create a new form builder instance. |
||
96 | * |
||
97 | * @param \Arcanedev\LaravelHtml\Contracts\HtmlBuilder $html |
||
98 | * @param \Illuminate\Contracts\Routing\UrlGenerator $url |
||
99 | * @param \Illuminate\Contracts\Session\Session $session |
||
100 | */ |
||
101 | 606 | public function __construct(Contracts\HtmlBuilder $html, UrlGenerator $url, Session $session) |
|
102 | { |
||
103 | 606 | $this->url = $url; |
|
104 | 606 | $this->html = $html; |
|
105 | 606 | $this->csrfToken = $session->token(); |
|
106 | |||
107 | 606 | $this->setSessionStore($session); |
|
108 | 606 | } |
|
109 | |||
110 | /* ----------------------------------------------------------------- |
||
111 | | Getters & Setters |
||
112 | | ----------------------------------------------------------------- |
||
113 | */ |
||
114 | |||
115 | /** |
||
116 | * Get the session store implementation. |
||
117 | * |
||
118 | * @return \Illuminate\Contracts\Session\Session|null |
||
119 | */ |
||
120 | 468 | public function getSessionStore(): ?Session |
|
121 | { |
||
122 | 468 | return $this->session; |
|
123 | } |
||
124 | |||
125 | /** |
||
126 | * Set the session store implementation. |
||
127 | * |
||
128 | * @param \Illuminate\Contracts\Session\Session $session |
||
129 | * |
||
130 | * @return $this |
||
131 | */ |
||
132 | 606 | public function setSessionStore(Session $session) |
|
133 | { |
||
134 | 606 | $this->session = $session; |
|
135 | |||
136 | 606 | return $this; |
|
137 | } |
||
138 | |||
139 | /** |
||
140 | * Set the model instance on the form builder. |
||
141 | * |
||
142 | * @param \Illuminate\Database\Eloquent\Model|mixed|null $model |
||
143 | * |
||
144 | * @return $this |
||
145 | */ |
||
146 | 66 | public function setModel($model) |
|
147 | { |
||
148 | 66 | $this->model = $model; |
|
149 | |||
150 | 66 | return $this; |
|
151 | } |
||
152 | |||
153 | /** |
||
154 | * Get the model instance on the form builder. |
||
155 | * |
||
156 | * @return \Illuminate\Database\Eloquent\Model|mixed|null |
||
157 | */ |
||
158 | 264 | public function getModel() |
|
159 | { |
||
160 | 264 | return $this->model; |
|
161 | } |
||
162 | |||
163 | /** |
||
164 | * Get the ID attribute for a field name. |
||
165 | * |
||
166 | * @param string|null $name |
||
167 | * @param array $attributes |
||
168 | * |
||
169 | * @return string|null |
||
170 | */ |
||
171 | 480 | public function getIdAttribute($name, array $attributes): ?string |
|
172 | { |
||
173 | 480 | if (array_key_exists('id', $attributes)) |
|
174 | 42 | return $attributes['id']; |
|
175 | |||
176 | 456 | if ( ! is_null($name) && in_array($name, $this->labels)) |
|
177 | 12 | return $name; |
|
178 | |||
179 | 444 | return null; |
|
180 | } |
||
181 | |||
182 | /** |
||
183 | * Get the value that should be assigned to the field. |
||
184 | * |
||
185 | * @param string $name |
||
186 | * @param mixed $value |
||
187 | * |
||
188 | * @return mixed |
||
189 | */ |
||
190 | 450 | public function getValueAttribute($name, $value = null) |
|
191 | { |
||
192 | 450 | if (is_null($name)) |
|
193 | 6 | return $value; |
|
194 | |||
195 | 444 | if ( ! is_null($this->old($name)) && $name !== '_method') |
|
196 | 30 | return $this->old($name); |
|
197 | |||
198 | 432 | if ( ! is_null($value)) |
|
199 | 252 | return $value; |
|
200 | |||
201 | 234 | return $this->getModelValueAttribute($name); |
|
202 | } |
||
203 | |||
204 | /** |
||
205 | * Get the model value that should be assigned to the field. |
||
206 | * |
||
207 | * @param string $name |
||
208 | * @param \Illuminate\Database\Eloquent\Model|mixed|null $model |
||
209 | * |
||
210 | * @return mixed |
||
211 | */ |
||
212 | 252 | private function getModelValueAttribute(string $name, $model = null) |
|
213 | { |
||
214 | 252 | $model = $model ?: $this->getModel(); |
|
215 | |||
216 | 252 | $key = static::transformKey($name); |
|
0 ignored issues
–
show
|
|||
217 | |||
218 | 252 | if (strpos($key, '.') !== false) { |
|
219 | 30 | $keys = explode('.', $key, 2); |
|
220 | |||
221 | 30 | return $this->getModelValueAttribute( |
|
222 | 30 | $keys[1], |
|
223 | 30 | $this->getModelValueAttribute($keys[0], $model) |
|
224 | ); |
||
225 | } |
||
226 | |||
227 | 252 | if (is_null($model) || is_array($model)) |
|
228 | 234 | return data_get($model, $key); |
|
229 | |||
230 | 36 | return method_exists($model, 'getFormValue') |
|
231 | 6 | ? $model->getFormValue($key) |
|
232 | 36 | : data_get($model, $key); |
|
233 | } |
||
234 | |||
235 | /** |
||
236 | * Get a value from the session's old input. |
||
237 | * |
||
238 | * @param string $name |
||
239 | * |
||
240 | * @return mixed |
||
241 | */ |
||
242 | 462 | public function old(string $name) |
|
243 | { |
||
244 | 462 | $session = $this->getSessionStore(); |
|
245 | |||
246 | 462 | return is_null($session) ? null : $session->getOldInput(static::transformKey($name)); |
|
0 ignored issues
–
show
Since
transformKey() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self , or increase the visibility of transformKey() to at least protected.
Let’s assume you have a class which uses late-static binding: class YourClass
{
private static function getTemperature() {
return "3422 °C";
}
public static function getSomeVariable()
{
return static::getTemperature();
}
} The code above will run fine in your PHP runtime. However, if you now create a
sub-class and call the class YourSubClass extends YourClass {
private static function getTemperature() {
return "-182 °C";
}
}
print YourSubClass::getSomeVariable(); // Will cause an access error.
In the case above, it makes sense to update class YourClass
{
private static function getTemperature() {
return "3422 °C";
}
public static function getSomeVariable()
{
return self::getTemperature();
}
}
![]() |
|||
247 | } |
||
248 | |||
249 | /** |
||
250 | * Transform key from array to dot syntax. |
||
251 | * |
||
252 | * @param string $key |
||
253 | * |
||
254 | * @return string |
||
255 | */ |
||
256 | 462 | private static function transformKey(string $key): string |
|
257 | { |
||
258 | 462 | return str_replace( |
|
259 | 462 | ['.', '[]', '[', ']'], |
|
260 | 462 | ['_', '', '.', ''], |
|
261 | $key |
||
262 | ); |
||
263 | } |
||
264 | |||
265 | /** |
||
266 | * Determine if the old input is empty. |
||
267 | * |
||
268 | * @return bool |
||
269 | */ |
||
270 | 24 | public function oldInputIsEmpty(): bool |
|
271 | { |
||
272 | 24 | $session = $this->getSessionStore(); |
|
273 | |||
274 | 24 | return ! is_null($session) |
|
275 | 24 | && (count($session->getOldInput()) === 0); |
|
276 | } |
||
277 | |||
278 | /* ----------------------------------------------------------------- |
||
279 | | Main Methods |
||
280 | | ----------------------------------------------------------------- |
||
281 | */ |
||
282 | |||
283 | /** |
||
284 | * Open up a new HTML form. |
||
285 | * |
||
286 | * @param array $attributes |
||
287 | * |
||
288 | * @return \Illuminate\Support\HtmlString |
||
289 | */ |
||
290 | 84 | public function open(array $attributes = []): HtmlString |
|
291 | { |
||
292 | 84 | $method = Str::upper(Arr::pull($attributes, 'method', 'POST')); |
|
293 | |||
294 | 84 | return Form::make() |
|
295 | 84 | ->method($method !== 'GET' ? 'POST' : $method) |
|
296 | 84 | ->action($this->getAction($attributes)) |
|
297 | 84 | ->attributes(array_merge( |
|
0 ignored issues
–
show
array_merge(array('accep...utes, $this->reserved)) is of type array , but the function expects a object<Arcanedev\Html\Elements\Concerns\iterable> .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
298 | 84 | ['accept-charset' => 'UTF-8'], |
|
299 | 84 | Arr::except($attributes, $this->reserved) |
|
300 | )) |
||
301 | 84 | ->if(Arr::pull($attributes, 'files', false), function (Form $form) { |
|
302 | 6 | return $form->acceptsFiles(); |
|
303 | 84 | }) |
|
304 | 84 | ->if(in_array($method, $this->spoofedMethods), function (Form $form) use ($method) { |
|
305 | 6 | return $form->addChild($this->hidden('_method', $method)); |
|
306 | 84 | }) |
|
307 | 84 | ->if($method !== 'GET', function (Form $form) { |
|
308 | 48 | return $form->addChild($this->token()); |
|
309 | 84 | }) |
|
310 | 84 | ->open(); |
|
311 | } |
||
312 | |||
313 | /** |
||
314 | * Create a new model based form builder. |
||
315 | * |
||
316 | * @param mixed $model |
||
317 | * @param array $attributes |
||
318 | * |
||
319 | * @return \Illuminate\Support\HtmlString |
||
320 | */ |
||
321 | 30 | public function model($model, array $attributes = []): HtmlString |
|
322 | { |
||
323 | 30 | return $this->setModel($model)->open($attributes); |
|
324 | } |
||
325 | |||
326 | /** |
||
327 | * Close the current form. |
||
328 | * |
||
329 | * @return \Illuminate\Support\HtmlString |
||
330 | */ |
||
331 | 6 | public function close(): HtmlString |
|
332 | { |
||
333 | 6 | $this->labels = []; |
|
334 | 6 | $this->setModel(null); |
|
335 | |||
336 | 6 | return Form::make()->close(); |
|
337 | } |
||
338 | |||
339 | /** |
||
340 | * Generate a hidden field with the current CSRF token. |
||
341 | * |
||
342 | * @return \Arcanedev\Html\Elements\Input |
||
343 | */ |
||
344 | 48 | public function token(): Input |
|
345 | { |
||
346 | 48 | $token = empty($this->csrfToken) |
|
347 | ? $this->getSessionStore()->token() |
||
348 | 48 | : $this->csrfToken; |
|
349 | |||
350 | 48 | return $this->hidden('_token', $token); |
|
351 | } |
||
352 | |||
353 | /** |
||
354 | * Create a form label element. |
||
355 | * |
||
356 | * @param string $name |
||
357 | * @param string|mixed $value |
||
358 | * @param array $attributes |
||
359 | * @param bool $escaped |
||
360 | * |
||
361 | * @return \Arcanedev\Html\Elements\Label |
||
362 | */ |
||
363 | 30 | public function label(string $name, $value = null, array $attributes = [], $escaped = true): Label |
|
364 | { |
||
365 | 30 | $this->labels[] = $name; |
|
366 | |||
367 | 30 | $value = $value ?: Str::title(str_replace(['_', '-'], ' ', $name)); |
|
368 | |||
369 | 30 | return Label::make() |
|
370 | 30 | ->for($name) |
|
371 | 30 | ->attributes($attributes) |
|
0 ignored issues
–
show
$attributes is of type array , but the function expects a object<Arcanedev\Html\Elements\Concerns\iterable> .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
372 | 30 | ->html($escaped ? e($value) : $value); |
|
373 | } |
||
374 | |||
375 | /** |
||
376 | * Create a form input field. |
||
377 | * |
||
378 | * @param string $type |
||
379 | * @param string|null $name |
||
380 | * @param string|mixed $value |
||
381 | * @param array $attributes |
||
382 | * |
||
383 | * @return \Arcanedev\Html\Elements\Input |
||
384 | */ |
||
385 | 354 | public function input(string $type, $name, $value = null, array $attributes = []): Input |
|
386 | { |
||
387 | 354 | if ( ! in_array($type, $this->skipValueTypes)) |
|
388 | 300 | $value = $this->getValueAttribute($name, $value); |
|
389 | |||
390 | 354 | $id = $this->getIdAttribute($name, $attributes); |
|
391 | |||
392 | 354 | return Input::make() |
|
393 | 354 | ->type($type) |
|
394 | 354 | ->attributeIfNotNull($name, 'name', $name) |
|
395 | 354 | ->attributeIfNotNull($id, 'id', $id) |
|
396 | 354 | ->attributeUnless(is_null($value) || empty($value), 'value', $value) |
|
397 | 354 | ->attributes($attributes); |
|
398 | } |
||
399 | |||
400 | /** |
||
401 | * Create a text input field. |
||
402 | * |
||
403 | * @param string $name |
||
404 | * @param string|mixed $value |
||
405 | * @param array $attributes |
||
406 | * |
||
407 | * @return \Arcanedev\Html\Elements\Input |
||
408 | */ |
||
409 | 42 | public function text(string $name, $value = null, array $attributes = []): Input |
|
410 | { |
||
411 | 42 | return $this->input('text', $name, $value, $attributes); |
|
412 | } |
||
413 | |||
414 | /** |
||
415 | * Create a password input field. |
||
416 | * |
||
417 | * @param string $name |
||
418 | * @param array $attributes |
||
419 | * |
||
420 | * @return \Arcanedev\Html\Elements\Input |
||
421 | */ |
||
422 | 18 | public function password(string $name, array $attributes = []): Input |
|
423 | { |
||
424 | 18 | return $this->input('password', $name, null, $attributes); |
|
425 | } |
||
426 | |||
427 | /** |
||
428 | * Create a hidden input field. |
||
429 | * |
||
430 | * @param string $name |
||
431 | * @param string|mixed $value |
||
432 | * @param array $attributes |
||
433 | * |
||
434 | * @return \Arcanedev\Html\Elements\Input |
||
435 | */ |
||
436 | 66 | public function hidden(string $name, $value = null, array $attributes = []): Input |
|
437 | { |
||
438 | 66 | return $this->input('hidden', $name, $value, $attributes); |
|
439 | } |
||
440 | |||
441 | /** |
||
442 | * Create an e-mail input field. |
||
443 | * |
||
444 | * @param string $name |
||
445 | * @param string|mixed $value |
||
446 | * @param array $attributes |
||
447 | * |
||
448 | * @return \Arcanedev\Html\Elements\Input |
||
449 | */ |
||
450 | 18 | public function email(string $name, $value = null, array $attributes = []): Input |
|
451 | { |
||
452 | 18 | return $this->input('email', $name, $value, $attributes); |
|
453 | } |
||
454 | |||
455 | /** |
||
456 | * Create a tel input field. |
||
457 | * |
||
458 | * @param string $name |
||
459 | * @param string|mixed $value |
||
460 | * @param array $attributes |
||
461 | * |
||
462 | * @return \Arcanedev\Html\Elements\Input |
||
463 | */ |
||
464 | 18 | public function tel(string $name, $value = null, array $attributes = []): Input |
|
465 | { |
||
466 | 18 | return $this->input('tel', $name, $value, $attributes); |
|
467 | } |
||
468 | |||
469 | /** |
||
470 | * Create a number input field. |
||
471 | * |
||
472 | * @param string $name |
||
473 | * @param string|mixed $value |
||
474 | * @param array $attributes |
||
475 | * |
||
476 | * @return \Arcanedev\Html\Elements\Input |
||
477 | */ |
||
478 | 18 | public function number(string $name, $value = null, array $attributes = []): Input |
|
479 | { |
||
480 | 18 | return $this->input('number', $name, $value, $attributes); |
|
481 | } |
||
482 | |||
483 | /** |
||
484 | * Create a date input field. |
||
485 | * |
||
486 | * @param string $name |
||
487 | * @param string $value |
||
488 | * @param array $attributes |
||
489 | * |
||
490 | * @return \Arcanedev\Html\Elements\Input |
||
491 | */ |
||
492 | 24 | public function date(string $name, $value = null, array $attributes = []): Input |
|
493 | { |
||
494 | 24 | if ($value instanceof DateTime) |
|
495 | 6 | $value = $value->format('Y-m-d'); |
|
496 | |||
497 | 24 | return $this->input('date', $name, $value, $attributes); |
|
498 | } |
||
499 | |||
500 | /** |
||
501 | * Create a datetime input field. |
||
502 | * |
||
503 | * @param string $name |
||
504 | * @param string|mixed $value |
||
505 | * @param array $attributes |
||
506 | * |
||
507 | * @return \Arcanedev\Html\Elements\Input |
||
508 | */ |
||
509 | 24 | public function datetime(string $name, $value = null, array $attributes = []): Input |
|
510 | { |
||
511 | 24 | if ($value instanceof DateTime) |
|
512 | 12 | $value = $value->format(DateTime::RFC3339); |
|
513 | |||
514 | 24 | return $this->input('datetime', $name, $value, $attributes); |
|
515 | } |
||
516 | |||
517 | /** |
||
518 | * Create a datetime-local input field. |
||
519 | * |
||
520 | * @param string $name |
||
521 | * @param string|mixed $value |
||
522 | * @param array $attributes |
||
523 | * |
||
524 | * @return \Arcanedev\Html\Elements\Input |
||
525 | */ |
||
526 | 24 | public function datetimeLocal(string $name, $value = null, array $attributes = []): Input |
|
527 | { |
||
528 | 24 | if ($value instanceof DateTime) |
|
529 | 12 | $value = $value->format('Y-m-d\TH:i'); |
|
530 | |||
531 | 24 | return $this->input('datetime-local', $name, $value, $attributes); |
|
532 | } |
||
533 | |||
534 | /** |
||
535 | * Create a time input field. |
||
536 | * |
||
537 | * @param string $name |
||
538 | * @param string|mixed $value |
||
539 | * @param array $attributes |
||
540 | * |
||
541 | * @return \Arcanedev\Html\Elements\Input |
||
542 | */ |
||
543 | 18 | public function time(string $name, $value = null, array $attributes = []): Input |
|
544 | { |
||
545 | 18 | return $this->input('time', $name, $value, $attributes); |
|
546 | } |
||
547 | |||
548 | /** |
||
549 | * Create a url input field. |
||
550 | * |
||
551 | * @param string $name |
||
552 | * @param string $value |
||
553 | * @param array $attributes |
||
554 | * |
||
555 | * @return \Arcanedev\Html\Elements\Input |
||
556 | */ |
||
557 | 12 | public function url(string $name, $value = null, array $attributes = []): Input |
|
558 | { |
||
559 | 12 | return $this->input('url', $name, $value, $attributes); |
|
560 | } |
||
561 | |||
562 | /** |
||
563 | * Create a file input field. |
||
564 | * |
||
565 | * @param string $name |
||
566 | * @param array $attributes |
||
567 | * |
||
568 | * @return \Arcanedev\Html\Elements\File |
||
569 | */ |
||
570 | 18 | public function file(string $name, array $attributes = []): File |
|
571 | { |
||
572 | 18 | return File::make()->name($name)->attributes($attributes); |
|
0 ignored issues
–
show
$attributes is of type array , but the function expects a object<Arcanedev\Html\Elements\Concerns\iterable> .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
573 | } |
||
574 | |||
575 | /** |
||
576 | * Create a textarea input field. |
||
577 | * |
||
578 | * @param string $name |
||
579 | * @param string $value |
||
580 | * @param array $attributes |
||
581 | * |
||
582 | * @return \Arcanedev\Html\Elements\Textarea |
||
583 | */ |
||
584 | 36 | public function textarea(string $name, $value = null, array $attributes = []): Textarea |
|
585 | { |
||
586 | 36 | $id = $this->getIdAttribute($name, $attributes); |
|
587 | 36 | $size = Arr::pull($attributes, 'size'); |
|
588 | 36 | $value = (string) $this->getValueAttribute($name, $value); |
|
589 | |||
590 | 36 | return Textarea::make() |
|
591 | 36 | ->name($name) |
|
592 | 36 | ->attributeUnless(is_null($id), 'id', $id) |
|
593 | 36 | ->unless(is_null($size), function (Textarea $elt) use ($size) { |
|
594 | 18 | return $elt->size($size); |
|
595 | 36 | }) |
|
596 | 36 | ->attributes($attributes) |
|
597 | 36 | ->html($this->html->escape($value)); |
|
598 | } |
||
599 | |||
600 | /** |
||
601 | * Create a select box field. |
||
602 | * |
||
603 | * @param string $name |
||
604 | * @param array|\Illuminate\Support\Collection|iterable $list |
||
605 | * @param string|bool $selected |
||
606 | * @param array $attributes |
||
607 | * @param array $optionsAttributes |
||
608 | * @param array $optgroupsAttributes |
||
609 | * |
||
610 | * @return \Arcanedev\Html\Elements\Select |
||
611 | */ |
||
612 | 90 | public function select( |
|
613 | string $name, |
||
614 | iterable $list = [], |
||
615 | $selected = null, |
||
616 | array $attributes = [], |
||
617 | array $optionsAttributes = [], |
||
618 | array $optgroupsAttributes = [] |
||
619 | ): Select { |
||
620 | 90 | return Select::make() |
|
621 | 90 | ->name($name) |
|
622 | 90 | ->options($list, $optionsAttributes, $optgroupsAttributes) |
|
0 ignored issues
–
show
It seems like
$list defined by parameter $list on line 614 can also be of type array ; however, Arcanedev\Html\Elements\Select::options() does only seem to accept object<Arcanedev\Html\Elements\iterable> , maybe add an additional type check?
This check looks at variables that have been passed in as parameters and are passed out again to other methods. If the outgoing method call has stricter type requirements than the method itself, an issue is raised. An additional type check may prevent trouble. ![]() |
|||
623 | 90 | ->attributes($attributes) |
|
0 ignored issues
–
show
$attributes is of type array , but the function expects a object<Arcanedev\Html\Elements\Concerns\iterable> .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
624 | 90 | ->attributeUnless(is_null($id = $this->getIdAttribute($name, $attributes)), 'id', $id) |
|
625 | 90 | ->value($this->getValueAttribute($name, $selected)); |
|
626 | } |
||
627 | |||
628 | /** |
||
629 | * Create a select range field. |
||
630 | * |
||
631 | * @param string $name |
||
632 | * @param string $begin |
||
633 | * @param string $end |
||
634 | * @param string $selected |
||
635 | * @param array $attributes |
||
636 | * |
||
637 | * @return \Arcanedev\Html\Elements\Select |
||
638 | */ |
||
639 | 12 | public function selectRange(string $name, $begin, $end, $selected = null, array $attributes = []): Select |
|
640 | { |
||
641 | 12 | $range = array_combine($range = range($begin, $end), $range); |
|
642 | |||
643 | 12 | return $this->select($name, $range, $selected, $attributes); |
|
644 | } |
||
645 | |||
646 | /** |
||
647 | * Create a select year field. |
||
648 | * |
||
649 | * @param string $name |
||
650 | * @param string $begin |
||
651 | * @param string $end |
||
652 | * @param string $selected |
||
653 | * @param array $attributes |
||
654 | * |
||
655 | * @return \Arcanedev\Html\Elements\Select |
||
656 | */ |
||
657 | 6 | public function selectYear(string $name, $begin, $end, $selected = null, array $attributes = []): Select |
|
658 | { |
||
659 | 6 | return $this->selectRange($name, $begin, $end, $selected, $attributes); |
|
660 | } |
||
661 | |||
662 | /** |
||
663 | * Create a select month field. |
||
664 | * |
||
665 | * @param string $name |
||
666 | * @param string $selected |
||
667 | * @param array $attributes |
||
668 | * @param string $format |
||
669 | * |
||
670 | * @return \Arcanedev\Html\Elements\Select |
||
671 | */ |
||
672 | 6 | public function selectMonth(string $name, $selected = null, array $attributes = [], $format = '%B'): Select |
|
673 | { |
||
674 | 6 | $months = []; |
|
675 | |||
676 | 6 | foreach(range(1, 12) as $month) { |
|
677 | 6 | $months[$month] = strftime($format, mktime(0, 0, 0, $month, 1)); |
|
678 | } |
||
679 | |||
680 | 6 | return $this->select($name, $months, $selected, $attributes); |
|
681 | } |
||
682 | |||
683 | /** |
||
684 | * Create a checkbox input field. |
||
685 | * |
||
686 | * @param string $name |
||
687 | * @param mixed $value |
||
688 | * @param bool|null $checked |
||
689 | * @param array $attributes |
||
690 | * |
||
691 | * @return \Arcanedev\Html\Elements\Input |
||
692 | */ |
||
693 | 24 | public function checkbox(string $name, $value = 1, $checked = null, array $attributes = []): Input |
|
694 | { |
||
695 | 24 | return $this->checkable('checkbox', $name, $value, $checked, $attributes); |
|
696 | } |
||
697 | |||
698 | /** |
||
699 | * Create a radio button input field. |
||
700 | * |
||
701 | * @param string $name |
||
702 | * @param mixed $value |
||
703 | * @param bool $checked |
||
704 | * @param array $attributes |
||
705 | * |
||
706 | * @return \Arcanedev\Html\Elements\Input |
||
707 | */ |
||
708 | 12 | public function radio(string $name, $value = null, $checked = null, array $attributes = []): Input |
|
709 | { |
||
710 | 12 | return $this->checkable('radio', $name, $value ?: $name, $checked, $attributes); |
|
711 | } |
||
712 | |||
713 | /** |
||
714 | * Create a HTML reset input element. |
||
715 | * |
||
716 | * @param string|mixed $value |
||
717 | * @param array $attributes |
||
718 | * |
||
719 | * @return \Arcanedev\Html\Elements\Button |
||
720 | */ |
||
721 | 6 | public function reset($value, array $attributes = []): Button |
|
722 | { |
||
723 | 6 | return $this->button($value, array_merge(['type' => 'reset'], $attributes)); |
|
724 | } |
||
725 | |||
726 | /** |
||
727 | * Create a HTML image input element. |
||
728 | * |
||
729 | * @param string $url |
||
730 | * @param string|null $name |
||
731 | * @param array $attributes |
||
732 | * |
||
733 | * @return \Arcanedev\Html\Elements\Input |
||
734 | */ |
||
735 | 6 | public function image(string $url, $name = null, array $attributes = []): Input |
|
736 | { |
||
737 | 6 | return $this->input('image', $name, null, array_merge($attributes, [ |
|
738 | 6 | 'src' => $this->url->asset($url), |
|
739 | ])); |
||
740 | } |
||
741 | |||
742 | /** |
||
743 | * Create a submit button element. |
||
744 | * |
||
745 | * @param string|mixed $value |
||
746 | * @param array $attributes |
||
747 | * |
||
748 | * @return \Arcanedev\Html\Elements\Button |
||
749 | */ |
||
750 | 6 | public function submit($value = null, array $attributes = []): Button |
|
751 | { |
||
752 | 6 | return $this->button($value, array_merge(['type' => 'submit'], $attributes)); |
|
753 | } |
||
754 | |||
755 | /** |
||
756 | * Create a button element. |
||
757 | * |
||
758 | * @param string|mixed $value |
||
759 | * @param array $attributes |
||
760 | * |
||
761 | * @return \Arcanedev\Html\Elements\Button |
||
762 | */ |
||
763 | 18 | public function button($value = null, array $attributes = []): Button |
|
764 | { |
||
765 | 18 | return Button::make() |
|
766 | 18 | ->type(Arr::pull($attributes, 'type', 'button')) |
|
767 | 18 | ->attributes($attributes) |
|
0 ignored issues
–
show
$attributes is of type array , but the function expects a object<Arcanedev\Html\Elements\Concerns\iterable> .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
768 | 18 | ->html($value); |
|
769 | } |
||
770 | |||
771 | /** |
||
772 | * Create a color input field. |
||
773 | * |
||
774 | * @param string $name |
||
775 | * @param string|mixed $value |
||
776 | * @param array $attributes |
||
777 | * |
||
778 | * @return \Arcanedev\Html\Elements\Input |
||
779 | */ |
||
780 | 18 | public function color(string $name, $value = null, array $attributes = []): Input |
|
781 | { |
||
782 | 18 | return $this->input('color', $name, $value, $attributes); |
|
783 | } |
||
784 | |||
785 | /* ----------------------------------------------------------------- |
||
786 | | Other Methods |
||
787 | | ----------------------------------------------------------------- |
||
788 | */ |
||
789 | |||
790 | /** |
||
791 | * Create a checkable input field. |
||
792 | * |
||
793 | * @param string $type |
||
794 | * @param string $name |
||
795 | * @param mixed $value |
||
796 | * @param bool|null $checked |
||
797 | * @param array $attributes |
||
798 | * |
||
799 | * @return \Arcanedev\Html\Elements\Input |
||
800 | */ |
||
801 | 42 | protected function checkable(string $type, string $name, $value, $checked, array $attributes): Input |
|
802 | { |
||
803 | 42 | $checked = $this->getCheckedState($type, $name, $value, $checked); |
|
804 | |||
805 | 42 | if ( ! is_null($checked) && $checked) |
|
806 | 36 | $attributes['checked'] = 'checked'; |
|
807 | |||
808 | 42 | return $this->input($type, $name, $value, $attributes); |
|
809 | } |
||
810 | |||
811 | /** |
||
812 | * Get the check state for a checkable input. |
||
813 | * |
||
814 | * @param string $type |
||
815 | * @param string $name |
||
816 | * @param mixed $value |
||
817 | * @param bool|null $checked |
||
818 | * |
||
819 | * @return bool |
||
820 | */ |
||
821 | 42 | private function getCheckedState(string $type, string $name, $value, $checked): bool |
|
822 | { |
||
823 | 42 | switch($type) { |
|
824 | 42 | case 'checkbox': |
|
825 | 24 | return $this->getCheckboxCheckedState($name, $value, $checked); |
|
826 | |||
827 | 18 | case 'radio': |
|
828 | 12 | return $this->getRadioCheckedState($name, $value, $checked); |
|
829 | |||
830 | default: |
||
831 | 6 | return $this->getValueAttribute($name) === $value; |
|
832 | } |
||
833 | } |
||
834 | |||
835 | /** |
||
836 | * Get the check state for a checkbox input. |
||
837 | * |
||
838 | * @param string $name |
||
839 | * @param mixed $value |
||
840 | * @param bool|null $checked |
||
841 | * |
||
842 | * @return bool |
||
843 | */ |
||
844 | 24 | private function getCheckboxCheckedState(string $name, $value, $checked): bool |
|
845 | { |
||
846 | if ( |
||
847 | 24 | isset($this->session) && |
|
848 | 24 | ! $this->oldInputIsEmpty() && |
|
849 | 24 | is_null($this->old($name)) |
|
850 | ) { |
||
851 | 6 | return false; |
|
852 | } |
||
853 | |||
854 | 24 | if ($this->missingOldAndModel($name)) { |
|
855 | 12 | return (bool) $checked; |
|
856 | } |
||
857 | |||
858 | 12 | $posted = $this->getValueAttribute($name, $checked); |
|
859 | |||
860 | 12 | if (is_array($posted)) { |
|
861 | 6 | return in_array($value, $posted); |
|
862 | } |
||
863 | |||
864 | 12 | if ($posted instanceof Collection) { |
|
865 | 6 | return $posted->contains('id', $value); |
|
866 | } |
||
867 | |||
868 | 12 | return (bool) $posted; |
|
869 | } |
||
870 | |||
871 | /** |
||
872 | * Get the check state for a radio input. |
||
873 | * |
||
874 | * @param string $name |
||
875 | * @param mixed $value |
||
876 | * @param bool|null $checked |
||
877 | * |
||
878 | * @return bool |
||
879 | */ |
||
880 | 12 | private function getRadioCheckedState(string $name, $value, $checked): bool |
|
881 | { |
||
882 | 12 | if ($this->missingOldAndModel($name)) { |
|
883 | 6 | return (bool) $checked; |
|
884 | } |
||
885 | |||
886 | 6 | return $this->getValueAttribute($name) === $value; |
|
887 | } |
||
888 | |||
889 | /** |
||
890 | * Determine if old input or model input exists for a key. |
||
891 | * |
||
892 | * @param string $name |
||
893 | * |
||
894 | * @return bool |
||
895 | */ |
||
896 | 36 | private function missingOldAndModel(string $name): bool |
|
897 | { |
||
898 | 36 | return is_null($this->old($name)) |
|
899 | 36 | && is_null($this->getModelValueAttribute($name)); |
|
900 | } |
||
901 | |||
902 | /** |
||
903 | * Get the form action from the options. |
||
904 | * |
||
905 | * @param array $attributes |
||
906 | * |
||
907 | * @return string |
||
908 | */ |
||
909 | 84 | private function getAction(array $attributes): string |
|
910 | { |
||
911 | 84 | if (isset($attributes['url'])) |
|
912 | 6 | return $this->getUrlAction($attributes['url']); |
|
913 | |||
914 | 78 | if (isset($attributes['route'])) |
|
915 | 12 | return $this->getRouteAction($attributes['route']); |
|
916 | |||
917 | 72 | if (isset($attributes['action'])) |
|
918 | 12 | return $this->getControllerAction($attributes['action']); |
|
919 | |||
920 | 60 | return $this->url->current(); |
|
921 | } |
||
922 | |||
923 | /** |
||
924 | * Get the action for a "url" option. |
||
925 | * |
||
926 | * @param array|string $attribute |
||
927 | * |
||
928 | * @return string |
||
929 | */ |
||
930 | 6 | private function getUrlAction($attribute): string |
|
931 | { |
||
932 | 6 | return is_array($attribute) |
|
933 | 6 | ? $this->url->to($attribute[0], array_slice($attribute, 1)) |
|
934 | 6 | : $this->url->to($attribute); |
|
935 | } |
||
936 | |||
937 | /** |
||
938 | * Get the action for a "route" option. |
||
939 | * |
||
940 | * @param array|string $attribute |
||
941 | * |
||
942 | * @return string |
||
943 | */ |
||
944 | 12 | private function getRouteAction($attribute): string |
|
945 | { |
||
946 | 12 | return is_array($attribute) |
|
947 | 6 | ? $this->url->route($attribute[0], array_slice($attribute, 1)) |
|
948 | 12 | : $this->url->route($attribute); |
|
949 | } |
||
950 | |||
951 | /** |
||
952 | * Get the action for an "action" option. |
||
953 | * |
||
954 | * @param array|string $attribute |
||
955 | * |
||
956 | * @return string |
||
957 | */ |
||
958 | 12 | private function getControllerAction($attribute): string |
|
959 | { |
||
960 | 12 | return is_array($attribute) |
|
961 | 6 | ? $this->url->action($attribute[0], array_slice($attribute, 1)) |
|
962 | 12 | : $this->url->action($attribute); |
|
963 | } |
||
964 | } |
||
965 |
Let’s assume you have a class which uses late-static binding:
}
The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the
getSomeVariable()
on that sub-class, you will receive a runtime error:In the case above, it makes sense to update
SomeClass
to useself
instead: