Completed
Push — master ( c139be...7e212d )
by wen
14:16
created

Display::apply()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
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\Initializable;
9
use Sco\Admin\Contracts\RepositoryInterface;
10
use Sco\Admin\Contracts\Display\Extensions\ExtensionInterface;
11
use Sco\Admin\Contracts\Display\DisplayInterface;
12
use Sco\Admin\Display\Extensions\Applies;
13
use Sco\Admin\Display\Extensions\Filters;
14
use Sco\Admin\Display\Extensions\Scopes;
15
use Sco\Admin\Contracts\Display\Filters\FilterInterface;
16
17
/**
18
 * @method Scopes getScopes() get query scopes
19
 * @method $this setScopes($scope, ...$scopes) set query scopes
20
 * @method $this addScope($scope, $parameter, ...$parameters) add query scope
21
 *
22
 * @method Applies getApplies() get query applies
23
 * @method $this setApplies(\Closure $apply, ...$applies) set query applies
24
 * @method $this addApply(\Closure $apply) add query apply
25
 *
26
 * @method Filters getFilters()
27
 * @method $this setFilters(FilterInterface $filter, ...$filters)
28
 * @method $this addFilter(FilterInterface $filter)
29
 *
30
 */
31
abstract class Display implements DisplayInterface, Arrayable
32
{
33
    /**
34
     * @var array
35
     */
36
    protected $with = [];
37
38
    /**
39
     * @var \Illuminate\Database\Eloquent\Model
40
     */
41
    protected $model;
42
43
    /**
44
     * @var null|RepositoryInterface
45
     */
46
    protected $repository;
47
48
    protected $type;
49
50
    protected $extensions;
51
52
    abstract public function get();
53
54
    public function __construct()
55
    {
56
        $this->extensions = new Extensions();
57
58
        $this->extend('scopes', new Scopes());
59
        $this->extend('applies', new Applies());
60
        $this->extend('filters', new Filters());
61
    }
62
63
    /**
64
     * @param \Illuminate\Database\Eloquent\Model $model
65
     *
66
     * @return $this
67
     */
68
    public function setModel(Model $model)
69
    {
70
        $this->model = $model;
71
72
        return $this;
73
    }
74
75
    /**
76
     * @return \Illuminate\Database\Eloquent\Model
77
     */
78
    public function getModel()
79
    {
80
        return $this->model;
81
    }
82
83
    /**
84
     * {@inheritdoc}
85
     */
86
    public function extend($name, ExtensionInterface $extension)
87
    {
88
        $this->extensions->put($name, $extension);
89
90
        return $this;
91
    }
92
93
    protected function makeRepository()
94
    {
95
        $repository = app(RepositoryInterface::class)
96
            ->setModel($this->getModel())
97
            ->with($this->getWith());
98
99
        return $repository;
100
    }
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
    public function setRepository(RepositoryInterface $repository)
112
    {
113
        $this->repository = $repository;
114
115
        return $this;
116
    }
117
118
    /**
119
     * @return string[]
120
     */
121
    public function getWith()
122
    {
123
        return $this->with;
124
    }
125
126
    /**
127
     * {@inheritdoc}
128
     */
129
    public function with($relations)
130
    {
131
        $this->with = array_flatten(func_get_args());
132
133
        return $this;
134
    }
135
136
    /**
137
     * {@inheritdoc}
138
     */
139
    public function getQuery()
140
    {
141
        $repository = $this->getRepository();
142
143
        $query = $repository->getQuery();
144
145
        if ($repository->isRestorable()) {
146
            $query->withTrashed();
147
        }
148
149
        $this->apply($query);
150
151
        return $query;
152
    }
153
154
    protected function apply(Builder $query)
155
    {
156
        $this->extensions->apply($query);
157
    }
158
159
    /**
160
     * Add an "order by" clause to the query.
161
     *
162
     * @param  string $column
163
     * @param  string $direction
164
     *
165
     * @return $this
166
     */
167
    public function orderBy($column, $direction = 'asc')
168
    {
169
        $this->addApply(function (Builder $query) use ($column, $direction) {
170
            $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...
171
        });
172
173
        return $this;
174
    }
175
176
    public function toArray()
177
    {
178
        return [
179
            'type'    => $this->type,
180
            'filters' => [
181
                'elements' => $this->getFilters(),
182
                'values'   => $this->getFilters()->getDisplayValues(),
183
            ],
184
        ];
185
    }
186
187
    public function __call($name, $parameters)
188
    {
189
        $method = snake_case(substr($name, 3));
190
191
        if (starts_with($name, 'get') && $this->extensions->has($method)) {
192
            $extensions = $this->extensions->get($method);
193
            if ($extensions instanceof Initializable) {
194
                $extensions->initialize();
195
            }
196
197
            return $extensions;
198
        }
199
200 View Code Duplication
        if (starts_with($name, 'set') && $this->extensions->has($method)) {
201
            $extension = $this->extensions->get($method);
202
            call_user_func_array([$extension, 'set'], $parameters);
203
204
            return $this;
205
        }
206
207 View Code Duplication
        if (starts_with($name, 'add') && $this->extensions->has(str_plural($method))) {
208
            $extension = $this->extensions->get(str_plural($method));
209
            call_user_func_array([$extension, 'add'], $parameters);
210
211
            return $this;
212
        }
213
214
        throw new \BadMethodCallException("Call to undefined method [{$name}]");
215
    }
216
}
217