Passed
Push — master ( 29235d...f90111 )
by Iman
07:03
created

DynamicRelations::defineNewMethod()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 3
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
crap 2
1
<?php
2
3
namespace Imanghafoori\Relativity;
4
5
use Illuminate\Support\Str;
6
7
trait DynamicRelations
8
{
9
    use BaseEloquentOverrides;
10
11
    protected static $dynamicRelations = [];
12
13 1
    public function getDynamicRelations()
14
    {
15 1
        return static::$dynamicRelations;
16
    }
17
18
    public static function defineNewMethod($name, $closure)
19
    {
20
        static::$dynamicRelations[$name] = $closure;
21
    }
22
23 1
    public function hasDynamicRelation(string $relation)
24
    {
25 1
        return isset(static::$dynamicRelations[$relation]);
26
    }
27
28 2
    public static function removeRelation(string $relationName)
29
    {
30 2
        if (! isset(static::$dynamicRelations[$relationName])) {
31 1
            throw new Exceptions\UndefinedDynamicRelationException($relationName);
32
        }
33
34 1
        unset(static::$dynamicRelations[$relationName]);
35 1
    }
36
37 8
    public static function defineRelation($relationType, $relationName, $data, $constraints)
38
    {
39
        $method = function () use ($relationType, $data, $constraints) {
40 7
            $relation = $this->{$relationType} (...$data);
41 7
            foreach ($constraints as $cons) {
42 1
                $relation = $relation->{$cons[0]}(...$cons[1]);
43
            }
44
45 7
            return $relation;
46 8
        };
47
48 8
        static::$dynamicRelations[$relationName] = $method;
49 8
    }
50
51
    /**
52
     * Dynamically handle calls to the class.
53
     *
54
     * @param  string  $method
55
     * @param  array   $parameters
56
     * @return mixed
57
     *
58
     * @throws \BadMethodCallException
59
     */
60 7
    public function __call($method, $parameters)
61
    {
62 7
        $dynamicRelation = static::$dynamicRelations[$method] ?? null;
63 7
        if (! $dynamicRelation) {
64 7
            return parent::__call($method, $parameters);
65
        }
66
67 7
        return call_user_func_array($dynamicRelation->bindTo($this, static::class), $parameters);
68
    }
69
70
    /**
71
     * Define a polymorphic, inverse many-to-many relationship.
72
     *
73
     * @param  string  $relationName
74
     * @param  string  $related
75
     * @param  string  $name
76
     * @param  string  $table
77
     * @param  string  $foreignPivotKey
78
     * @param  string  $relatedPivotKey
79
     * @param  string  $parentKey
80
     * @param  string  $relatedKey
81
     *
82
     * @return \Illuminate\Database\Eloquent\Relations\MorphToMany
83
     */
84 1
    public static function morphed_by_many($relationName, $related, $name, $table = null, $foreignPivotKey = null,
85
        $relatedPivotKey = null, $parentKey = null, $relatedKey = null)
86
    {
87 1
        return new AbstractRelation(['morphedByMany', static::class, $relationName, [$related, $name, $table, $foreignPivotKey,
88 1
            $relatedPivotKey, $parentKey, $relatedKey, $relationName, ]]);
89
    }
90
91
    /**
92
     * @param string $relationName
93
     * @param string $related
94
     * @param null $foreignKey
95
     * @param null $localKey
96
     *
97
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
98
     */
99 3
    public static function has_many($relationName, $related, $foreignKey = null, $localKey = null)
100
    {
101 3
        return new AbstractRelation(['hasMany', static::class, $relationName, [$related, $foreignKey, $localKey]]);
102
    }
103
104
    /**
105
     * Define a one-to-one relationship.
106
     *
107
     * @param  string  $relationName
108
     * @param  string  $related
109
     * @param  string  $foreignKey
110
     * @param  string  $localKey
111
     *
112
     * @return \Illuminate\Database\Eloquent\Relations\HasOne
113
     */
114 1
    public static function has_one($relationName, $related, $foreignKey = null, $localKey = null)
115
    {
116 1
        return new AbstractRelation(['hasOne', static::class, $relationName, [$related, $foreignKey, $localKey]]);
117
    }
118
119
    /**
120
     * @param string $relationName
121
     * @param string $related
122
     * @param null $foreignKey
123
     * @param null $ownerKey
124
     *
125
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
126
     */
127 1
    public static function belongs_to($relationName, string $related, $foreignKey = null, $ownerKey = null)
128
    {
129 1
        if (is_null($foreignKey)) {
130
            $foreignKey = Str::snake($relationName).'_id';
131
        }
132
133 1
        return new AbstractRelation(['belongsTo', static::class, $relationName, [$related, $foreignKey, $ownerKey, $relationName]]);
134
    }
135
136
    /**
137
     * Define a many-to-many relationship.
138
     *
139
     * @param  string  $relationName
140
     * @param  string  $related
141
     * @param  string  $table
142
     * @param  string  $foreignPivotKey
143
     * @param  string  $relatedPivotKey
144
     * @param  string  $parentKey
145
     * @param  string  $relatedKey
146
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
147
     */
148 1
    public static function belongs_to_many($relationName, $related, $table = null, $foreignPivotKey = null, $relatedPivotKey = null,
149
        $parentKey = null, $relatedKey = null)
150
    {
151 1
        $params = [$related, $table, $foreignPivotKey, $relatedPivotKey, $parentKey, $relatedKey, $relationName];
152
153 1
        return new AbstractRelation(['belongsToMany', static::class, $relationName, $params]);
154
    }
155
156
    /**
157
     * Define a polymorphic many-to-many relationship.
158
     *
159
     * @param  string  $relationName
160
     * @param  string  $related
161
     * @param  string  $name
162
     * @param  string  $table
163
     * @param  string  $foreignPivotKey
164
     * @param  string  $relatedPivotKey
165
     * @param  string  $parentKey
166
     * @param  string  $relatedKey
167
     * @param  bool  $inverse
168
     * @return \Illuminate\Database\Eloquent\Relations\MorphToMany
169
     */
170 1
    public static function morph_to_many($relationName, $related, $name, $table = null, $foreignPivotKey = null,
171
        $relatedPivotKey = null, $parentKey = null,
172
        $relatedKey = null, $inverse = false)
173
    {
174 1
        $params = [$related, $name, $table, $foreignPivotKey,
175 1
            $relatedPivotKey, $parentKey, $relatedKey, $inverse, $relationName, ];
176
177 1
        return new AbstractRelation(['morphToMany', static::class, $relationName, $params]);
178
    }
179
180
    /**
181
     * Define a polymorphic one-to-many relationship.
182
     *
183
     * @param  string  $relationName
184
     * @param  string  $related
185
     * @param  string  $name
186
     * @param  string  $type
187
     * @param  string  $id
188
     * @param  string  $localKey
189
     * @return \Illuminate\Database\Eloquent\Relations\MorphMany
190
     */
191 1
    public static function morph_many($relationName, $related, $name, $type = null, $id = null, $localKey = null)
192
    {
193 1
        $params = [$related, $name, $type, $id, $localKey];
194
195 1
        return new AbstractRelation(['morphMany', static::class, $relationName, $params]);
196
    }
197
198
    /**
199
     * Define a polymorphic one-to-one relationship.
200
     *
201
     * @param  string  $relationName
202
     * @param  string  $related
203
     * @param  string  $name
204
     * @param  string  $type
205
     * @param  string  $id
206
     * @param  string  $localKey
207
     * @return \Illuminate\Database\Eloquent\Relations\MorphOne
208
     */
209
    public static function morph_one($relationName, $related, $name, $type = null, $id = null, $localKey = null)
210
    {
211
        $params = [$related, $name, $type, $id, $localKey];
212
213
        return new AbstractRelation(['morphOne', static::class, $relationName, $params]);
214
    }
215
216
    /**
217
     * Define a polymorphic, inverse one-to-one or many relationship.
218
     *
219
     * @param  string  $relationName
220
     * @param  string  $type
221
     * @param  string  $id
222
     * @param  string  $ownerKey
223
     * @return \Illuminate\Database\Eloquent\Relations\MorphTo
224
     */
225 1
    public static function morph_to($relationName, $type = null, $id = null, $ownerKey = null)
226
    {
227 1
        $params = [$relationName, $type, $id, $ownerKey];
228
229 1
        return new AbstractRelation(['morphTo', static::class, $relationName, $params]);
230
    }
231
232
    /**
233
     * Define a has-many-through relationship.
234
     *
235
     * @param  string  $relationName
236
     * @param  string  $related
237
     * @param  string  $through
238
     * @param  string|null  $firstKey
239
     * @param  string|null  $secondKey
240
     * @param  string|null  $localKey
241
     * @param  string|null  $secondLocalKey
242
     * @return \Illuminate\Database\Eloquent\Relations\HasManyThrough
243
     */
244 1
    public static function has_many_through($relationName, $related, $through, $firstKey = null, $secondKey = null, $localKey = null, $secondLocalKey = null)
245
    {
246 1
        $params = [$related, $through, $firstKey, $secondKey, $localKey, $secondLocalKey];
247
248 1
        return new AbstractRelation(['hasManyThrough', static::class, $relationName, $params]);
249
    }
250
251 1
    public static function forceEagerLoading(...$relation)
252
    {
253
        static::registerModelEvent('booting', function ($model) use ($relation) {
254 1
            $model->with = $model->with + $relation;
255 1
        });
256 1
    }
257
}
258