Issues (389)

src/Admin/Grid/Column.php (1 issue)

1
<?php
2
3
namespace Arbory\Base\Admin\Grid;
4
5
use Closure;
6
use Arbory\Base\Html\Html;
7
use Arbory\Base\Admin\Grid;
8
use Arbory\Base\Html\Elements\Element;
9
use Illuminate\Database\Eloquent\Model;
10
use Arbory\Base\Admin\Filter\FilterItem;
11
use Arbory\Base\Admin\Filter\FilterCollection;
12
use Illuminate\Database\Eloquent\Relations\Relation;
13
use Illuminate\Database\Eloquent\Builder as QueryBuilder;
14
15
/**
16
 * Class Column.
17
 */
18
class Column
19
{
20
    /**
21
     * @var string
22
     */
23
    protected $name;
24
25
    /**
26
     * @var string
27
     */
28
    protected $label;
29
30
    /**
31
     * @var string
32
     */
33
    protected $relationName;
34
35
    /**
36
     * @var string
37
     */
38
    protected $relationColumn;
39
40
    /**
41
     * @var Grid
42
     */
43
    protected $grid;
44
45
    /**
46
     * @var Closure
47
     */
48
    protected $displayer;
49
50
    /**
51
     * @var bool
52
     */
53
    protected $sortable = false;
54
55
    /**
56
     * @var bool
57
     */
58
    protected $searchable = true;
59
60
    /**
61
     * @var bool
62
     */
63
    protected $hasFilter = false;
64
65
    /**
66
     * @var
67
     */
68
    protected $filterType;
69
70
    /**
71
     * @var bool
72
     */
73
    protected $checkable = false;
74
75
    /**
76
     * @var callable
77
     */
78
    protected $customQuery;
79
80
    /**
81
     * @var Closure
82
     */
83
    protected $exportColumnDisplay;
84
85
    /**
86
     * Column constructor.
87
     *
88
     * @param  string  $name
89
     * @param  string  $label
90
     */
91
    public function __construct($name = null, $label = null)
92
    {
93
        $this->name = $name;
94
        $this->label = $label;
95
    }
96
97
    /**
98
     * @return string
99
     */
100
    public function __toString()
101
    {
102
        return (string) $this->getName();
103
    }
104
105
    /**
106
     * @return null|string
107
     */
108
    public function getName()
109
    {
110
        return $this->name;
111
    }
112
113
    public function getFilterType()
114
    {
115
        return $this->filterType;
116
    }
117
118
    /**
119
     * @return bool
120
     */
121
    public function getHasFilter(): bool
122
    {
123
        return $this->hasFilter;
124
    }
125
126
    /**
127
     * @return string
128
     */
129
    public function getRelationName()
130
    {
131
        return $this->relationName;
132
    }
133
134
    /**
135
     * @return string
136
     */
137
    public function getRelationColumn()
138
    {
139
        return $this->relationColumn;
140
    }
141
142
    /**
143
     * @return string
144
     */
145
    public function getLabel()
146
    {
147
        return $this->label ?: $this->name;
148
    }
149
150
    /**
151
     * @return Grid
152
     */
153
    public function getGrid(): Grid
154
    {
155
        return $this->grid;
156
    }
157
158
    /**
159
     * @param  Grid  $grid
160
     * @return Column
161
     */
162
    public function setGrid(Grid $grid)
163
    {
164
        $this->grid = $grid;
165
166
        return $this;
167
    }
168
169
    /**
170
     * @param  Closure  $callable
171
     * @return Column
172
     */
173
    public function display(Closure $callable)
174
    {
175
        $this->displayer = $callable;
176
177
        return $this;
178
    }
179
180
    /**
181
     * @param  bool  $isSortable
182
     * @return Column
183
     */
184
    public function sortable($isSortable = true)
185
    {
186
        $this->sortable = $isSortable;
187
188
        return $this;
189
    }
190
191
    /**
192
     * @param  bool  $isCheckable
193
     * @return $this
194
     */
195
    public function checkable($isCheckable = true)
196
    {
197
        $this->checkable = $isCheckable;
198
199
        return $this;
200
    }
201
202
    /**
203
     * @param  bool  $isSearchable
204
     * @return Column
205
     */
206
    public function searchable($isSearchable = true)
207
    {
208
        $this->searchable = $isSearchable;
209
210
        return $this;
211
    }
212
213
    /**
214
     * @param  string|null  $type
215
     * @return $this
216
     */
217
    public function setFilter($type = null)
218
    {
219
        $this->filterType = $type;
220
        $this->hasFilter = $type !== null;
221
222
        return $this;
223
    }
224
225
    /**
226
     * @return bool
227
     */
228
    public function isSortable()
229
    {
230
        return $this->sortable && empty($this->relationName);
231
    }
232
233
    /**
234
     * @return bool
235
     */
236
    public function isCheckable()
237
    {
238
        return $this->checkable;
239
    }
240
241
    /**
242
     * @return bool
243
     */
244
    public function isSearchable()
245
    {
246
        return $this->searchable;
247
    }
248
249
    /**
250
     * @param  callable  $query
251
     * @return $this
252
     */
253
    public function setCustomSearchQuery(callable $query)
254
    {
255
        $this->customQuery = $query;
256
257
        return $this;
258
    }
259
260
    /**
261
     * @return null|QueryBuilder
262
     */
263
    public function getCustomSearchQuery()
264
    {
265
        return $this->customQuery;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->customQuery returns the type callable which is incompatible with the documented return type Illuminate\Database\Eloquent\Builder|null.
Loading history...
266
    }
267
268
    /**
269
     * @param  QueryBuilder  $query
270
     * @param $string
271
     * @return QueryBuilder
272
     */
273
    public function searchConditions(QueryBuilder $query, $string)
274
    {
275
        if ($this->customQuery) {
276
            return call_user_func($this->customQuery, $query, $string);
277
        }
278
279
        if ($this->relationName) {
280
            return $query->orWhereHas($this->relationName, function (QueryBuilder $query) use ($string) {
281
                $query->where($this->relationColumn, 'like', "%$string%");
282
            });
283
        }
284
285
        return $query->where($this->getName(), 'like', "%$string%", 'OR');
286
    }
287
288
    /**
289
     * @param  Model  $model
290
     * @return mixed
291
     */
292
    protected function getValue(Model $model)
293
    {
294
        if ($this->relationName) {
295
            if ($this->relationName === 'translations') {
296
                $translation = $model->getTranslation(null, true);
297
298
                if (! $translation) {
299
                    return '';
300
                }
301
302
                return $translation->getAttribute($this->relationColumn);
303
            }
304
305
            $attribute = $model->getAttribute($this->relationName);
306
307
            if ($attribute instanceof Model || $attribute instanceof Relation) {
308
                return $attribute->getAttribute($this->relationColumn);
309
            }
310
311
            return $attribute;
312
        }
313
314
        return $model->getAttribute($this->getName());
315
    }
316
317
    /**
318
     * @param  Model  $model
319
     * @return Element
320
     */
321
    public function callDisplayCallback(Model $model)
322
    {
323
        $value = $this->getValue($model);
324
325
        if ($this->displayer === null) {
326
            $value = (string) $value;
327
328
            if ($url = $this->grid->getRowUrl($model)) {
329
                return Html::link($value)->addAttributes([
330
                    'href' => $url,
331
                ]);
332
            }
333
334
            return Html::span($value);
335
        }
336
337
        return call_user_func_array($this->displayer, [$value, $this, $model]);
338
    }
339
340
    /**
341
     * @param  \Closure  $closure
342
     * @return $this
343
     */
344
    public function setExportColumnDisplay(Closure $closure): self
345
    {
346
        $this->exportColumnDisplay = $closure;
347
348
        return $this;
349
    }
350
351
    /**
352
     * @param  \Illuminate\Database\Eloquent\Model  $model
353
     * @return mixed
354
     */
355
    public function getExportColumnDisplay(Model $model)
356
    {
357
        if ($this->exportColumnDisplay === null) {
358
            return $this->callDisplayCallback($model);
359
        }
360
361
        $value = $this->getValue($model);
362
363
        return call_user_func($this->exportColumnDisplay, $value, $this, $model);
364
    }
365
366
    /**
367
     * @param $relationName
368
     * @param $relationColumn
369
     */
370
    public function setRelation($relationName, $relationColumn)
371
    {
372
        $this->relationName = $relationName;
373
        $this->relationColumn = $relationColumn;
374
    }
375
376
    /**
377
     * @param  string  $filterType
378
     * @param  iterable  $filterTypeConfig
379
     * @return FilterItem
380
     */
381
    public function addFilter(string $filterType, iterable $filterTypeConfig = []): FilterItem
382
    {
383
        $filterManager = $this->grid->getFilterManager();
384
385
        return $filterManager
386
            ->addFilter($this->getName(), $this->getLabel(), $filterType, $filterTypeConfig)
387
            ->setOwner($this);
388
    }
389
390
    /**
391
     * @return FilterCollection|FilterItem[]
392
     */
393
    public function getFilters(): FilterCollection
394
    {
395
        $filterManager = $this->grid->getFilterManager();
396
397
        return $filterManager->getFilters()->findByOwner($this);
398
    }
399
}
400