GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

RelationHelper::getModelRelations()   B
last analyzed

Complexity

Conditions 7
Paths 10

Size

Total Lines 37

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 37
rs 8.3946
c 0
b 0
f 0
cc 7
nc 10
nop 1
1
<?php
2
3
namespace Neurony\Duplicate\Helpers;
4
5
use Illuminate\Database\Eloquent\Model;
6
use Illuminate\Database\Eloquent\Relations\BelongsTo;
7
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
8
use Illuminate\Database\Eloquent\Relations\HasMany;
9
use Illuminate\Database\Eloquent\Relations\HasOne;
10
use Illuminate\Database\Eloquent\Relations\MorphMany;
11
use Illuminate\Database\Eloquent\Relations\MorphOne;
12
use Illuminate\Database\Eloquent\Relations\MorphTo;
13
use Illuminate\Database\Eloquent\Relations\MorphToMany;
14
use Illuminate\Database\Eloquent\Relations\Relation;
15
use ReflectionException;
16
use ReflectionMethod;
17
use SplFileObject;
18
19
class RelationHelper
20
{
21
    /**
22
     * List of all relations defined on a model class.
23
     *
24
     * @var array
25
     */
26
    protected static $relations = [];
27
28
    /**
29
     * Laravel's available relation types (classes|methods).
30
     *
31
     * @var array
32
     */
33
    protected static $relationTypes = [
34
        'hasOne',
35
        'hasMany',
36
        'hasManyThrough',
37
        'belongsTo',
38
        'belongsToMany',
39
        'morphOne',
40
        'morphMany',
41
        'morphTo',
42
        'morphToMany',
43
    ];
44
45
    /**
46
     * All available Laravel's direct relations.
47
     *
48
     * @var array
49
     */
50
    protected static $directRelations = [
51
        HasOne::class,
52
        MorphOne::class,
53
        HasMany::class,
54
        MorphMany::class,
55
        BelongsTo::class,
56
        MorphTo::class,
57
    ];
58
59
    /**
60
     * All available Laravel's pivoted relations.
61
     *
62
     * @var array
63
     */
64
    protected static $pivotedRelations = [
65
        BelongsToMany::class,
66
        MorphToMany::class,
67
    ];
68
69
    /**
70
     * All available Laravel's direct parent relations.
71
     *
72
     * @var array
73
     */
74
    protected static $parentRelations = [
75
        BelongsTo::class,
76
        MorphTo::class,
77
    ];
78
79
    /**
80
     * All available Laravel's direct child relations.
81
     *
82
     * @var array
83
     */
84
    protected static $childRelations = [
85
        HasOne::class,
86
        MorphOne::class,
87
        HasMany::class,
88
        MorphMany::class,
89
    ];
90
91
    /**
92
     * All available Laravel's direct single child relations.
93
     *
94
     * @var array
95
     */
96
    protected static $childRelationsSingle = [
97
        HasOne::class,
98
        MorphOne::class,
99
    ];
100
101
    /**
102
     * All available Laravel's direct multiple children relations.
103
     *
104
     * @var array
105
     */
106
    protected static $childRelationsMultiple = [
107
        HasMany::class,
108
        MorphMany::class,
109
    ];
110
111
    /**
112
     * Verify if a given relation is direct or not.
113
     *
114
     * @param string $relation
115
     * @return bool
116
     */
117
    public static function isDirect(string $relation): bool
118
    {
119
        return in_array($relation, static::$directRelations);
120
    }
121
122
    /**
123
     * Verify if a given relation is pivoted or not.
124
     *
125
     * @param string $relation
126
     * @return bool
127
     */
128
    public static function isPivoted(string $relation): bool
129
    {
130
        return in_array($relation, static::$pivotedRelations);
131
    }
132
133
    /**
134
     * Verify if a given direct relation is of type parent.
135
     *
136
     * @param string $relation
137
     * @return bool
138
     */
139
    public static function isParent(string $relation): bool
140
    {
141
        return in_array($relation, static::$parentRelations);
142
    }
143
144
    /**
145
     * Verify if a given direct relation is of type child.
146
     *
147
     * @param string $relation
148
     * @return bool
149
     */
150
    public static function isChild(string $relation): bool
151
    {
152
        return in_array($relation, static::$childRelations);
153
    }
154
155
    /**
156
     * Verify if a given direct relation is of type single child.
157
     * Ex: hasOne, morphOne.
158
     *
159
     * @param string $relation
160
     * @return bool
161
     */
162
    public static function isChildSingle(string $relation): bool
163
    {
164
        return in_array($relation, static::$childRelationsSingle);
165
    }
166
167
    /**
168
     * Verify if a given direct relation is of type single child.
169
     * Ex: hasMany, morphMany.
170
     *
171
     * @param string $relation
172
     * @return bool
173
     */
174
    public static function isChildMultiple(string $relation): bool
175
    {
176
        return in_array($relation, static::$childRelationsMultiple);
177
    }
178
179
    /**
180
     * Get all the defined model class relations.
181
     * Not just the eager loaded ones present in the $relations Eloquent property.
182
     *
183
     * @param Model $model
184
     * @return array
185
     * @throws ReflectionException
186
     */
187
    public static function getModelRelations(Model $model): array
188
    {
189
        foreach (get_class_methods($model) as $method) {
190
            if (! method_exists(Model::class, $method)) {
191
                $reflection = new ReflectionMethod($model, $method);
192
                $file = new SplFileObject($reflection->getFileName());
193
                $code = '';
194
195
                $file->seek($reflection->getStartLine() - 1);
196
197
                while ($file->key() < $reflection->getEndLine()) {
198
                    $code .= $file->current();
199
                    $file->next();
200
                }
201
202
                $code = trim(preg_replace('/\s\s+/', '', $code));
203
                $begin = strpos($code, 'function(');
204
                $code = substr($code, $begin, strrpos($code, '}') - $begin + 1);
205
206
                foreach (static::$relationTypes as $type) {
207
                    if (stripos($code, '$this->'.$type.'(')) {
208
                        $relation = $model->$method();
209
210
                        if ($relation instanceof Relation) {
211
                            static::$relations[$method] = [
212
                                'type' => get_class($relation),
213
                                'model' => $relation->getRelated(),
214
                                'original' => $relation->getParent(),
215
                            ];
216
                        }
217
                    }
218
                }
219
            }
220
        }
221
222
        return static::$relations;
223
    }
224
}
225