Completed
Push — master ( 650783...0c9838 )
by wen
15:06
created

Display::__call()   C

Complexity

Conditions 7
Paths 4

Size

Total Lines 24
Code Lines 13

Duplication

Lines 11
Ratio 45.83 %

Importance

Changes 0
Metric Value
dl 11
loc 24
rs 6.7272
c 0
b 0
f 0
cc 7
eloc 13
nc 4
nop 2
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 RepositoryInterface
44
     */
45
    protected $repository;
46
47
    protected $type;
48
49
    protected $extensions;
50
51
    public function __construct()
52
    {
53
        $this->extensions = new Extensions();
54
55
        $this->extend('scopes', new Scopes());
56
        $this->extend('applies', new Applies());
57
        $this->extend('filters', new Filters());
58
    }
59
60
    /**
61
     * @param \Illuminate\Database\Eloquent\Model $model
62
     *
63
     * @return $this
64
     */
65
    public function setModel(Model $model)
66
    {
67
        $this->model = $model;
68
69
        return $this;
70
    }
71
72
    /**
73
     * @return \Illuminate\Database\Eloquent\Model
74
     */
75
    public function getModel()
76
    {
77
        return $this->model;
78
    }
79
80
    public function initialize()
81
    {
82
        $this->makeRepository();
83
        $this->extensions->initialize();
84
    }
85
86
    public function extend($name, ExtensionInterface $extension)
87
    {
88
        $this->extensions->put($name, $extension);
89
    }
90
91
    protected function makeRepository()
92
    {
93
        $this->repository = app(RepositoryInterface::class)
94
            ->setModel($this->getModel())
95
            ->with($this->getWith());
96
97
        return $this;
98
    }
99
100
    public function getRepository()
101
    {
102
        return $this->repository;
103
    }
104
105
    /**
106
     * @return string[]
107
     */
108
    public function getWith()
109
    {
110
        return $this->with;
111
    }
112
113
    /**
114
     * {@inheritdoc}
115
     */
116
    public function with($relations)
117
    {
118
        $this->with = array_flatten(func_get_args());
119
120
        return $this;
121
    }
122
123
    public function getQuery()
124
    {
125
        $repository = $this->getRepository();
126
127
        $query = $repository->getQuery();
128
129
        if ($repository->isRestorable()) {
130
            $query->withTrashed();
131
        }
132
133
        $this->apply($query);
134
135
        return $query;
136
    }
137
138
    protected function apply(Builder $query)
139
    {
140
        $this->extensions->apply($query);
141
    }
142
143
    /**
144
     * Add an "order by" clause to the query.
145
     *
146
     * @param  string $column
147
     * @param  string $direction
148
     *
149
     * @return $this
150
     */
151
    public function orderBy($column, $direction = 'asc')
152
    {
153
        $this->addApply(function (Builder $query) use ($column, $direction) {
154
            $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...
155
        });
156
157
        return $this;
158
    }
159
160
    public function toArray()
161
    {
162
        return [
163
            'type'    => $this->type,
164
            'filters' => [
165
                'elements' => $this->getFilters(),
166
                'values'   => $this->getFilters()->getDisplayValues(),
167
            ],
168
        ];
169
    }
170
171
    public function __call($name, $parameters)
172
    {
173
        $method = snake_case(substr($name, 3));
174
175
        if (starts_with($name, 'get') && $this->extensions->has($method)) {
176
            return $this->extensions->get($method);
177
        }
178
179 View Code Duplication
        if (starts_with($name, 'set') && $this->extensions->has($method)) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
180
            $extension = $this->extensions->get($method);
181
            call_user_func_array([$extension, 'set'], $parameters);
182
183
            return $this;
184
        }
185
186 View Code Duplication
        if (starts_with($name, 'add') && $this->extensions->has(str_plural($method))) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
187
            $extension = $this->extensions->get(str_plural($method));
188
            call_user_func_array([$extension, 'add'], $parameters);
189
190
            return $this;
191
        }
192
193
        throw new \BadMethodCallException("Call to undefined method [{$name}]");
194
    }
195
}
196