Relationships   A
last analyzed

Complexity

Total Complexity 9

Size/Duplication

Total Lines 115
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 9
eloc 62
c 1
b 0
f 0
dl 0
loc 115
ccs 28
cts 28
cp 1
rs 10

2 Methods

Rating   Name   Duplication   Size   Complexity  
A qualifyModel() 0 13 4
A get() 0 32 5
1
<?php
2
3
namespace Cerbero\EloquentInspector\Components;
4
5
use Cerbero\EloquentInspector\Concerns\ReadsModel;
6
use Cerbero\EloquentInspector\Dtos\Relationship;
7
use Cerbero\EloquentInspector\Inspector;
8
use Illuminate\Database\Eloquent\Relations;
9
use ReflectionClass;
10
use ReflectionMethod;
11
12
/**
13
 * The relationships component.
14
 *
15
 */
16
class Relationships extends Component
17
{
18
    use ReadsModel;
19
20
    /**
21
     * The relationships map.
22
     *
23
     * @var array
24
     */
25
    protected $relationsMap = [
26
        'hasOne' => [
27
            'class' => Relations\HasOne::class,
28
            'relatesToMany' => false,
29
        ],
30
        'hasOneThrough' => [
31
            'class' => Relations\HasOneThrough::class,
32
            'relatesToMany' => false,
33
        ],
34
        'morphOne' => [
35
            'class' => Relations\MorphOne::class,
36
            'relatesToMany' => false,
37
        ],
38
        'belongsTo' => [
39
            'class' => Relations\BelongsTo::class,
40
            'relatesToMany' => false,
41
        ],
42
        'morphTo' => [
43
            'class' => Relations\MorphTo::class,
44
            'relatesToMany' => false,
45
        ],
46
        'hasMany' => [
47
            'class' => Relations\HasMany::class,
48
            'relatesToMany' => true,
49
        ],
50
        'hasManyThrough' => [
51
            'class' => Relations\HasManyThrough::class,
52
            'relatesToMany' => true,
53
        ],
54
        'morphMany' => [
55
            'class' => Relations\MorphMany::class,
56
            'relatesToMany' => true,
57
        ],
58
        'belongsToMany' => [
59
            'class' => Relations\BelongsToMany::class,
60
            'relatesToMany' => true,
61
        ],
62
        'morphToMany' => [
63
            'class' => Relations\MorphToMany::class,
64
            'relatesToMany' => true,
65
        ],
66
        'morphedByMany' => [
67
            'class' => Relations\MorphToMany::class,
68
            'relatesToMany' => true,
69
        ],
70
    ];
71
72
    /**
73
     * Retrieve the model relationships
74
     *
75
     * @return array
76
     */
77 1
    public function get(): array
78
    {
79 1
        $relationships = [];
80 1
        $relations = implode('|', array_keys($this->relationsMap));
81 1
        $regex = "/\\\$this->($relations)\W+([\w\\\]+)/";
82 1
        $reflection = new ReflectionClass($this->model);
83 1
        $methods = $reflection->getMethods(ReflectionMethod::IS_PUBLIC);
84
85 1
        foreach ($methods as $method) {
86 1
            if ($method->getFileName() != $reflection->getFileName()) {
87 1
                continue;
88
            }
89
90 1
            if (!preg_match($regex, $this->readFirstLineOfMethod($method), $matches)) {
91 1
                continue;
92
            }
93
94 1
            [, $relation, $relatedModel] = $matches;
95
96 1
            if (!$qualifiedModel = $this->qualifyModel($relatedModel, $reflection)) {
97 1
                continue;
98
            }
99
100 1
            $relationships[$method->name] = $relationship = new Relationship();
101 1
            $relationship->name = $method->name;
102 1
            $relationship->type = $relation;
103 1
            $relationship->class = $this->relationsMap[$relation]['class'];
104 1
            $relationship->model = $qualifiedModel;
105 1
            $relationship->relatesToMany = $this->relationsMap[$relation]['relatesToMany'];
106
        }
107
108 1
        return $relationships;
109
    }
110
111
    /**
112
     * Retrieve the fully qualified class name of the given model
113
     *
114
     * @param string $model
115
     * @param ReflectionClass $reflection
116
     * @return string|null
117
     */
118 1
    protected function qualifyModel(string $model, ReflectionClass $reflection): ?string
119
    {
120 1
        if (class_exists($model)) {
121 1
            return $model;
122
        }
123
124 1
        $useStatements = Inspector::inspect($this->model)->getUseStatements();
125
126 1
        if (isset($useStatements[$model])) {
127 1
            return $useStatements[$model];
128
        }
129
130 1
        return class_exists($class = $reflection->getNamespaceName() . "\\{$model}") ? $class : null;
131
    }
132
}
133