Completed
Pull Request — master (#49)
by
unknown
01:21
created

RelationMapper::getDetails()   B

Complexity

Conditions 7
Paths 19

Size

Total Lines 77

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 77
rs 7.5684
c 0
b 0
f 0
cc 7
nc 19
nop 2

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Mtolhuys\LaravelSchematics\Services;
4
use Mtolhuys\LaravelSchematics\Services\Pivot as PivotService;
5
6
use Illuminate\Database\Eloquent\Relations\Relation;
7
use Illuminate\Database\Eloquent\Model;
8
9
use ReflectionException;
10
use ReflectionClass;
11
use ReflectionMethod;
12
use Config;
13
14
class RelationMapper extends ClassReader
15
{
16
	public static $relations = [];
17
	public static $models = [];
18
19
    /**
20
     * Maps relations details map through array of Eloquent models
21
     *
22
     * @param null $models
23
     * @return array
24
     * @throws ReflectionException
25
     */
26
    public static function map($models = null): array
27
    {
28
		$models = $models ?? ModelMapper::map();
29
		self::$models = $models;
30
        foreach ($models as $model) {
31
            self::getMethods($model)->each(static function ($method) use ($model) {
32
				$details = self::getDetails($method, $model);
33
				if ($details) {
34
					if (empty(self::$relations[$details->table])) {
35
						self::$relations[$details->table] = [];
36
					}
37
					self::$relations[$details->table][] = $details;
38
					
39
					$usePivot = Config::get('schematics.use-pivot');
40
					if ($usePivot && $details->type == "BelongsToMany" && isset($details->pivotsTo)){
41
						if (empty(self::$relations[$details->relation->table])) {
42
							self::$relations[$details->relation->table] = [];
43
						}
44
						self::$relations[$details->relation->table][] = $details->pivotsTo;
45
						unset( $details->pivotsTo);
46
					}
47
                }
48
            });
49
        }
50
        return self::$relations;
51
    }
52
53
    /**
54
     * @param ReflectionMethod $method
55
     * @param string $model
56
     * @return object|null
57
     */
58
    protected static function getDetails(ReflectionMethod $method, string $model)
59
    {
60
		$usePivot = Config::get('schematics.use-pivot');
61
        try {
62
            $class = app($model);
63
            $invocation = $method->invoke($class);
64
65
            if ($invocation instanceof Relation) {
66
				if ($usePivot && get_class($invocation) === "Illuminate\Database\Eloquent\Relations\BelongsToMany"){
67
					$pivotModel = PivotService::getPivotModel($method);
68
					if (!$pivotModel){
69
						$pivotModel = PivotService::getPivotModelFallback($class, $invocation, $method, self::$models);
70
					}
71
					if ($pivotModel){
72
						$dst = $invocation->getRelated();
73
						//TODO: neater way to create these objects
74
						$result = (object)[
75
							'model' => $model,
76
							'table' =>  $class->getTable(),
77
							'type' => 'BelongsToMany',
78
79
							'relation' => (object)[
80
								'model' => get_class($pivotModel),
81
								'table' => $pivotModel->getTable(),
82
								'pivotsTo' => get_class($dst),
83
							],
84
							'method' => (object)[
85
								'name' => $method->getName(),
86
								'file' => $method->getFileName(),
87
								'line' => $method->getStartLine(),
88
							],
89
						];
90
						$pivotsTo = (object)[
91
							'model' => $model,
92
							'table' =>  $class->getTable(),
93
							'type' => 'BelongsToMany',
94
95
							'relation' => (object)[
96
								'model' => get_class($dst),
97
								'table' => $dst->getTable(),
98
								'pivotsFrom' => $model
99
							],
100
							'method' => (object)[
101
								'model' => $model, //To make it clear in GUI that function does not come from pivot model, this should be shown in GUI
102
								'name' => $method->getName(),
103
								'file' => $method->getFileName(),
104
								'line' => $method->getStartLine(),
105
							],
106
						];
107
						$result->pivotsTo = $pivotsTo;
108
					} else {
109
						return NULL;
110
					}
111
				} else {
112
					$related = $invocation->getRelated();
113
					$result = (object)[
114
						'model' => $model,
115
						'table' => $class->getTable(),
116
						'type' => (new ReflectionClass($invocation))->getShortName(),
117
						'relation' => (object)[
118
							'model' => get_class($related),
119
							'table' => $related->getTable(),
120
						],
121
						'method' => (object)[
122
							'name' => $method->getName(),
123
							'file' => $method->getFileName(),
124
							'line' => $method->getStartLine(),
125
						],
126
					];
127
				}	
128
				return $result;
129
            }
130
		}
131
        catch (\Throwable $e) {
132
            return null;
133
        }
134
	}
135
}