Completed
Push — master ( 31e550...936008 )
by Maarten
01:19
created

RelationMapper::getMethods()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 16
rs 9.7333
c 0
b 0
f 0
cc 2
nc 1
nop 1
1
<?php
2
3
namespace Mtolhuys\LaravelSchematics\Services;
4
5
use Illuminate\Database\Eloquent\Relations\Relation;
6
7
use ReflectionException;
8
use Illuminate\Support\Collection;
9
use ReflectionClass;
10
use ReflectionMethod;
11
12
class RelationMapper
13
{
14
    public static $relations = [];
15
16
    /**
17
     * Maps relations details map through array of Eloquent models
18
     *
19
     * @param null $models
20
     * @return array
21
     * @throws ReflectionException
22
     */
23
    public static function map($models = null): array
24
    {
25
        $models = $models ?? ModelMapper::map();
26
27
        foreach ($models as $model) {
28
            foreach (self::getMethods($model) as $method) {
29
                $details = self::getDetails($method, $model);
30
31
                if ($details) {
32
                    if (empty(self::$relations[$details->table])) {
33
                        self::$relations[$details->table] = [];
34
                    }
35
36
                    self::$relations[$details->table][] = $details;
37
                }
38
            }
39
        }
40
41
        return self::$relations;
42
    }
43
44
    /**
45
     * @param string $model
46
     * @return Collection
47
     * @throws ReflectionException
48
     */
49
    public static function getMethods(string $model)
50
    {
51
        $class = new ReflectionClass($model);
52
53
        return Collection::make($class->getMethods(ReflectionMethod::IS_PUBLIC))
54
            ->merge(Collection::make($class->getTraits())
55
                ->map(function (ReflectionClass $trait) {
56
                    return Collection::make(
57
                        $trait->getMethods(ReflectionMethod::IS_PUBLIC)
58
                    );
59
                })->flatten()
60
            )
61
            ->reject(function (ReflectionMethod $method) use ($model) {
62
                return $method->class !== $model || $method->getNumberOfParameters() > 0;
63
            });
64
    }
65
66
    /**
67
     * @param ReflectionMethod $method
68
     * @param string $model
69
     * @return object|null
70
     */
71
    protected static function getDetails(ReflectionMethod $method, string $model)
72
    {
73
        try {
74
            $class = app($model);
75
            $invocation = $method->invoke($class);
76
77
            if ($invocation instanceof Relation) {
78
                $related = $invocation->getRelated();
79
80
                return (object)[
81
                    'model' => $model,
82
                    'table' => $class->getTable(),
83
                    'type' => (new ReflectionClass($invocation))->getShortName(),
84
                    'relation' => (object)[
85
                        'model' => get_class($related),
86
                        'table' => $related->getTable(),
87
                    ],
88
                    'method' => (object)[
89
                        'name' => $method->getName(),
90
                        'file' => $method->getFileName(),
91
                        'line' => $method->getStartLine(),
92
                    ],
93
                ];
94
            }
95
        } catch (\Throwable $e) {}
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
96
97
        return null;
98
    }
99
100
}
101