Completed
Push — master ( 026811...d027d5 )
by
unknown
01:11
created

RelationFinder::getParentKey()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
namespace BeyondCode\ErdGenerator;
4
5
use Illuminate\Database\Eloquent\Relations\BelongsTo;
6
use Illuminate\Database\Eloquent\Relations\HasOneOrMany;
7
use Illuminate\Database\Eloquent\Relations\Relation;
8
use Illuminate\Support\Collection;
9
use ReflectionClass;
10
use ReflectionMethod;
11
12
class RelationFinder
13
{
14
    /**
15
     * Return all relations from a fully qualified model class name.
16
     *
17
     * @param string $model
18
     * @return Collection
19
     * @throws \ReflectionException
20
     */
21
    public function getModelRelations(string $model)
22
    {
23
        $class = new ReflectionClass($model);
24
25
        $traitMethods = Collection::make($class->getTraits())->map(function (ReflectionClass $trait) {
26
            return Collection::make($trait->getMethods(ReflectionMethod::IS_PUBLIC));
27
        })->flatten();
28
29
        $methods = Collection::make($class->getMethods(ReflectionMethod::IS_PUBLIC))
30
            ->merge($traitMethods)
31
            ->reject(function (ReflectionMethod $method) use ($model) {
32
                return $method->class !== $model || $method->getNumberOfParameters() > 0;
33
            });
34
35
        $relations = Collection::make();
36
37
        $methods->map(function (ReflectionMethod $method) use ($model, &$relations) {
38
            $relations = $relations->merge($this->getRelationshipFromMethodAndModel($method, $model));
39
        });
40
41
        $relations = $relations->filter();
42
43
        if ($ignoreRelations = array_get(config('erd-generator.ignore', []),$model))
0 ignored issues
show
Deprecated Code introduced by
The function array_get() has been deprecated with message: Arr::get() should be used directly instead. Will be removed in Laravel 6.0.

This function has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.

Loading history...
44
        {
45
            $relations = $relations->diffKeys(array_flip($ignoreRelations));
46
        }
47
48
        return $relations;
49
    }
50
51
    /**
52
     * @param string $qualifiedKeyName
53
     * @return mixed
54
     */
55
    protected function getParentKey(string $qualifiedKeyName)
56
    {
57
        $segments = explode('.', $qualifiedKeyName);
58
59
        return end($segments);
60
    }
61
62
    /**
63
     * @param ReflectionMethod $method
64
     * @param string $model
65
     * @return array|null
66
     */
67
    protected function getRelationshipFromMethodAndModel(ReflectionMethod $method, string $model)
68
    {
69
        try {
70
            $return = $method->invoke(app($model));
71
72
            if ($return instanceof Relation) {
73
                $localKey = null;
74
                $foreignKey = null;
75
76
                if ($return instanceof HasOneOrMany) {
77
                    $localKey = $this->getParentKey($return->getQualifiedParentKeyName());
78
                    $foreignKey = $return->getForeignKeyName();
79
                }
80
81
                if ($return instanceof BelongsTo) {
82
                    $foreignKey = $this->getParentKey($return->getQualifiedOwnerKeyName());
83
                    $localKey = method_exists($return, 'getForeignKeyName') ? $return->getForeignKeyName() : $return->getForeignKey();
0 ignored issues
show
Bug introduced by
The method getForeignKey() does not exist on Illuminate\Database\Eloquent\Relations\BelongsTo. Did you maybe mean getForeignKeyName()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
84
                }
85
86
                return [
87
                    $method->getName() => new ModelRelation(
88
                        $method->getShortName(),
89
                        (new ReflectionClass($return))->getShortName(),
90
                        (new ReflectionClass($return->getRelated()))->getName(),
91
                        $localKey,
92
                        $foreignKey
93
                    )
94
                ];
95
            }
96
        } catch (\Throwable $e) {}
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
97
        return null;
98
    }
99
    
100
}
101