Display::__call()   C
last analyzed

Complexity

Conditions 7
Paths 4

Size

Total Lines 24
Code Lines 13

Duplication

Lines 12
Ratio 50 %

Code Coverage

Tests 0
CRAP Score 56

Importance

Changes 0
Metric Value
dl 12
loc 24
c 0
b 0
f 0
ccs 0
cts 18
cp 0
rs 6.7272
cc 7
eloc 13
nc 4
nop 2
crap 56
1
<?php
2
3
namespace Sco\Admin\Display;
4
5
use Illuminate\Contracts\Support\Arrayable;
6
use Illuminate\Database\Eloquent\Builder;
7
use Illuminate\Database\Eloquent\Model;
8
use Sco\Admin\Contracts\RepositoryInterface;
9
use Sco\Admin\Contracts\Display\Extensions\ExtensionInterface;
10
use Sco\Admin\Contracts\Display\DisplayInterface;
11
use Sco\Admin\Display\Extensions\Applies;
12
use Sco\Admin\Display\Extensions\Filters;
13
use Sco\Admin\Display\Extensions\Scopes;
14
use Sco\Admin\Contracts\Display\Filters\FilterInterface;
15
16
/**
17
 * @method Scopes getScopes() get query scopes
18
 * @method $this setScopes($scope, ...$scopes) set query scopes
19
 * @method $this addScope($scope, $parameter, ...$parameters) add query scope
20
 *
21
 * @method Applies getApplies() get query applies
22
 * @method $this setApplies(\Closure $apply, ...$applies) set query applies
23
 * @method $this addApply(\Closure $apply) add query apply
24
 *
25
 * @method Filters getFilters()
26
 * @method $this setFilters(FilterInterface $filter, ...$filters)
27
 * @method $this addFilter(FilterInterface $filter)
28
 *
29
 */
30
abstract class Display implements DisplayInterface, Arrayable
31
{
32
    /**
33
     * @var array
34
     */
35
    protected $with = [];
36
37
    /**
38
     * @var \Illuminate\Database\Eloquent\Model
39
     */
40
    protected $model;
41
42
    /**
43
     * @var null|RepositoryInterface
44
     */
45
    protected $repository;
46
47
    protected $type;
48
49
    protected $extensions;
50
51
    abstract public function get();
52
53
    public function __construct()
54
    {
55
        $this->extensions = new Extensions();
56
57
        $this->extend('scopes', new Scopes());
58
        $this->extend('applies', new Applies());
59
        $this->extend('filters', new Filters());
60
    }
61
62
    /**
63
     * {@inheritdoc}
64
     */
65
    public function setModel(Model $model)
66
    {
67
        $this->model = $model;
68
69
        return $this;
70
    }
71
72
    /**
73
     * {@inheritdoc}
74
     */
75
    public function getModel()
76
    {
77
        return $this->model;
78
    }
79
80
    /**
81
     * {@inheritdoc}
82
     */
83
    public function extend($name, ExtensionInterface $extension)
84
    {
85
        $this->extensions->put($name, $extension);
86
87
        return $this;
88
    }
89
90
    protected function makeRepository()
91
    {
92
        $repository = app(RepositoryInterface::class)
93
            ->setModel($this->getModel())
94
            ->with($this->getWith());
95
96
        return $repository;
97
    }
98
99
    /**
100
     * {@inheritdoc}
101
     */
102
    public function getRepository()
103
    {
104
        if (is_null($this->repository)) {
105
            $this->setRepository($this->makeRepository());
106
        }
107
108
        return $this->repository;
109
    }
110
111
    /**
112
     * {@inheritdoc}
113
     */
114
    public function setRepository(RepositoryInterface $repository)
115
    {
116
        $this->repository = $repository;
117
118
        return $this;
119
    }
120
121
    /**
122
     * {@inheritdoc}
123
     */
124
    public function getWith()
125
    {
126
        return $this->with;
127
    }
128
129
    /**
130
     * {@inheritdoc}
131
     */
132
    public function with($relations)
133
    {
134
        $this->with = array_flatten(func_get_args());
135
136
        return $this;
137
    }
138
139
    /**
140
     * {@inheritdoc}
141
     */
142
    public function getQuery()
143
    {
144
        $repository = $this->getRepository();
145
146
        $query = $repository->getQuery();
147
148
        if ($repository->isRestorable()) {
149
            $query->withTrashed();
150
        }
151
152
        $this->apply($query);
153
154
        return $query;
155
    }
156
157
    protected function apply(Builder $query)
158
    {
159
        $this->extensions->apply($query);
160
    }
161
162
    /**
163
     * {@inheritdoc}
164
     */
165
    public function orderBy($column, $direction = 'asc')
166
    {
167
        $this->addApply(function (Builder $query) use ($column, $direction) {
168
            $query->orderBy($column, $direction);
0 ignored issues
show
Bug introduced by
The method orderBy() does not exist on Illuminate\Database\Eloquent\Builder. Did you maybe mean enforceOrderBy()?

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...
169
        });
170
171
        return $this;
172
    }
173
174
    public function toArray()
175
    {
176
        return [
177
            'type'    => $this->type,
178
            'filters' => [
179
                'elements' => $this->getFilters(),
180
                'values'   => $this->getFilters()->getDisplayValues(),
181
            ],
182
        ];
183
    }
184
185
    public function __call($name, $parameters)
186
    {
187
        $method = snake_case(substr($name, 3));
188
189
        if (starts_with($name, 'get') && $this->extensions->has($method)) {
190
            return $this->extensions->get($method);
191
        }
192
193 View Code Duplication
        if (starts_with($name, 'set') && $this->extensions->has($method)) {
194
            $extension = $this->extensions->get($method);
195
            call_user_func_array([$extension, 'set'], $parameters);
196
197
            return $this;
198
        }
199
200 View Code Duplication
        if (starts_with($name, 'add') && $this->extensions->has(str_plural($method))) {
201
            $extension = $this->extensions->get(str_plural($method));
202
            call_user_func_array([$extension, 'add'], $parameters);
203
204
            return $this;
205
        }
206
207
        throw new \BadMethodCallException("Call to undefined method [{$name}]");
208
    }
209
}
210