Issues (11)

src/Components/HandlesBoundValues.php (6 issues)

1
<?php
2
3
namespace ProtoneMedia\LaravelFormComponents\Components;
4
5
use DateTimeInterface;
6
use Illuminate\Database\Eloquent\Model;
7
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
8
use Illuminate\Database\Eloquent\Relations\MorphMany;
9
use Illuminate\Support\Carbon;
10
use Illuminate\Support\Str;
11
use ProtoneMedia\LaravelFormComponents\FormDataBinder;
12
13
trait HandlesBoundValues
14
{
15
    /**
16
     * Wether to retrieve the default value as a single
17
     * attribute or as a collection from the database.
18
     *
19
     * @var boolean
20
     */
21
    protected $manyRelation = false;
22
23
    /**
24
     * Get an instance of FormDataBinder.
25
     *
26
     * @return FormDataBinder
27
     */
28
    private function getFormDataBinder(): FormDataBinder
29
    {
30
        return app(FormDataBinder::class);
31
    }
32
33
    /**
34
     * Get the latest bound target.
35
     *
36
     * @return mixed
37
     */
38
    private function getBoundTarget()
39
    {
40
        return $this->getFormDataBinder()->get();
41
    }
42
43
    /**
44
     * Get an item from the latest bound target.
45
     *
46
     * @param mixed $bind
47
     * @param string $name
48
     * @return mixed
49
     */
50
    private function getBoundValue($bind, string $name)
51
    {
52
        if ($bind === false) {
53
            return null;
54
        }
55
56
        $bind = $bind ?: $this->getBoundTarget();
57
58
        if ($this->manyRelation) {
59
            return $this->getAttachedKeysFromRelation($bind, $name);
60
        }
61
62
        $boundValue = data_get($bind, $name);
63
64
        if ($bind instanceof Model && $boundValue instanceof DateTimeInterface) {
65
            return $this->formatDateTime($bind, $name, $boundValue);
0 ignored issues
show
Are you sure the usage of $this->formatDateTime($bind, $name, $boundValue) targeting ProtoneMedia\LaravelForm...alues::formatDateTime() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
66
        }
67
68
        return $boundValue;
69
    }
70
71
    /**
72
     * Formats a DateTimeInterface if the key is specified as a date or datetime in the model.
73
     *
74
     * @param \Illuminate\Database\Eloquent\Model $model
75
     * @param string $key
76
     * @param DateTimeInterface $date
77
     * @return void
78
     */
79
    private function formatDateTime(Model $model, string $key, DateTimeInterface $date)
80
    {
81
        if (!config('form-components.use_eloquent_date_casting')) {
82
            return $date;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $date returns the type DateTimeInterface which is incompatible with the documented return type void.
Loading history...
83
        }
84
85
        $cast = $model->getCasts()[$key] ?? null;
86
87
        if (!$cast || $cast === 'date' || $cast === 'datetime') {
88
            return Carbon::instance($date)->toJSON();
0 ignored issues
show
Bug Best Practice introduced by
The expression return Illuminate\Suppor...stance($date)->toJSON() also could return the type string which is incompatible with the documented return type void.
Loading history...
89
        }
90
91
        if ($this->isCustomDateTimeCast($cast)) {
92
            return $date->format(explode(':', $cast, 2)[1]);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $date->format(explode(':', $cast, 2)[1]) returns the type string which is incompatible with the documented return type void.
Loading history...
93
        }
94
95
        return $date;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $date returns the type DateTimeInterface which is incompatible with the documented return type void.
Loading history...
96
    }
97
98
    /**
99
     * Determine if the cast type is a custom date time cast.
100
     *
101
     * @param  string  $cast
102
     * @return bool
103
     */
104
    protected function isCustomDateTimeCast($cast)
105
    {
106
        return Str::startsWith($cast, [
107
            'date:',
108
            'datetime:',
109
            'immutable_date:',
110
            'immutable_datetime:',
111
        ]);
112
    }
113
114
    /**
115
     * Returns an array with the attached keys.
116
     *
117
     * @param mixed $bind
118
     * @param string $name
119
     * @return void
120
     */
121
    private function getAttachedKeysFromRelation($bind, string $name): ?array
122
    {
123
        if (!$bind instanceof Model) {
124
            return data_get($bind, $name);
125
        }
126
127
        $relation = $bind->{$name}();
128
129
        if ($relation instanceof BelongsToMany) {
130
            $relatedKeyName = $relation->getRelatedKeyName();
131
132
            return $relation->getBaseQuery()
133
                ->get($relation->getRelated()->qualifyColumn($relatedKeyName))
134
                ->pluck($relatedKeyName)
135
                ->all();
136
        }
137
138
        if ($relation instanceof MorphMany) {
139
            $parentKeyName = $relation->getLocalKeyName();
140
141
            return $relation->getBaseQuery()
142
                ->get($relation->getQuery()->qualifyColumn($parentKeyName))
143
                ->pluck($parentKeyName)
144
                ->all();
145
        }
146
147
        return data_get($bind, $name);
0 ignored issues
show
Bug Best Practice introduced by
The expression return data_get($bind, $name) could return the type Illuminate\Database\Eloquent\Model which is incompatible with the type-hinted return array|null. Consider adding an additional type-check to rule them out.
Loading history...
148
    }
149
}
150