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)) |
|
|
|
|
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(); |
|
|
|
|
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) {} |
|
|
|
|
97
|
|
|
return null; |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
} |
101
|
|
|
|
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.