Passed
Push — v2 ( b247ab...8c624d )
by Alexander
02:21
created

HasRelationships   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 118
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
dl 0
loc 118
ccs 0
cts 17
cp 0
rs 10
c 0
b 0
f 0
wmc 9
lcom 1
cbo 2

8 Methods

Rating   Name   Duplication   Size   Complexity  
resolveContainer() 0 1 ?
A allowsAllRelations() 0 4 1
A getRelations() 0 6 1
A getDefaultRelations() 0 4 1
A extractDefaultRelations() 0 12 1
A getDefaultRelationsWithEagerLoads() 0 10 2
A makeEagerLoadCallback() 0 6 1
A resolveRelation() 0 8 2
1
<?php
2
3
namespace Flugg\Responder\Transformers\Concerns;
4
5
use Closure;
6
use Illuminate\Contracts\Container\Container;
7
use Illuminate\Database\Eloquent\Model;
8
use Illuminate\Support\Collection;
9
10
/**
11
 * A trait to be used by a transformer to handle relations
12
 *
13
 * @package flugger/laravel-responder
14
 * @author  Alexander Tømmerås <[email protected]>
15
 * @license The MIT License
16
 */
17
trait HasRelationships
18
{
19
    /**
20
     * List of available relations.
21
     *
22
     * @var string[]
23
     */
24
    protected $relations = ['*'];
25
26
    /**
27
     * A list of autoloaded default relations.
28
     *
29
     * @var array
30
     */
31
    protected $load = [];
32
33
    /**
34
     * Indicates if all relations are allowed.
35
     *
36
     * @return bool
37
     */
38
    public function allowsAllRelations(): bool
39
    {
40
        return $this->relations == ['*'];
41
    }
42
43
    /**
44
     * Get a list of whitelisted relations.
45
     *
46
     * @return string[]
47
     */
48
    public function getRelations(): array
49
    {
50
        return array_filter($this->relations, function ($relation) {
51
            return $relation != '*';
52
        });
53
    }
54
55
    /**
56
     * Get a list of default relations.
57
     *
58
     * @return string[]
59
     */
60
    public function getDefaultRelations(): array
61
    {
62
        return array_keys($this->load);
63
    }
64
65
    /**
66
     * Extract a deep list of default relations, recursively.
67
     *
68
     * @return string[]
69
     */
70
    public function extractDefaultRelations(): array
71
    {
72
        return collect($this->getDefaultRelationsWithEagerLoads())
73
            ->merge(collect($this->load)->map(function ($transformer, $relation) {
74
                return collect($this->resolveContainer()->make($transformer)->extractDefaultRelations())
75
                    ->keys()
76
                    ->map(function ($nestedRelation) use ($relation) {
77
                        return "$relation.$nestedRelation";
0 ignored issues
show
Coding Style Best Practice introduced by
As per coding-style, please use concatenation or sprintf for the variable $relation instead of interpolation.

It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings.

// Instead of
$x = "foo $bar $baz";

// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
Loading history...
Coding Style Best Practice introduced by
As per coding-style, please use concatenation or sprintf for the variable $nestedRelation instead of interpolation.

It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings.

// Instead of
$x = "foo $bar $baz";

// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
Loading history...
78
                    });
79
            }))
80
            ->all();
81
    }
82
83
    /**
84
     *
85
     *
86
     * @return string[]
87
     */
88
    protected function getDefaultRelationsWithEagerLoads(): array
89
    {
90
        return collect($this->load)->keys()->mapWithKeys(function ($relation) {
91
            if (method_exists($this, $method = 'load' . ucfirst($relation))) {
92
                return [$relation => $this->makeEagerLoadCallback($method)];
93
            }
94
95
            return [$relation => function () { }];
96
        })->all();
97
    }
98
99
    /**
100
     *
101
     *
102
     * @param  string $method
103
     * @return \Closure
104
     */
105
    protected function makeEagerLoadCallback(string $method): Closure
106
    {
107
        return function ($query) use ($method) {
108
            return $this->$method($query);
109
        };
110
    }
111
112
    /**
113
     *
114
     *
115
     * @param \Illuminate\Database\Eloquent\Model $model
116
     * @param  string                             $identifier
117
     * @return mixed
118
     */
119
    protected function resolveRelation(Model $model, string $identifier)
120
    {
121
        if (method_exists($this, $method = 'filter' . ucfirst($identifier))) {
122
            return $this->$method($model->$identifier);
123
        }
124
125
        return $model->$identifier;
126
    }
127
128
    /**
129
     * Resolve a container using the resolver callback.
130
     *
131
     * @return \Illuminate\Contracts\Container\Container
132
     */
133
    protected abstract function resolveContainer(): Container;
134
}