Completed
Pull Request — master (#26)
by ARCANEDEV
10:17
created

FormBuilder::select()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 24
ccs 9
cts 9
cp 1
rs 9.536
c 0
b 0
f 0
cc 1
nc 1
nop 6
crap 1
1
<?php namespace Arcanedev\LaravelHtml;
2
3
use Arcanedev\Html\Elements;
4
use Arcanedev\LaravelHtml\Bases\Builder;
5
use Arcanedev\LaravelHtml\Contracts\FormBuilder as FormBuilderContract;
6
use DateTime;
7
use Illuminate\Contracts\Routing\UrlGenerator;
8
use Illuminate\Contracts\Session\Session;
9
use Illuminate\Support\Arr;
10
use Illuminate\Support\Collection;
11
use Illuminate\Support\Str;
12
13
/**
14
 * Class     FormBuilder
15
 *
16
 * @package  Arcanedev\LaravelHtml
17
 * @author   ARCANEDEV <[email protected]>
18
 */
19
class FormBuilder extends Builder 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
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 321
    public function __construct(Contracts\HtmlBuilder $html, UrlGenerator $url, Session $session)
102
    {
103 321
        $this->url       = $url;
104 321
        $this->html      = $html;
105 321
        $this->csrfToken = $session->token();
106
107 321
        $this->setSessionStore($session);
108 321
    }
109
110
    /* -----------------------------------------------------------------
111
     |  Getters & Setters
112
     | -----------------------------------------------------------------
113
     */
114
115
    /**
116
     * Get the session store implementation.
117
     *
118
     * @return  \Illuminate\Contracts\Session\Session
119
     */
120 3
    public function getSessionStore()
121
    {
122 3
        return $this->session;
123
    }
124
125
    /**
126
     * Set the session store implementation.
127
     *
128
     * @param  \Illuminate\Contracts\Session\Session  $session
129
     *
130
     * @return self
131
     */
132 321
    public function setSessionStore(Session $session)
133
    {
134 321
        $this->session = $session;
135
136 321
        return $this;
137
    }
138
139
    /**
140
     * Set the model instance on the form builder.
141
     *
142
     * @param  \Illuminate\Database\Eloquent\Model  $model
143
     *
144
     * @return self
145
     */
146 36
    public function setModel($model)
147
    {
148 36
        $this->model = $model;
149
150 36
        return $this;
151
    }
152
153
    /**
154
     * Get the model instance on the form builder.
155
     *
156
     * @return \Illuminate\Database\Eloquent\Model
157
     */
158 138
    public function getModel()
159
    {
160 138
        return $this->model;
161
    }
162
163
    /**
164
     * Get the ID attribute for a field name.
165
     *
166
     * @param  string  $name
167
     * @param  array   $attributes
168
     *
169
     * @return string
170
     */
171 261
    public function getIdAttribute($name, array $attributes)
172
    {
173 261
        if (array_key_exists('id', $attributes))
174 21
            return $attributes['id'];
175
176 249
        if (in_array($name, $this->labels))
177 6
            return $name;
178
179 243
        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 237
    public function getValueAttribute($name, $value = null)
191
    {
192 237
        if (is_null($name))
193 9
            return $value;
194
195 228
        if ( ! is_null($this->old($name)) && $name !== '_method')
196 12
            return $this->old($name);
197
198 222
        if ( ! is_null($value))
199 126
            return $value;
200
201 123
        return ! is_null($this->getModel())
202 18
            ? $this->getModelValueAttribute($name)
203 123
            : null;
204
    }
205
206
    /**
207
     * Get the model value that should be assigned to the field.
208
     *
209
     * @param  string                               $name
210
     * @param  \Illuminate\Database\Eloquent\Model  $model
211
     *
212
     * @return mixed
213
     */
214 27
    private function getModelValueAttribute($name, $model = null)
215
    {
216 27
        $model = $model ?: $this->getModel();
217
218 27
        $key = $this->transformKey($name);
219
220 27
        if (strpos($key, '.') !== false) {
221 15
            $keys = explode('.', $key, 2);
222
223 15
            return $this->getModelValueAttribute($keys[1],
224 15
                $this->getModelValueAttribute($keys[0], $model)
225
            );
226
        }
227
228 27
        return method_exists($model, 'getFormValue')
229 3
            ? $model->getFormValue($key)
230 27
            : data_get($model, $key);
231
    }
232
233
    /**
234
     * Get a value from the session's old input.
235
     *
236
     * @param  string  $name
237
     *
238
     * @return mixed
239
     */
240 237
    public function old($name)
241
    {
242 237
        return ! is_null($this->session)
243 237
            ? $this->session->getOldInput($this->transformKey($name))
244 237
            : null;
245
    }
246
247
    /**
248
     * Transform key from array to dot syntax.
249
     *
250
     * @param  string  $key
251
     *
252
     * @return string
253
     */
254 237
    private function transformKey($key)
255
    {
256 237
        return str_replace(
257 237
            ['.', '[]', '[', ']'],
258 237
            ['_', '', '.', ''],
259 158
            $key
260
        );
261
    }
262
263
    /**
264
     * Determine if the old input is empty.
265
     *
266
     * @return bool
267
     */
268 12
    public function oldInputIsEmpty()
269
    {
270 12
        return ! is_null($this->session)
271 12
            && (count($this->session->getOldInput()) === 0);
272
    }
273
274
    /* -----------------------------------------------------------------
275
     |  Main Methods
276
     | -----------------------------------------------------------------
277
     */
278
279
    /**
280
     * Open up a new HTML form.
281
     *
282
     * @param  array  $attributes
283
     *
284
     * @return \Illuminate\Support\HtmlString
285
     */
286 57
    public function open(array $attributes = [])
287
    {
288 57
        $method = strtoupper(Arr::pull($attributes, 'method', 'POST'));
289
290 57
        $form = Elements\Form::make()
291 57
            ->method($method !== 'GET' ? 'POST' : $method)
292 57
            ->action($this->getAction($attributes))
293 57
            ->attributes(array_merge(
294 57
                ['accept-charset' => 'UTF-8'],
295 57
                Arr::except($attributes, $this->reserved)
296
            ));
297
298 57
        if (Arr::pull($attributes, 'files', false))
299 6
            $form = $form->acceptsFiles();
300
301 57
        if (in_array($method, $this->spoofedMethods))
302 6
            $form = $form->addChild($this->hidden('_method', $method));
303
304 57
        if ($method !== 'GET')
305 30
            $form = $form->addChild($this->token());
306
307 57
        return $form->open();
308
    }
309
310
    /**
311
     * Create a new model based form builder.
312
     *
313
     * @param  mixed  $model
314
     * @param  array  $attributes
315
     *
316
     * @return \Illuminate\Support\HtmlString
317
     */
318 15
    public function model($model, array $attributes = [])
319
    {
320 15
        return $this->setModel($model)
321 15
                    ->open($attributes);
322
    }
323
324
    /**
325
     * Close the current form.
326
     *
327
     * @return \Illuminate\Support\HtmlString
328
     */
329 6
    public function close()
330
    {
331 6
        $this->labels = [];
332 6
        $this->setModel(null);
0 ignored issues
show
Documentation introduced by
null is of type null, but the function expects a object<Illuminate\Database\Eloquent\Model>.

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);
Loading history...
333
334 6
        return Elements\Form::make()->close();
335
    }
336
337
    /**
338
     * Generate a hidden field with the current CSRF token.
339
     *
340
     * @return \Illuminate\Support\HtmlString
341
     */
342 30
    public function token()
343
    {
344 30
        return $this->hidden(
345 30
            '_token',
346 30
            empty($this->csrfToken) ? $this->session->token() : $this->csrfToken
347
        );
348
    }
349
350
    /**
351
     * Create a form label element.
352
     *
353
     * @param  string        $name
354
     * @param  string|mixed  $value
355
     * @param  array         $attributes
356
     * @param  bool          $escaped
357
     *
358
     * @return \Illuminate\Support\HtmlString
359
     */
360 15
    public function label($name, $value = null, array $attributes = [], $escaped = true)
361
    {
362 15
        $this->labels[] = $name;
363
364 15
        $value = $value ?: Str::title(str_replace(['_', '-'], ' ', $name));
365
366 15
        return Elements\Label::make()
367 15
            ->for($name)
368 15
            ->attributes($attributes)
369 15
            ->html($escaped ? e($value) : $value)
370 15
            ->render();
371
    }
372
373
    /**
374
     * Create a form input field.
375
     *
376
     * @param  string        $type
377
     * @param  string        $name
378
     * @param  string|mixed  $value
379
     * @param  array         $attributes
380
     *
381
     * @return \Illuminate\Support\HtmlString
382
     */
383 198
    public function input($type, $name, $value = null, array $attributes = [])
384
    {
385 198
        $id = $this->getIdAttribute($name, $attributes);
386
387 198
        if ( ! in_array($type, $this->skipValueTypes))
388 162
            $value = $this->getValueAttribute($name, $value);
389
390 198
        return Elements\Input::make()
391 198
            ->type($type)
392 198
            ->attributeUnless(is_null($name), 'name', $name)
393 198
            ->attributeUnless(is_null($id), 'id', $id)
394 198
            ->attributeUnless(is_null($value) || empty($value), 'value', $value)
395 198
            ->attributes($attributes)
396 198
            ->render();
397
    }
398
399
    /**
400
     * Create a text input field.
401
     *
402
     * @param  string        $name
403
     * @param  string|mixed  $value
404
     * @param  array         $attributes
405
     *
406
     * @return \Illuminate\Support\HtmlString
407
     */
408 21
    public function text($name, $value = null, array $attributes = [])
409
    {
410 21
        return $this->input('text', $name, $value, $attributes);
411
    }
412
413
    /**
414
     * Create a password input field.
415
     *
416
     * @param  string  $name
417
     * @param  array   $attributes
418
     *
419
     * @return \Illuminate\Support\HtmlString
420
     */
421 9
    public function password($name, array $attributes = [])
422
    {
423 9
        return $this->input('password', $name, null, $attributes);
424
    }
425
426
    /**
427
     * Create a hidden input field.
428
     *
429
     * @param  string        $name
430
     * @param  string|mixed  $value
431
     * @param  array         $attributes
432
     *
433
     * @return \Illuminate\Support\HtmlString
434
     */
435 39
    public function hidden($name, $value = null, array $attributes = [])
436
    {
437 39
        return $this->input('hidden', $name, $value, $attributes);
438
    }
439
440
    /**
441
     * Create an e-mail input field.
442
     *
443
     * @param  string        $name
444
     * @param  string|mixed  $value
445
     * @param  array         $attributes
446
     *
447
     * @return \Illuminate\Support\HtmlString
448
     */
449 9
    public function email($name, $value = null, array $attributes = [])
450
    {
451 9
        return $this->input('email', $name, $value, $attributes);
452
    }
453
454
    /**
455
     * Create a tel input field.
456
     *
457
     * @param  string        $name
458
     * @param  string|mixed  $value
459
     * @param  array         $attributes
460
     *
461
     * @return \Illuminate\Support\HtmlString
462
     */
463 9
    public function tel($name, $value = null, array $attributes = [])
464
    {
465 9
        return $this->input('tel', $name, $value, $attributes);
466
    }
467
468
    /**
469
     * Create a number input field.
470
     *
471
     * @param  string        $name
472
     * @param  string|mixed  $value
473
     * @param  array         $attributes
474
     *
475
     * @return \Illuminate\Support\HtmlString
476
     */
477 9
    public function number($name, $value = null, array $attributes = [])
478
    {
479 9
        return $this->input('number', $name, $value, $attributes);
480
    }
481
482
    /**
483
     * Create a date input field.
484
     *
485
     * @param  string  $name
486
     * @param  string  $value
487
     * @param  array   $attributes
488
     *
489
     * @return \Illuminate\Support\HtmlString
490
     */
491 12
    public function date($name, $value = null, array $attributes = [])
492
    {
493 12
        if ($value instanceof DateTime)
494 3
            $value = $value->format('Y-m-d');
495
496 12
        return $this->input('date', $name, $value, $attributes);
497
    }
498
499
    /**
500
     * Create a datetime input field.
501
     *
502
     * @param  string        $name
503
     * @param  string|mixed  $value
504
     * @param  array         $attributes
505
     *
506
     * @return \Illuminate\Support\HtmlString
507
     */
508 12
    public function datetime($name, $value = null, array $attributes = [])
509
    {
510 12
        if ($value instanceof DateTime)
511 6
            $value = $value->format(DateTime::RFC3339);
512
513 12
        return $this->input('datetime', $name, $value, $attributes);
514
    }
515
516
    /**
517
     * Create a datetime-local input field.
518
     *
519
     * @param  string        $name
520
     * @param  string|mixed  $value
521
     * @param  array         $attributes
522
     *
523
     * @return \Illuminate\Support\HtmlString
524
     */
525 12
    public function datetimeLocal($name, $value = null, array $attributes = [])
526
    {
527 12
        if ($value instanceof DateTime)
528 6
            $value = $value->format('Y-m-d\TH:i');
529
530 12
        return $this->input('datetime-local', $name, $value, $attributes);
531
    }
532
533
    /**
534
     * Create a time input field.
535
     *
536
     * @param  string        $name
537
     * @param  string|mixed  $value
538
     * @param  array         $options
539
     *
540
     * @return \Illuminate\Support\HtmlString
541
     */
542 9
    public function time($name, $value = null, array $options = [])
543
    {
544 9
        return $this->input('time', $name, $value, $options);
545
    }
546
547
    /**
548
     * Create a url input field.
549
     *
550
     * @param  string  $name
551
     * @param  string  $value
552
     * @param  array   $options
553
     *
554
     * @return \Illuminate\Support\HtmlString
555
     */
556 6
    public function url($name, $value = null, array $options = [])
557
    {
558 6
        return $this->input('url', $name, $value, $options);
559
    }
560
561
    /**
562
     * Create a file input field.
563
     *
564
     * @param  string  $name
565
     * @param  array   $options
566
     *
567
     * @return \Illuminate\Support\HtmlString
568
     */
569 9
    public function file($name, array $options = [])
570
    {
571 9
        return $this->input('file', $name, null, $options);
572
    }
573
574
    /**
575
     * Create a textarea input field.
576
     *
577
     * @param  string  $name
578
     * @param  string  $value
579
     * @param  array   $attributes
580
     *
581
     * @return \Illuminate\Support\HtmlString
582
     */
583 18
    public function textarea($name, $value = null, array $attributes = [])
584
    {
585
        // Next we will look for the rows and cols attributes, as each of these are put
586
        // on the textarea element definition. If they are not present, we will just
587
        // assume some sane default values for these attributes for the developer.
588 18
        $attributes = $this->setTextAreaSize($attributes);
589 18
        $id      = $this->getIdAttribute($name, $attributes);
590 18
        $value   = (string) $this->getValueAttribute($name, $value);
591
592 18
        unset($attributes['size']);
593
594 18
        return Elements\Textarea::make()
595 18
            ->name($name)
596 18
            ->attributeUnless(is_null($id), 'id', $id)
597 18
            ->attributes($attributes)
598 18
            ->html($this->html->escape($value))
599 18
            ->render();
600
    }
601
602
    /**
603
     * Set the text area size on the attributes.
604
     *
605
     * @param  array  $attributes
606
     *
607
     * @return array
608
     */
609 18
    private function setTextAreaSize(array $attributes)
610
    {
611 18
        if (isset($attributes['size']))
612 9
            return $this->setQuickTextAreaSize($attributes);
613
614
        // If the "size" attribute was not specified, we will just look for the regular
615
        // columns and rows attributes, using sane defaults if these do not exist on
616
        // the attributes array. We'll then return this entire options array back.
617 9
        $cols = Arr::get($attributes, 'cols', 50);
618 9
        $rows = Arr::get($attributes, 'rows', 10);
619
620 9
        return array_merge($attributes, compact('cols', 'rows'));
621
    }
622
623
    /**
624
     * Set the text area size using the quick "size" attribute.
625
     *
626
     * @param  array  $attributes
627
     *
628
     * @return array
629
     */
630 9
    protected function setQuickTextAreaSize(array $attributes)
631
    {
632 9
        list($cols, $rows) = explode('x', $attributes['size']);
633
634 9
        return array_merge($attributes, compact('cols', 'rows'));
635
    }
636
637
    /**
638
     * Create a select box field.
639
     *
640
     * @param  string                                $name
641
     * @param  array|\Illuminate\Support\Collection  $list
642
     * @param  string|bool                           $selected
643
     * @param  array                                 $attributes
644
     * @param  array                                 $optionsAttributes
645
     * @param  array                                 $optgroupsAttributes
646
     *
647
     * @return \Illuminate\Support\HtmlString
648
     */
649 45
    public function select(
650
        $name,
651
        $list = [],
652
        $selected = null,
653
        array $attributes = [],
654
        array $optionsAttributes = [],
655
        array $optgroupsAttributes = []
656
    ) {
657
658 45
        $select = Elements\Select::make()->name($name);
659
660
        // When building a select box the "value" attribute is really the selected one
661
        // so we will use that when checking the model or session for a value which
662
        // should provide a convenient method of re-populating the forms on post.
663 45
        $selected = $this->getValueAttribute($name, $selected);
664 45
        $id       = $this->getIdAttribute($name, $attributes);
665
666
        return $select
667 45
            ->options($list, $optionsAttributes, $optgroupsAttributes)
668 45
            ->attributes($attributes)
669 45
            ->attributeUnless(is_null($id), 'id', $id)
670 45
            ->value($selected)
671 45
            ->render();
672
    }
673
674
    /**
675
     * Create a select range field.
676
     *
677
     * @param  string  $name
678
     * @param  string  $begin
679
     * @param  string  $end
680
     * @param  string  $selected
681
     * @param  array   $attributes
682
     *
683
     * @return \Illuminate\Support\HtmlString
684
     */
685 6
    public function selectRange($name, $begin, $end, $selected = null, array $attributes = [])
686
    {
687 6
        $range = array_combine($range = range($begin, $end), $range);
688
689 6
        return $this->select($name, $range, $selected, $attributes);
690
    }
691
692
    /**
693
     * Create a select year field.
694
     *
695
     * @param  string  $name
696
     * @param  string  $begin
697
     * @param  string  $end
698
     * @param  string  $selected
699
     * @param  array   $attributes
700
     *
701
     * @return \Illuminate\Support\HtmlString
702
     */
703 3
    public function selectYear($name, $begin, $end, $selected = null, array $attributes = [])
704
    {
705 3
        return $this->selectRange($name, $begin, $end, $selected, $attributes);
706
    }
707
708
    /**
709
     * Create a select month field.
710
     *
711
     * @param  string  $name
712
     * @param  string  $selected
713
     * @param  array   $attributes
714
     * @param  string  $format
715
     *
716
     * @return \Illuminate\Support\HtmlString
717
     */
718 3
    public function selectMonth($name, $selected = null, array $attributes = [], $format = '%B')
719
    {
720 3
        $months = [];
721
722 3
        foreach(range(1, 12) as $month) {
723 3
            $months[$month] = strftime($format, mktime(0, 0, 0, $month, 1));
724
        }
725
726 3
        return $this->select($name, $months, $selected, $attributes);
727
    }
728
729
    /**
730
     * Create a checkbox input field.
731
     *
732
     * @param  string     $name
733
     * @param  mixed      $value
734
     * @param  bool|null  $checked
735
     * @param  array      $attributes
736
     *
737
     * @return \Illuminate\Support\HtmlString
738
     */
739 12
    public function checkbox($name, $value = 1, $checked = null, array $attributes = [])
740
    {
741 12
        return $this->checkable('checkbox', $name, $value, $checked, $attributes);
742
    }
743
744
    /**
745
     * Create a radio button input field.
746
     *
747
     * @param  string  $name
748
     * @param  mixed   $value
749
     * @param  bool    $checked
750
     * @param  array   $options
751
     *
752
     * @return \Illuminate\Support\HtmlString
753
     */
754 6
    public function radio($name, $value = null, $checked = null, array $options = [])
755
    {
756 6
        return $this->checkable('radio', $name, $value ?: $name, $checked, $options);
757
    }
758
759
    /**
760
     * Create a HTML reset input element.
761
     *
762
     * @param  string|mixed  $value
763
     * @param  array         $attributes
764
     *
765
     * @return \Illuminate\Support\HtmlString
766
     */
767 3
    public function reset($value, array $attributes = [])
768
    {
769 3
        return $this->input('reset', null, $value, $attributes);
770
    }
771
772
    /**
773
    * Create a HTML image input element.
774
    *
775
    * @param  string       $url
776
    * @param  string|null  $name
777
    * @param  array        $attributes
778
    *
779
     * @return \Illuminate\Support\HtmlString
780
    */
781 3
    public function image($url, $name = null, array $attributes = [])
782
    {
783 3
        return $this->input('image', $name, null, array_merge($attributes, [
784 3
            'src' => $this->url->asset($url),
785
        ]));
786
    }
787
788
    /**
789
     * Create a submit button element.
790
     *
791
     * @param  string|mixed  $value
792
     * @param  array         $attributes
793
     *
794
     * @return \Illuminate\Support\HtmlString
795
     */
796 3
    public function submit($value = null, array $attributes = [])
797
    {
798 3
        return $this->input('submit', null, $value, $attributes);
799
    }
800
801
    /**
802
     * Create a button element.
803
     *
804
     * @param  string|mixed  $value
805
     * @param  array         $attributes
806
     *
807
     * @return \Illuminate\Support\HtmlString
808
     */
809 3
    public function button($value = null, array $attributes = [])
810
    {
811 3
        return Elements\Button::make()
812 3
            ->type(Arr::pull($attributes, 'type', 'button'))
813 3
            ->attributes($attributes)
814 3
            ->html($value)
815 3
            ->render();
816
    }
817
818
    /**
819
     * Create a color input field.
820
     *
821
     * @param  string        $name
822
     * @param  string|mixed  $value
823
     * @param  array         $attributes
824
     *
825
     * @return \Illuminate\Support\HtmlString
826
     */
827 9
    public function color($name, $value = null, array $attributes = [])
828
    {
829 9
        return $this->input('color', $name, $value, $attributes);
830
    }
831
832
    /* -----------------------------------------------------------------
833
     |  Other Methods
834
     | -----------------------------------------------------------------
835
     */
836
837
    /**
838
     * Create a checkable input field.
839
     *
840
     * @param  string     $type
841
     * @param  string     $name
842
     * @param  mixed      $value
843
     * @param  bool|null  $checked
844
     * @param  array      $attributes
845
     *
846
     * @return \Illuminate\Support\HtmlString
847
     */
848 21
    protected function checkable($type, $name, $value, $checked, array $attributes)
849
    {
850 21
        $checked = $this->getCheckedState($type, $name, $value, $checked);
851
852 21
        if ( ! is_null($checked) && $checked)
853 18
            $attributes['checked'] = 'checked';
854
855 21
        return $this->input($type, $name, $value, $attributes);
856
    }
857
858
    /**
859
     * Get the check state for a checkable input.
860
     *
861
     * @param  string     $type
862
     * @param  string     $name
863
     * @param  mixed      $value
864
     * @param  bool|null  $checked
865
     *
866
     * @return bool
867
     */
868 21
    private function getCheckedState($type, $name, $value, $checked)
869
    {
870 7
        switch($type) {
871 21
            case 'checkbox':
872 12
                return $this->getCheckboxCheckedState($name, $value, $checked);
873
874 9
            case 'radio':
875 6
                return $this->getRadioCheckedState($name, $value, $checked);
876
877
            default:
878 3
                return $this->getValueAttribute($name) === $value;
879
        }
880
    }
881
882
    /**
883
     * Get the check state for a checkbox input.
884
     *
885
     * @param  string     $name
886
     * @param  mixed      $value
887
     * @param  bool|null  $checked
888
     *
889
     * @return bool
890
     */
891 12
    private function getCheckboxCheckedState($name, $value, $checked)
892
    {
893
        if (
894 12
            isset($this->session) &&
895 12
            ! $this->oldInputIsEmpty() &&
896 9
            is_null($this->old($name))
897
        )
898 3
            return false;
899
900 12
        if ($this->missingOldAndModel($name))
901 6
            return $checked;
902
903 6
        $posted = $this->getValueAttribute($name, $checked);
904
905 6
        if (is_array($posted))
906 3
            return in_array($value, $posted);
907
908 6
        if ($posted instanceof Collection)
909 3
            return $posted->contains('id', $value);
910
911 6
        return (bool) $posted;
912
    }
913
914
    /**
915
     * Get the check state for a radio input.
916
     *
917
     * @param  string     $name
918
     * @param  mixed      $value
919
     * @param  bool|null  $checked
920
     *
921
     * @return bool
922
     */
923 6
    private function getRadioCheckedState($name, $value, $checked)
924
    {
925 6
        return $this->missingOldAndModel($name)
926 2
            ? $checked
927 6
            : $this->getValueAttribute($name) === $value;
928
    }
929
930
    /**
931
     * Determine if old input or model input exists for a key.
932
     *
933
     * @param  string  $name
934
     *
935
     * @return bool
936
     */
937 18
    private function missingOldAndModel($name)
938
    {
939 18
        return (is_null($this->old($name)) && is_null($this->getModelValueAttribute($name)));
940
    }
941
942
    /**
943
     * Get the form action from the options.
944
     *
945
     * @param  array  $attributes
946
     *
947
     * @return string
948
     */
949 57
    private function getAction(array $attributes)
950
    {
951 57
        if (isset($attributes['url']))
952 18
            return $this->getUrlAction($attributes['url']);
953
954 39
        if (isset($attributes['route']))
955 6
            return $this->getRouteAction($attributes['route']);
956
957 36
        if (isset($attributes['action']))
958 6
            return $this->getControllerAction($attributes['action']);
959
960 30
        return $this->url->current();
961
    }
962
963
    /**
964
     * Get the action for a "url" option.
965
     *
966
     * @param  array|string  $attribute
967
     *
968
     * @return string
969
     */
970 18
    private function getUrlAction($attribute)
971
    {
972 18
        return is_array($attribute)
973 3
            ? $this->url->to($attribute[0], array_slice($attribute, 1))
974 18
            : $this->url->to($attribute);
975
    }
976
977
    /**
978
     * Get the action for a "route" option.
979
     *
980
     * @param  array|string  $attribute
981
     *
982
     * @return string
983
     */
984 6
    private function getRouteAction($attribute)
985
    {
986 6
        return is_array($attribute)
987 3
            ? $this->url->route($attribute[0], array_slice($attribute, 1))
988 6
            : $this->url->route($attribute);
989
    }
990
991
    /**
992
     * Get the action for an "action" option.
993
     *
994
     * @param  array|string  $attribute
995
     *
996
     * @return string
997
     */
998 6
    private function getControllerAction($attribute)
999
    {
1000 6
        return is_array($attribute)
1001 3
            ? $this->url->action($attribute[0], array_slice($attribute, 1))
1002 6
            : $this->url->action($attribute);
1003
    }
1004
}
1005