Complex classes like FormBuilder often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use FormBuilder, and based on these observations, apply Extract Interface, too.
1 | <?php namespace Arcanedev\LaravelHtml; |
||
17 | class FormBuilder extends Builder implements FormBuilderContract |
||
18 | { |
||
19 | /* ----------------------------------------------------------------- |
||
20 | | Properties |
||
21 | | ----------------------------------------------------------------- |
||
22 | */ |
||
23 | |||
24 | /** |
||
25 | * The HTML builder instance. |
||
26 | * |
||
27 | * @var \Arcanedev\LaravelHtml\Contracts\HtmlBuilder |
||
28 | */ |
||
29 | protected $html; |
||
30 | |||
31 | /** |
||
32 | * The URL generator instance. |
||
33 | * |
||
34 | * @var \Illuminate\Contracts\Routing\UrlGenerator |
||
35 | */ |
||
36 | protected $url; |
||
37 | |||
38 | /** |
||
39 | * The CSRF token used by the form builder. |
||
40 | * |
||
41 | * @var string |
||
42 | */ |
||
43 | protected $csrfToken; |
||
44 | |||
45 | /** |
||
46 | * The session store implementation. |
||
47 | * |
||
48 | * @var \Illuminate\Contracts\Session\Session |
||
49 | */ |
||
50 | protected $session; |
||
51 | |||
52 | /** |
||
53 | * The current model instance for the form. |
||
54 | * |
||
55 | * @var \Illuminate\Database\Eloquent\Model |
||
56 | */ |
||
57 | protected $model; |
||
58 | |||
59 | /** |
||
60 | * An array of label names we've created. |
||
61 | * |
||
62 | * @var array |
||
63 | */ |
||
64 | protected $labels = []; |
||
65 | |||
66 | /** |
||
67 | * The reserved form open attributes. |
||
68 | * |
||
69 | * @var array |
||
70 | */ |
||
71 | protected $reserved = ['method', 'url', 'route', 'action', 'files']; |
||
72 | |||
73 | /** |
||
74 | * The form methods that should be spoofed, in uppercase. |
||
75 | * |
||
76 | * @var array |
||
77 | */ |
||
78 | protected $spoofedMethods = ['DELETE', 'PATCH', 'PUT']; |
||
79 | |||
80 | /** |
||
81 | * The types of inputs to not fill values on by default. |
||
82 | * |
||
83 | * @var array |
||
84 | */ |
||
85 | protected $skipValueTypes = ['file', 'password', 'checkbox', 'radio']; |
||
86 | |||
87 | /* ----------------------------------------------------------------- |
||
88 | | Constructor |
||
89 | | ----------------------------------------------------------------- |
||
90 | */ |
||
91 | |||
92 | /** |
||
93 | * Create a new form builder instance. |
||
94 | * |
||
95 | * @param \Arcanedev\LaravelHtml\Contracts\HtmlBuilder $html |
||
96 | * @param \Illuminate\Contracts\Routing\UrlGenerator $url |
||
97 | * @param \Illuminate\Contracts\Session\Session $session |
||
98 | */ |
||
99 | 404 | public function __construct( |
|
100 | Contracts\HtmlBuilder $html, |
||
101 | UrlGenerator $url, |
||
102 | Session $session |
||
103 | ) { |
||
104 | 404 | $this->url = $url; |
|
105 | 404 | $this->html = $html; |
|
106 | 404 | $this->csrfToken = $session->token(); |
|
107 | |||
108 | 404 | $this->setSessionStore($session); |
|
109 | 404 | } |
|
110 | |||
111 | /* ----------------------------------------------------------------- |
||
112 | | Getters & Setters |
||
113 | | ----------------------------------------------------------------- |
||
114 | */ |
||
115 | |||
116 | /** |
||
117 | * Get the session store implementation. |
||
118 | * |
||
119 | * @return \Illuminate\Contracts\Session\Session |
||
120 | */ |
||
121 | 4 | public function getSessionStore() |
|
122 | { |
||
123 | 4 | return $this->session; |
|
124 | } |
||
125 | |||
126 | /** |
||
127 | * Set the session store implementation. |
||
128 | * |
||
129 | * @param \Illuminate\Contracts\Session\Session $session |
||
130 | * |
||
131 | * @return self |
||
132 | */ |
||
133 | 404 | public function setSessionStore(Session $session) |
|
134 | { |
||
135 | 404 | $this->session = $session; |
|
136 | |||
137 | 404 | return $this; |
|
138 | } |
||
139 | |||
140 | /** |
||
141 | * Set the model instance on the form builder. |
||
142 | * |
||
143 | * @param \Illuminate\Database\Eloquent\Model $model |
||
144 | * |
||
145 | * @return self |
||
146 | */ |
||
147 | 44 | public function setModel($model) |
|
148 | { |
||
149 | 44 | $this->model = $model; |
|
150 | |||
151 | 44 | return $this; |
|
152 | } |
||
153 | |||
154 | /** |
||
155 | * Get the ID attribute for a field name. |
||
156 | * |
||
157 | * @param string $name |
||
158 | * @param array $attributes |
||
159 | * |
||
160 | * @return string |
||
161 | */ |
||
162 | 332 | public function getIdAttribute($name, array $attributes) |
|
163 | { |
||
164 | 332 | if (array_key_exists('id', $attributes)) |
|
165 | 28 | return $attributes['id']; |
|
166 | |||
167 | 312 | if (in_array($name, $this->labels)) |
|
168 | 8 | return $name; |
|
169 | |||
170 | 304 | return null; |
|
171 | } |
||
172 | |||
173 | /** |
||
174 | * Get the value that should be assigned to the field. |
||
175 | * |
||
176 | * @param string $name |
||
177 | * @param mixed $value |
||
178 | * |
||
179 | * @return mixed |
||
180 | */ |
||
181 | 296 | public function getValueAttribute($name, $value = null) |
|
182 | { |
||
183 | 296 | if (is_null($name)) |
|
184 | 12 | return $value; |
|
185 | |||
186 | 284 | if ( ! is_null($this->old($name)) && $name !== '_method') |
|
187 | 16 | return $this->old($name); |
|
188 | |||
189 | 276 | if ( ! is_null($value)) |
|
190 | 156 | return $value; |
|
191 | |||
192 | 160 | return isset($this->model) |
|
193 | 20 | ? $this->getModelValueAttribute($name) |
|
194 | 160 | : null; |
|
195 | } |
||
196 | |||
197 | /** |
||
198 | * Get the model value that should be assigned to the field. |
||
199 | * |
||
200 | * @param string $name |
||
201 | * |
||
202 | * @return mixed |
||
203 | */ |
||
204 | 32 | private function getModelValueAttribute($name) |
|
205 | { |
||
206 | 32 | $key = $this->transformKey($name); |
|
207 | |||
208 | 32 | return method_exists($this->model, 'getFormValue') |
|
209 | ? $this->model->getFormValue($key) |
||
210 | 32 | : data_get($this->model, $key); |
|
211 | } |
||
212 | |||
213 | /** |
||
214 | * Get a value from the session's old input. |
||
215 | * |
||
216 | * @param string $name |
||
217 | * |
||
218 | * @return mixed |
||
219 | */ |
||
220 | 296 | public function old($name) |
|
221 | { |
||
222 | 296 | return isset($this->session) |
|
223 | 296 | ? $this->session->getOldInput($this->transformKey($name)) |
|
|
|||
224 | 296 | : null; |
|
225 | } |
||
226 | |||
227 | /** |
||
228 | * Transform key from array to dot syntax. |
||
229 | * |
||
230 | * @param string $key |
||
231 | * |
||
232 | * @return string |
||
233 | */ |
||
234 | 296 | private function transformKey($key) |
|
235 | { |
||
236 | 296 | return str_replace(['.', '[]', '[', ']'], ['_', '', '.', ''], $key); |
|
237 | } |
||
238 | |||
239 | /** |
||
240 | * Determine if the old input is empty. |
||
241 | * |
||
242 | * @return bool |
||
243 | */ |
||
244 | 16 | public function oldInputIsEmpty() |
|
245 | { |
||
246 | 16 | return isset($this->session) && (count($this->session->getOldInput()) == 0); |
|
247 | } |
||
248 | |||
249 | /** |
||
250 | * Parse the form action method. |
||
251 | * |
||
252 | * @param string $method |
||
253 | * |
||
254 | * @return string |
||
255 | */ |
||
256 | 64 | private function getMethod($method) |
|
257 | { |
||
258 | 64 | $method = strtoupper($method); |
|
259 | |||
260 | 64 | return $method !== 'GET' ? 'POST' : $method; |
|
261 | } |
||
262 | |||
263 | /* ----------------------------------------------------------------- |
||
264 | | Main Methods |
||
265 | | ----------------------------------------------------------------- |
||
266 | */ |
||
267 | |||
268 | /** |
||
269 | * Open up a new HTML form. |
||
270 | * |
||
271 | * @param array $options |
||
272 | * |
||
273 | * @return \Illuminate\Support\HtmlString |
||
274 | */ |
||
275 | 64 | public function open(array $options = []) |
|
276 | { |
||
277 | 64 | $method = Arr::get($options, 'method', 'post'); |
|
278 | |||
279 | // We need to extract the proper method from the attributes. If the method is |
||
280 | // something other than GET or POST we'll use POST since we will spoof the |
||
281 | // actual method since forms don't support the reserved methods in HTML. |
||
282 | 64 | $attributes = []; |
|
283 | 64 | $attributes['method'] = $this->getMethod($method); |
|
284 | 64 | $attributes['action'] = $this->getAction($options); |
|
285 | 64 | $attributes['accept-charset'] = 'UTF-8'; |
|
286 | |||
287 | 64 | if (isset($options['files']) && $options['files']) { |
|
288 | 8 | $options['enctype'] = 'multipart/form-data'; |
|
289 | } |
||
290 | |||
291 | // Finally we're ready to create the final form HTML field. We will attribute |
||
292 | // format the array of attributes. We will also add on the appendage which |
||
293 | // is used to spoof requests for this PUT, PATCH, etc. methods on forms. |
||
294 | 64 | $attributes = array_merge( |
|
295 | 64 | $attributes, array_except($options, $this->reserved) |
|
296 | ); |
||
297 | |||
298 | // Finally, we will concatenate all of the attributes into a single string so |
||
299 | // we can build out the final form open statement. We'll also append on an |
||
300 | // extra value for the hidden _method field if it's needed for the form. |
||
301 | 64 | $attributes = $this->html->attributes($attributes); |
|
302 | |||
303 | // If the method is PUT, PATCH or DELETE we will need to add a spoofer hidden |
||
304 | // field that will instruct the Symfony request to pretend the method is a |
||
305 | // different method than it actually is, for convenience from the forms. |
||
306 | 64 | $append = $this->getAppendage($method); |
|
307 | |||
308 | 64 | return $this->toHtmlString('<form' . $attributes . '>' . $append); |
|
309 | } |
||
310 | |||
311 | /** |
||
312 | * Create a new model based form builder. |
||
313 | * |
||
314 | * @param mixed $model |
||
315 | * @param array $options |
||
316 | * |
||
317 | * @return \Illuminate\Support\HtmlString |
||
318 | */ |
||
319 | 20 | public function model($model, array $options = []) |
|
320 | { |
||
321 | 20 | $this->setModel($model); |
|
322 | |||
323 | 20 | return $this->open($options); |
|
324 | } |
||
325 | |||
326 | /** |
||
327 | * Close the current form. |
||
328 | * |
||
329 | * @return \Illuminate\Support\HtmlString |
||
330 | */ |
||
331 | 8 | public function close() |
|
332 | { |
||
333 | 8 | $this->labels = []; |
|
334 | 8 | $this->setModel(null); |
|
335 | |||
336 | 8 | return $this->toHtmlString('</form>'); |
|
337 | } |
||
338 | |||
339 | /** |
||
340 | * Generate a hidden field with the current CSRF token. |
||
341 | * |
||
342 | * @return \Illuminate\Support\HtmlString |
||
343 | */ |
||
344 | 28 | public function token() |
|
345 | { |
||
346 | 28 | $token = ! empty($this->csrfToken) |
|
347 | 20 | ? $this->csrfToken |
|
348 | 28 | : $this->session->token(); |
|
349 | |||
350 | 28 | return $this->hidden('_token', $token); |
|
351 | } |
||
352 | |||
353 | /** |
||
354 | * Create a form label element. |
||
355 | * |
||
356 | * @param string $name |
||
357 | * @param string $value |
||
358 | * @param array $options |
||
359 | * @param bool $escaped |
||
360 | * |
||
361 | * @return \Illuminate\Support\HtmlString |
||
362 | */ |
||
363 | 20 | public function label($name, $value = null, array $options = [], $escaped = true) |
|
364 | { |
||
365 | 20 | $this->labels[] = $name; |
|
366 | |||
367 | 20 | return $this->toHtmlString( |
|
368 | 20 | Helpers\Label::make($name, $value, $options, $escaped) |
|
369 | ); |
||
370 | } |
||
371 | |||
372 | /** |
||
373 | * Create a form input field. |
||
374 | * |
||
375 | * @param string $type |
||
376 | * @param string $name |
||
377 | * @param string $value |
||
378 | * @param array $options |
||
379 | * |
||
380 | * @return \Illuminate\Support\HtmlString |
||
381 | */ |
||
382 | 252 | public function input($type, $name, $value = null, array $options = []) |
|
383 | { |
||
384 | 252 | if ( ! isset($options['name'])) { |
|
385 | 252 | $options['name'] = $name; |
|
386 | } |
||
387 | |||
388 | // We will get the appropriate value for the given field. We will look for the |
||
389 | // value in the session for the value in the old input data then we'll look |
||
390 | // in the model instance if one is set. Otherwise we will just use empty. |
||
391 | 252 | $id = $this->getIdAttribute($name, $options); |
|
392 | |||
393 | 252 | if ( ! in_array($type, $this->skipValueTypes)) { |
|
394 | 204 | $value = $this->getValueAttribute($name, $value); |
|
395 | } |
||
396 | |||
397 | // Once we have the type, value, and ID we can merge them into the rest of the |
||
398 | // attributes array so we can convert them into their HTML attribute format |
||
399 | // when creating the HTML element. Then, we will return the entire input. |
||
400 | 252 | $options = array_merge($options, compact('type', 'value', 'id')); |
|
401 | |||
402 | 252 | return $this->toHtmlString('<input' . $this->html->attributes($options) . '>'); |
|
403 | } |
||
404 | |||
405 | /** |
||
406 | * Create a text input field. |
||
407 | * |
||
408 | * @param string $name |
||
409 | * @param string $value |
||
410 | * @param array $options |
||
411 | * |
||
412 | * @return \Illuminate\Support\HtmlString |
||
413 | */ |
||
414 | 28 | public function text($name, $value = null, array $options = []) |
|
415 | { |
||
416 | 28 | return $this->input('text', $name, $value, $options); |
|
417 | } |
||
418 | |||
419 | /** |
||
420 | * Create a password input field. |
||
421 | * |
||
422 | * @param string $name |
||
423 | * @param array $options |
||
424 | * |
||
425 | * @return \Illuminate\Support\HtmlString |
||
426 | */ |
||
427 | 12 | public function password($name, array $options = []) |
|
428 | { |
||
429 | 12 | return $this->input('password', $name, '', $options); |
|
430 | } |
||
431 | |||
432 | /** |
||
433 | * Create a hidden input field. |
||
434 | * |
||
435 | * @param string $name |
||
436 | * @param string $value |
||
437 | * @param array $options |
||
438 | * |
||
439 | * @return \Illuminate\Support\HtmlString |
||
440 | */ |
||
441 | 40 | public function hidden($name, $value = null, array $options = []) |
|
442 | { |
||
443 | 40 | return $this->input('hidden', $name, $value, $options); |
|
444 | } |
||
445 | |||
446 | /** |
||
447 | * Create an e-mail input field. |
||
448 | * |
||
449 | * @param string $name |
||
450 | * @param string $value |
||
451 | * @param array $options |
||
452 | * |
||
453 | * @return \Illuminate\Support\HtmlString |
||
454 | */ |
||
455 | 12 | public function email($name, $value = null, array $options = []) |
|
456 | { |
||
457 | 12 | return $this->input('email', $name, $value, $options); |
|
458 | } |
||
459 | |||
460 | /** |
||
461 | * Create a tel input field. |
||
462 | * |
||
463 | * @param string $name |
||
464 | * @param string $value |
||
465 | * @param array $options |
||
466 | * |
||
467 | * @return \Illuminate\Support\HtmlString |
||
468 | */ |
||
469 | 12 | public function tel($name, $value = null, array $options = []) |
|
470 | { |
||
471 | 12 | return $this->input('tel', $name, $value, $options); |
|
472 | } |
||
473 | |||
474 | /** |
||
475 | * Create a number input field. |
||
476 | * |
||
477 | * @param string $name |
||
478 | * @param string $value |
||
479 | * @param array $options |
||
480 | * |
||
481 | * @return \Illuminate\Support\HtmlString |
||
482 | */ |
||
483 | 12 | public function number($name, $value = null, array $options = []) |
|
484 | { |
||
485 | 12 | return $this->input('number', $name, $value, $options); |
|
486 | } |
||
487 | |||
488 | /** |
||
489 | * Create a date input field. |
||
490 | * |
||
491 | * @param string $name |
||
492 | * @param string $value |
||
493 | * @param array $options |
||
494 | * |
||
495 | * @return \Illuminate\Support\HtmlString |
||
496 | */ |
||
497 | 16 | public function date($name, $value = null, array $options = []) |
|
498 | { |
||
499 | 16 | if ($value instanceof DateTime) { |
|
500 | 4 | $value = $value->format('Y-m-d'); |
|
501 | } |
||
502 | |||
503 | 16 | return $this->input('date', $name, $value, $options); |
|
504 | } |
||
505 | |||
506 | /** |
||
507 | * Create a datetime input field. |
||
508 | * |
||
509 | * @param string $name |
||
510 | * @param string $value |
||
511 | * @param array $options |
||
512 | * |
||
513 | * @return \Illuminate\Support\HtmlString |
||
514 | */ |
||
515 | 16 | public function datetime($name, $value = null, array $options = []) |
|
516 | { |
||
517 | 16 | if ($value instanceof DateTime) { |
|
518 | 8 | $value = $value->format(DateTime::RFC3339); |
|
519 | } |
||
520 | |||
521 | 16 | return $this->input('datetime', $name, $value, $options); |
|
522 | } |
||
523 | |||
524 | /** |
||
525 | * Create a datetime-local input field. |
||
526 | * |
||
527 | * @param string $name |
||
528 | * @param string $value |
||
529 | * @param array $options |
||
530 | * |
||
531 | * @return \Illuminate\Support\HtmlString |
||
532 | */ |
||
533 | 16 | public function datetimeLocal($name, $value = null, array $options = []) |
|
534 | { |
||
535 | 16 | if ($value instanceof DateTime) { |
|
536 | 8 | $value = $value->format('Y-m-d\TH:i'); |
|
537 | } |
||
538 | |||
539 | 16 | return $this->input('datetime-local', $name, $value, $options); |
|
540 | } |
||
541 | |||
542 | /** |
||
543 | * Create a time input field. |
||
544 | * |
||
545 | * @param string $name |
||
546 | * @param string $value |
||
547 | * @param array $options |
||
548 | * |
||
549 | * @return \Illuminate\Support\HtmlString |
||
550 | */ |
||
551 | 12 | public function time($name, $value = null, array $options = []) |
|
552 | { |
||
553 | 12 | return $this->input('time', $name, $value, $options); |
|
554 | } |
||
555 | |||
556 | /** |
||
557 | * Create a url input field. |
||
558 | * |
||
559 | * @param string $name |
||
560 | * @param string $value |
||
561 | * @param array $options |
||
562 | * |
||
563 | * @return \Illuminate\Support\HtmlString |
||
564 | */ |
||
565 | 8 | public function url($name, $value = null, array $options = []) |
|
566 | { |
||
567 | 8 | return $this->input('url', $name, $value, $options); |
|
568 | } |
||
569 | |||
570 | /** |
||
571 | * Create a file input field. |
||
572 | * |
||
573 | * @param string $name |
||
574 | * @param array $options |
||
575 | * |
||
576 | * @return \Illuminate\Support\HtmlString |
||
577 | */ |
||
578 | 12 | public function file($name, array $options = []) |
|
579 | { |
||
580 | 12 | return $this->input('file', $name, null, $options); |
|
581 | } |
||
582 | |||
583 | /** |
||
584 | * Create a textarea input field. |
||
585 | * |
||
586 | * @param string $name |
||
587 | * @param string $value |
||
588 | * @param array $options |
||
589 | * |
||
590 | * @return \Illuminate\Support\HtmlString |
||
591 | */ |
||
592 | 24 | public function textarea($name, $value = null, array $options = []) |
|
593 | { |
||
594 | 24 | if ( ! isset($options['name'])) { |
|
595 | 24 | $options['name'] = $name; |
|
596 | } |
||
597 | |||
598 | // Next we will look for the rows and cols attributes, as each of these are put |
||
599 | // on the textarea element definition. If they are not present, we will just |
||
600 | // assume some sane default values for these attributes for the developer. |
||
601 | 24 | $options = $this->setTextAreaSize($options); |
|
602 | 24 | $options['id'] = $this->getIdAttribute($name, $options); |
|
603 | 24 | $value = (string) $this->getValueAttribute($name, $value); |
|
604 | |||
605 | 24 | unset($options['size']); |
|
606 | |||
607 | // Next we will convert the attributes into a string form. Also we have removed |
||
608 | // the size attribute, as it was merely a short-cut for the rows and cols on |
||
609 | // the element. Then we'll create the final textarea elements HTML for us. |
||
610 | 24 | $options = $this->html->attributes($options); |
|
611 | |||
612 | 24 | return $this->toHtmlString('<textarea' . $options . '>' . $this->html->escape($value) . '</textarea>'); |
|
613 | } |
||
614 | |||
615 | /** |
||
616 | * Set the text area size on the attributes. |
||
617 | * |
||
618 | * @param array $options |
||
619 | * |
||
620 | * @return array |
||
621 | */ |
||
622 | 24 | private function setTextAreaSize(array $options) |
|
623 | { |
||
624 | 24 | if (isset($options['size'])) { |
|
625 | 12 | return $this->setQuickTextAreaSize($options); |
|
626 | } |
||
627 | |||
628 | // If the "size" attribute was not specified, we will just look for the regular |
||
629 | // columns and rows attributes, using sane defaults if these do not exist on |
||
630 | // the attributes array. We'll then return this entire options array back. |
||
631 | 12 | $cols = Arr::get($options, 'cols', 50); |
|
632 | 12 | $rows = Arr::get($options, 'rows', 10); |
|
633 | |||
634 | 12 | return array_merge($options, compact('cols', 'rows')); |
|
635 | } |
||
636 | |||
637 | /** |
||
638 | * Set the text area size using the quick "size" attribute. |
||
639 | * |
||
640 | * @param array $options |
||
641 | * |
||
642 | * @return array |
||
643 | */ |
||
644 | 12 | protected function setQuickTextAreaSize(array $options) |
|
645 | { |
||
646 | 12 | list($cols, $rows) = explode('x', $options['size']); |
|
647 | |||
648 | 12 | return array_merge($options, [ |
|
649 | 12 | 'cols' => $cols, |
|
650 | 12 | 'rows' => $rows |
|
651 | ]); |
||
652 | } |
||
653 | |||
654 | /** |
||
655 | * Create a select box field. |
||
656 | * |
||
657 | * @param string $name |
||
658 | * @param array|\Illuminate\Support\Collection $list |
||
659 | * @param string $selected |
||
660 | * @param array $options |
||
661 | * |
||
662 | * @return \Illuminate\Support\HtmlString |
||
663 | */ |
||
664 | 56 | public function select($name, $list = [], $selected = null, array $options = []) |
|
665 | { |
||
666 | // When building a select box the "value" attribute is really the selected one |
||
667 | // so we will use that when checking the model or session for a value which |
||
668 | // should provide a convenient method of re-populating the forms on post. |
||
669 | 56 | $selected = $this->getValueAttribute($name, $selected); |
|
670 | |||
671 | // Transform to array if it is a collection |
||
672 | 56 | if ($selected instanceof Collection) { |
|
673 | 4 | $selected = $selected->all(); |
|
674 | } |
||
675 | |||
676 | 56 | $options['id'] = $this->getIdAttribute($name, $options); |
|
677 | |||
678 | 56 | if ( ! isset($options['name'])) { |
|
679 | 40 | $options['name'] = $name; |
|
680 | } |
||
681 | |||
682 | // We will simply loop through the options and build an HTML value for each of |
||
683 | // them until we have an array of HTML declarations. Then we will join them |
||
684 | // all together into one single HTML element that can be put on the form. |
||
685 | 56 | $html = []; |
|
686 | |||
687 | 56 | if (isset($options['placeholder'])) { |
|
688 | 4 | $html[] = $this->placeholderOption($options['placeholder'], $selected); |
|
689 | 4 | unset($options['placeholder']); |
|
690 | } |
||
691 | |||
692 | 56 | foreach($list as $value => $display) { |
|
693 | 52 | $html[] = $this->getSelectOption($display, $value, $selected); |
|
694 | } |
||
695 | |||
696 | // Once we have all of this HTML, we can join this into a single element after |
||
697 | // formatting the attributes into an HTML "attributes" string, then we will |
||
698 | // build out a final select statement, which will contain all the values. |
||
699 | 56 | $options = $this->html->attributes($options); |
|
700 | |||
701 | 56 | return $this->toHtmlString("<select{$options}>".implode('', $html).'</select>'); |
|
702 | } |
||
703 | |||
704 | /** |
||
705 | * Create a select range field. |
||
706 | * |
||
707 | * @param string $name |
||
708 | * @param string $begin |
||
709 | * @param string $end |
||
710 | * @param string $selected |
||
711 | * @param array $options |
||
712 | * |
||
713 | * @return \Illuminate\Support\HtmlString |
||
714 | */ |
||
715 | 8 | public function selectRange($name, $begin, $end, $selected = null, array $options = []) |
|
716 | { |
||
717 | 8 | $range = array_combine($range = range($begin, $end), $range); |
|
718 | |||
719 | 8 | return $this->select($name, $range, $selected, $options); |
|
720 | } |
||
721 | |||
722 | /** |
||
723 | * Create a select year field. |
||
724 | * |
||
725 | * @param string $name |
||
726 | * @param string $begin |
||
727 | * @param string $end |
||
728 | * @param string $selected |
||
729 | * @param array $options |
||
730 | * |
||
731 | * @return \Illuminate\Support\HtmlString |
||
732 | */ |
||
733 | 4 | public function selectYear($name, $begin, $end, $selected = null, array $options = []) |
|
734 | { |
||
735 | 4 | return call_user_func_array( |
|
736 | 4 | [$this, 'selectRange'], |
|
737 | 4 | compact('name', 'begin', 'end', 'selected', 'options') |
|
738 | ); |
||
739 | } |
||
740 | |||
741 | /** |
||
742 | * Create a select month field. |
||
743 | * |
||
744 | * @param string $name |
||
745 | * @param string $selected |
||
746 | * @param array $options |
||
747 | * @param string $format |
||
748 | * |
||
749 | * @return \Illuminate\Support\HtmlString |
||
750 | */ |
||
751 | 4 | public function selectMonth($name, $selected = null, array $options = [], $format = '%B') |
|
752 | { |
||
753 | 4 | $months = []; |
|
754 | |||
755 | 4 | foreach(range(1, 12) as $month) { |
|
756 | 4 | $months[$month] = strftime($format, mktime(0, 0, 0, $month, 1)); |
|
757 | } |
||
758 | |||
759 | 4 | return $this->select($name, $months, $selected, $options); |
|
760 | } |
||
761 | |||
762 | /** |
||
763 | * Get the select option for the given value. |
||
764 | * |
||
765 | * @param string $display |
||
766 | * @param string $value |
||
767 | * @param string $selected |
||
768 | * |
||
769 | * @return string |
||
770 | */ |
||
771 | 52 | private function getSelectOption($display, $value, $selected) |
|
772 | { |
||
773 | 52 | return is_array($display) |
|
774 | 8 | ? $this->optionGroup($display, $value, $selected) |
|
775 | 52 | : $this->option($display, $value, $selected); |
|
776 | } |
||
777 | |||
778 | /** |
||
779 | * Create an option group form element. |
||
780 | * |
||
781 | * @param array $list |
||
782 | * @param string $label |
||
783 | * @param string $selected |
||
784 | * |
||
785 | * @return string |
||
786 | */ |
||
787 | 8 | private function optionGroup(array $list, $label, $selected) |
|
788 | { |
||
789 | 8 | $html = []; |
|
790 | |||
791 | 8 | foreach($list as $value => $display) { |
|
792 | 8 | $html[] = $this->option($display, $value, $selected); |
|
793 | } |
||
794 | |||
795 | 8 | return '<optgroup label="'.$this->html->escape($label).'">'.implode('', $html).'</optgroup>'; |
|
796 | } |
||
797 | |||
798 | /** |
||
799 | * Create a select element option. |
||
800 | * |
||
801 | * @param string $display |
||
802 | * @param string $value |
||
803 | * @param string $selected |
||
804 | * |
||
805 | * @return string |
||
806 | */ |
||
807 | 52 | private function option($display, $value, $selected) |
|
814 | |||
815 | /** |
||
816 | * Create a placeholder select element option. |
||
817 | * |
||
818 | * @param string $display |
||
819 | * @param string $selected |
||
820 | * |
||
821 | * @return string |
||
822 | */ |
||
823 | 4 | private function placeholderOption($display, $selected) |
|
831 | |||
832 | /** |
||
833 | * Determine if the value is selected. |
||
834 | * |
||
835 | * @param string $value |
||
836 | * @param string $selected |
||
837 | * |
||
838 | * @return string|null |
||
839 | */ |
||
840 | 52 | private function getSelectedValue($value, $selected) |
|
848 | |||
849 | /** |
||
850 | * Create a checkbox input field. |
||
851 | * |
||
852 | * @param string $name |
||
853 | * @param mixed $value |
||
854 | * @param bool|null $checked |
||
855 | * @param array $options |
||
856 | * |
||
857 | * @return \Illuminate\Support\HtmlString |
||
858 | */ |
||
859 | 16 | public function checkbox($name, $value = 1, $checked = null, array $options = []) |
|
863 | |||
864 | /** |
||
865 | * Create a radio button input field. |
||
866 | * |
||
867 | * @param string $name |
||
868 | * @param mixed $value |
||
869 | * @param bool $checked |
||
870 | * @param array $options |
||
871 | * |
||
872 | * @return \Illuminate\Support\HtmlString |
||
873 | */ |
||
874 | 8 | public function radio($name, $value = null, $checked = null, array $options = []) |
|
875 | { |
||
876 | 8 | if (is_null($value)) { |
|
877 | 4 | $value = $name; |
|
878 | } |
||
879 | |||
880 | 8 | return $this->checkable('radio', $name, $value, $checked, $options); |
|
881 | } |
||
882 | |||
883 | /** |
||
884 | * Create a checkable input field. |
||
885 | * |
||
886 | * @param string $type |
||
887 | * @param string $name |
||
888 | * @param mixed $value |
||
889 | * @param bool|null $checked |
||
890 | * @param array $options |
||
891 | * |
||
892 | * @return \Illuminate\Support\HtmlString |
||
893 | */ |
||
894 | 28 | protected function checkable($type, $name, $value, $checked, array $options) |
|
895 | { |
||
896 | 28 | $checked = $this->getCheckedState($type, $name, $value, $checked); |
|
897 | |||
898 | 28 | if ( ! is_null($checked) && $checked) { |
|
899 | 24 | $options['checked'] = 'checked'; |
|
900 | } |
||
901 | |||
902 | 28 | return $this->input($type, $name, $value, $options); |
|
903 | } |
||
904 | |||
905 | /** |
||
906 | * Get the check state for a checkable input. |
||
907 | * |
||
908 | * @param string $type |
||
909 | * @param string $name |
||
910 | * @param mixed $value |
||
911 | * @param bool|null $checked |
||
912 | * |
||
913 | * @return bool |
||
914 | */ |
||
915 | 28 | private function getCheckedState($type, $name, $value, $checked) |
|
916 | { |
||
917 | switch($type) { |
||
918 | 28 | case 'checkbox': |
|
919 | 16 | return $this->getCheckboxCheckedState($name, $value, $checked); |
|
920 | |||
921 | 12 | case 'radio': |
|
922 | 8 | return $this->getRadioCheckedState($name, $value, $checked); |
|
923 | |||
924 | default: |
||
925 | 4 | return $this->getValueAttribute($name) == $value; |
|
926 | } |
||
927 | } |
||
928 | |||
929 | /** |
||
930 | * Get the check state for a checkbox input. |
||
931 | * |
||
932 | * @param string $name |
||
933 | * @param mixed $value |
||
934 | * @param bool|null $checked |
||
935 | * |
||
936 | * @return bool |
||
937 | */ |
||
938 | 16 | private function getCheckboxCheckedState($name, $value, $checked) |
|
939 | { |
||
940 | 16 | if (isset($this->session) && ! $this->oldInputIsEmpty() && is_null($this->old($name))) { |
|
941 | 4 | return false; |
|
942 | } |
||
943 | |||
944 | 16 | if ($this->missingOldAndModel($name)) { |
|
945 | 8 | return $checked; |
|
946 | } |
||
947 | |||
948 | 8 | $posted = $this->getValueAttribute($name, $checked); |
|
949 | |||
950 | 8 | if (is_array($posted)) { |
|
951 | 4 | return in_array($value, $posted); |
|
952 | } |
||
953 | |||
954 | 8 | if ($posted instanceof Collection) { |
|
955 | 4 | return $posted->contains('id', $value); |
|
956 | } |
||
957 | |||
958 | 8 | return (bool) $posted; |
|
959 | } |
||
960 | |||
961 | /** |
||
962 | * Get the check state for a radio input. |
||
963 | * |
||
964 | * @param string $name |
||
965 | * @param mixed $value |
||
966 | * @param bool|null $checked |
||
967 | * |
||
968 | * @return bool |
||
969 | */ |
||
970 | 8 | private function getRadioCheckedState($name, $value, $checked) |
|
971 | { |
||
972 | 8 | return $this->missingOldAndModel($name) |
|
973 | 4 | ? $checked |
|
974 | 8 | : $this->getValueAttribute($name) == $value; |
|
975 | } |
||
976 | |||
977 | /** |
||
978 | * Determine if old input or model input exists for a key. |
||
979 | * |
||
980 | * @param string $name |
||
981 | * |
||
982 | * @return bool |
||
983 | */ |
||
984 | 24 | private function missingOldAndModel($name) |
|
985 | { |
||
986 | 24 | return (is_null($this->old($name)) && is_null($this->getModelValueAttribute($name))); |
|
987 | } |
||
988 | |||
989 | /** |
||
990 | * Create a HTML reset input element. |
||
991 | * |
||
992 | * @param string $value |
||
993 | * @param array $attributes |
||
994 | * |
||
995 | * @return \Illuminate\Support\HtmlString |
||
996 | */ |
||
997 | 4 | public function reset($value, array $attributes = []) |
|
998 | { |
||
999 | 4 | return $this->input('reset', null, $value, $attributes); |
|
1000 | } |
||
1001 | |||
1002 | /** |
||
1003 | * Create a HTML image input element. |
||
1004 | * |
||
1005 | * @param string $url |
||
1006 | * @param string $name |
||
1007 | * @param array $attributes |
||
1008 | * |
||
1009 | * @return \Illuminate\Support\HtmlString |
||
1010 | */ |
||
1011 | 4 | public function image($url, $name = null, array $attributes = []) |
|
1012 | { |
||
1013 | 4 | $attributes['src'] = $this->url->asset($url); |
|
1014 | |||
1015 | 4 | return $this->input('image', $name, null, $attributes); |
|
1016 | } |
||
1017 | |||
1018 | /** |
||
1019 | * Create a submit button element. |
||
1020 | * |
||
1021 | * @param string $value |
||
1022 | * @param array $options |
||
1023 | * |
||
1024 | * @return \Illuminate\Support\HtmlString |
||
1025 | */ |
||
1026 | 4 | public function submit($value = null, array $options = []) |
|
1027 | { |
||
1028 | 4 | return $this->input('submit', null, $value, $options); |
|
1029 | } |
||
1030 | |||
1031 | /** |
||
1032 | * Create a button element. |
||
1033 | * |
||
1034 | * @param string $value |
||
1035 | * @param array $options |
||
1036 | * |
||
1037 | * @return \Illuminate\Support\HtmlString |
||
1038 | */ |
||
1039 | 4 | public function button($value = null, array $options = []) |
|
1040 | { |
||
1041 | 4 | if ( ! array_key_exists('type', $options)) { |
|
1042 | 4 | $options['type'] = 'button'; |
|
1043 | } |
||
1044 | |||
1045 | 4 | return $this->toHtmlString( |
|
1046 | 4 | '<button' . $this->html->attributes($options) . '>' . $value . '</button>' |
|
1047 | ); |
||
1048 | } |
||
1049 | |||
1050 | /** |
||
1051 | * Create a color input field. |
||
1052 | * |
||
1053 | * @param string $name |
||
1054 | * @param string $value |
||
1055 | * @param array $options |
||
1056 | * |
||
1057 | * @return \Illuminate\Support\HtmlString |
||
1058 | */ |
||
1059 | 12 | public function color($name, $value = null, array $options = []) |
|
1060 | { |
||
1061 | 12 | return $this->input('color', $name, $value, $options); |
|
1062 | } |
||
1063 | |||
1064 | /* ----------------------------------------------------------------- |
||
1065 | | Other Methods |
||
1066 | | ----------------------------------------------------------------- |
||
1067 | */ |
||
1068 | |||
1069 | /** |
||
1070 | * Get the form action from the options. |
||
1071 | * |
||
1072 | * @param array $options |
||
1073 | * |
||
1074 | * @return string |
||
1075 | */ |
||
1076 | 64 | private function getAction(array $options) |
|
1077 | { |
||
1078 | // We will also check for a "route" or "action" parameter on the array so that |
||
1079 | // developers can easily specify a route or controller action when creating |
||
1080 | // a form providing a convenient interface for creating the form actions. |
||
1081 | 64 | if (isset($options['url'])) { |
|
1082 | 20 | return $this->getUrlAction($options['url']); |
|
1083 | } |
||
1084 | 44 | elseif (isset($options['route'])) { |
|
1085 | 4 | return $this->getRouteAction($options['route']); |
|
1086 | } |
||
1087 | 44 | elseif (isset($options['action'])) { |
|
1088 | // If an action is available, we are attempting to open a form to a controller |
||
1089 | // action route. So, we will use the URL generator to get the path to these |
||
1090 | // actions and return them from the method. Otherwise, we'll use current. |
||
1091 | 4 | return $this->getControllerAction($options['action']); |
|
1092 | } |
||
1093 | |||
1094 | 40 | return $this->url->current(); |
|
1095 | } |
||
1096 | |||
1097 | /** |
||
1098 | * Get the action for a "url" option. |
||
1099 | * |
||
1100 | * @param array|string $options |
||
1101 | * |
||
1102 | * @return string |
||
1103 | */ |
||
1104 | 20 | private function getUrlAction($options) |
|
1105 | { |
||
1106 | 20 | return is_array($options) |
|
1107 | ? $this->url->to($options[0], array_slice($options, 1)) |
||
1108 | 20 | : $this->url->to($options); |
|
1109 | } |
||
1110 | |||
1111 | /** |
||
1112 | * Get the action for a "route" option. |
||
1113 | * |
||
1114 | * @param array|string $options |
||
1115 | * |
||
1116 | * @return string |
||
1117 | */ |
||
1118 | 4 | private function getRouteAction($options) |
|
1119 | { |
||
1120 | 4 | return is_array($options) |
|
1121 | ? $this->url->route($options[0], array_slice($options, 1)) |
||
1122 | 4 | : $this->url->route($options); |
|
1123 | } |
||
1124 | |||
1125 | /** |
||
1126 | * Get the action for an "action" option. |
||
1127 | * |
||
1128 | * @param array|string $options |
||
1129 | * |
||
1130 | * @return string |
||
1131 | */ |
||
1132 | 4 | private function getControllerAction($options) |
|
1133 | { |
||
1134 | 4 | return is_array($options) |
|
1135 | ? $this->url->action($options[0], array_slice($options, 1)) |
||
1136 | 4 | : $this->url->action($options); |
|
1137 | } |
||
1138 | |||
1139 | /** |
||
1140 | * Get the form appendage for the given method. |
||
1141 | * |
||
1142 | * @param string $method |
||
1143 | * |
||
1144 | * @return string |
||
1145 | */ |
||
1146 | 64 | private function getAppendage($method) |
|
1166 | } |
||
1167 |
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.