Issues (64)

src/Http/Traits/CompositeRelationships.php (10 issues)

1
<?php
2
3
namespace MaksimM\CompositePrimaryKeys\Http\Traits;
4
5
use Closure;
6
use Illuminate\Database\Eloquent\Builder;
7
use Illuminate\Database\Eloquent\Model;
8
use Illuminate\Database\Eloquent\Relations\BelongsTo;
9
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
10
use Illuminate\Database\Eloquent\Relations\HasMany;
11
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
12
use Illuminate\Database\Eloquent\Relations\HasOne;
13
use Illuminate\Database\Eloquent\Relations\MorphMany;
14
use Illuminate\Database\Eloquent\Relations\MorphOne;
15
use Illuminate\Database\Eloquent\Relations\MorphTo;
16
use Illuminate\Database\Eloquent\Relations\MorphToMany;
17
use Illuminate\Support\Str;
18
use MaksimM\CompositePrimaryKeys\Eloquent\Relationships\CompositeBelongsTo;
19
use MaksimM\CompositePrimaryKeys\Eloquent\Relationships\CompositeBelongsToMany;
20
21
trait CompositeRelationships
22
{
23
    /**
24
     * @param      $related
25
     * @param null $foreignKey
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $foreignKey is correct as it would always require null to be passed?
Loading history...
26
     * @param null $ownerKey
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $ownerKey is correct as it would always require null to be passed?
Loading history...
27
     * @param null $relation
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $relation is correct as it would always require null to be passed?
Loading history...
28
     *
29
     * @return BelongsTo
30
     */
31
    public function belongsTo($related, $foreignKey = null, $ownerKey = null, $relation = null)
32
    {
33
        // If no relation name was given, we will use this debug backtrace to extract
34
        // the calling method's name and use that as the relationship name as most
35
        // of the time this will be what we desire to use for the relationships.
36
        if (is_null($relation)) {
0 ignored issues
show
The condition is_null($relation) is always true.
Loading history...
37
            $relation = $this->guessBelongsToRelation();
0 ignored issues
show
It seems like guessBelongsToRelation() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

37
            /** @scrutinizer ignore-call */ 
38
            $relation = $this->guessBelongsToRelation();
Loading history...
38
        }
39
40
        /**
41
         * @var Model $instance
42
         */
43
        $instance = $this->newRelatedInstance($related);
0 ignored issues
show
It seems like newRelatedInstance() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

43
        /** @scrutinizer ignore-call */ 
44
        $instance = $this->newRelatedInstance($related);
Loading history...
44
45
        // If no foreign key was supplied, we can use a backtrace to guess the proper
46
        // foreign key name by using the name of the relationship function, which
47
        // when combined with an "_id" should conventionally match the columns.
48
        if (is_null($foreignKey)) {
0 ignored issues
show
The condition is_null($foreignKey) is always true.
Loading history...
49
            $foreignKey = is_array($instance->getKeyName()) ? array_map(
0 ignored issues
show
The condition is_array($instance->getKeyName()) is always false.
Loading history...
50
                function ($key) use ($relation) {
51
                    return Str::snake($relation).'_'.$key;
52
                },
53
                $instance->getKeyName()
54
            ) : Str::snake($relation).'_'.$instance->getKeyName();
55
        }
56
57
        // Once we have the foreign key names, we'll just create a new Eloquent query
58
        // for the related models and returns the relationship instance which will
59
        // actually be responsible for retrieving and hydrating every relations.
60
        $ownerKey = $ownerKey ?: $instance->getKeyName();
0 ignored issues
show
$ownerKey is of type null, thus it always evaluated to false.
Loading history...
61
62
        $relationQuery = $this->newBelongsTo(
63
            $instance->newQuery(),
64
            $this,
0 ignored issues
show
$this of type MaksimM\CompositePrimary...\CompositeRelationships is incompatible with the type Illuminate\Database\Eloquent\Model expected by parameter $child of MaksimM\CompositePrimary...onships::newBelongsTo(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

64
            /** @scrutinizer ignore-type */ $this,
Loading history...
65
            $foreignKey,
66
            $ownerKey,
67
            $relation
68
        );
69
70
        return $relationQuery;
71
    }
72
73
    protected function executeWithinOptionalBinaryTransformation(Closure $relation, ...$models)
74
    {
75
        foreach ($models as $model) {
76
            if (method_exists($model, 'disableBinaryMutators')) {
77
                $model->disableBinaryMutators();
78
            }
79
        }
80
        $relationResult = $relation();
81
        foreach ($models as $model) {
82
            if (method_exists($model, 'enableBinaryMutators')) {
83
                $model->enableBinaryMutators();
84
            }
85
        }
86
87
        return $relationResult;
88
    }
89
90
    /**
91
     * Instantiate a new BelongsTo relationship.
92
     *
93
     * @param Builder $query
94
     * @param Model   $child
95
     * @param string  $foreignKey
96
     * @param string  $ownerKey
97
     * @param string  $relation
98
     *
99
     * @return BelongsTo
100
     */
101
    protected function newBelongsTo(Builder $query, Model $child, $foreignKey, $ownerKey, $relation)
102
    {
103
        return $this->executeWithinOptionalBinaryTransformation(function () use ($query, $child, $foreignKey, $ownerKey, $relation) {
104
            return new CompositeBelongsTo($query, $child, $foreignKey, $ownerKey, $relation);
105
        }, $query->getModel(), $child);
106
    }
107
108
    /**
109
     * Instantiate a new HasOne relationship.
110
     *
111
     * @param Builder $query
112
     * @param Model   $parent
113
     * @param string  $foreignKey
114
     * @param string  $localKey
115
     *
116
     * @return HasOne
117
     */
118
    protected function newHasOne(Builder $query, Model $parent, $foreignKey, $localKey)
119
    {
120
        return $this->executeWithinOptionalBinaryTransformation(function () use ($query, $parent, $foreignKey, $localKey) {
121
            return new HasOne($query, $parent, $foreignKey, $localKey);
122
        }, $query->getModel(), $parent);
123
    }
124
125
    /**
126
     * Instantiate a new MorphOne relationship.
127
     *
128
     * @param Builder $query
129
     * @param Model   $parent
130
     * @param string  $type
131
     * @param string  $id
132
     * @param string  $localKey
133
     *
134
     * @return MorphOne
135
     */
136
    protected function newMorphOne(Builder $query, Model $parent, $type, $id, $localKey)
137
    {
138
        return $this->executeWithinOptionalBinaryTransformation(function () use ($query, $parent, $type, $id, $localKey) {
139
            return new MorphOne($query, $parent, $type, $id, $localKey);
140
        }, $query->getModel(), $parent);
141
    }
142
143
    /**
144
     * Instantiate a new MorphTo relationship.
145
     *
146
     * @param Builder $query
147
     * @param Model   $parent
148
     * @param string  $foreignKey
149
     * @param string  $ownerKey
150
     * @param string  $type
151
     * @param string  $relation
152
     *
153
     * @return MorphTo
154
     */
155
    protected function newMorphTo(Builder $query, Model $parent, $foreignKey, $ownerKey, $type, $relation)
156
    {
157
        return $this->executeWithinOptionalBinaryTransformation(function () use ($query, $parent, $foreignKey, $ownerKey, $type, $relation) {
158
            return new MorphTo($query, $parent, $foreignKey, $ownerKey, $type, $relation);
159
        }, $query->getModel(), $parent);
160
    }
161
162
    /**
163
     * Instantiate a new HasMany relationship.
164
     *
165
     * @param Builder $query
166
     * @param Model   $parent
167
     * @param string  $foreignKey
168
     * @param string  $localKey
169
     *
170
     * @return HasMany
171
     */
172
    protected function newHasMany(Builder $query, Model $parent, $foreignKey, $localKey)
173
    {
174
        return $this->executeWithinOptionalBinaryTransformation(function () use ($query, $parent, $foreignKey, $localKey) {
175
            return new HasMany($query, $parent, $foreignKey, $localKey);
176
        }, $query->getModel(), $parent);
177
    }
178
179
    /**
180
     * Instantiate a new HasManyThrough relationship.
181
     *
182
     * @param Builder $query
183
     * @param Model   $farParent
184
     * @param Model   $throughParent
185
     * @param string  $firstKey
186
     * @param string  $secondKey
187
     * @param string  $localKey
188
     * @param string  $secondLocalKey
189
     *
190
     * @return HasManyThrough
191
     */
192
    protected function newHasManyThrough(Builder $query, Model $farParent, Model $throughParent, $firstKey, $secondKey, $localKey, $secondLocalKey)
193
    {
194
        return $this->executeWithinOptionalBinaryTransformation(function () use ($query, $farParent, $throughParent, $firstKey, $secondKey, $localKey, $secondLocalKey) {
195
            return new HasManyThrough($query, $farParent, $throughParent, $firstKey, $secondKey, $localKey, $secondLocalKey);
196
        }, $query->getModel(), $farParent);
197
    }
198
199
    /**
200
     * Instantiate a new MorphMany relationship.
201
     *
202
     * @param Builder $query
203
     * @param Model   $parent
204
     * @param string  $type
205
     * @param string  $id
206
     * @param string  $localKey
207
     *
208
     * @return MorphMany
209
     */
210
    protected function newMorphMany(Builder $query, Model $parent, $type, $id, $localKey)
211
    {
212
        return $this->executeWithinOptionalBinaryTransformation(function () use ($query, $parent, $type, $id, $localKey) {
213
            return new MorphMany($query, $parent, $type, $id, $localKey);
214
        }, $query->getModel(), $parent);
215
    }
216
217
    /**
218
     * Instantiate a new BelongsToMany relationship.
219
     *
220
     * @param Builder $query
221
     * @param Model   $parent
222
     * @param string  $table
223
     * @param string  $foreignPivotKey
224
     * @param string  $relatedPivotKey
225
     * @param string  $parentKey
226
     * @param string  $relatedKey
227
     * @param string  $relationName
228
     *
229
     * @return BelongsToMany
230
     */
231
    protected function newBelongsToMany(
232
        Builder $query,
233
        Model $parent,
234
        $table,
235
        $foreignPivotKey,
236
        $relatedPivotKey,
237
        $parentKey,
238
        $relatedKey,
239
        $relationName = null
240
    ) {
241
        return $this->executeWithinOptionalBinaryTransformation(function () use ($query, $parent, $table, $foreignPivotKey, $relatedPivotKey, $parentKey, $relatedKey, $relationName) {
242
            return new CompositeBelongsToMany($query, $parent, $table, $foreignPivotKey, $relatedPivotKey, $parentKey, $relatedKey, $relationName);
243
        }, $query->getModel(), $parent);
244
    }
245
246
    /**
247
     * Instantiate a new MorphToMany relationship.
248
     *
249
     * @param Builder $query
250
     * @param Model   $parent
251
     * @param string  $name
252
     * @param string  $table
253
     * @param string  $foreignPivotKey
254
     * @param string  $relatedPivotKey
255
     * @param string  $parentKey
256
     * @param string  $relatedKey
257
     * @param string  $relationName
258
     * @param bool    $inverse
259
     *
260
     * @return MorphToMany
261
     */
262
    protected function newMorphToMany(
263
        Builder $query,
264
        Model $parent,
265
        $name,
266
        $table,
267
        $foreignPivotKey,
268
        $relatedPivotKey,
269
        $parentKey,
270
        $relatedKey,
271
        $relationName = null,
272
        $inverse = false
273
    ) {
274
        return $this->executeWithinOptionalBinaryTransformation(function () use ($query, $parent, $name, $table, $foreignPivotKey, $relatedPivotKey, $parentKey, $relatedKey,
275
            $relationName, $inverse) {
276
            return new MorphToMany(
277
                $query,
278
                $parent,
279
                $name,
280
                $table,
281
                $foreignPivotKey,
282
                $relatedPivotKey,
283
                $parentKey,
284
                $relatedKey,
285
                $relationName,
286
                $inverse
287
            );
288
        }, $query->getModel(), $parent);
289
    }
290
}
291