|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
namespace Encore\Admin; |
|
4
|
|
|
|
|
5
|
|
|
use Closure; |
|
6
|
|
|
use Encore\Admin\Exception\Handler; |
|
7
|
|
|
use Encore\Admin\Grid\Column; |
|
8
|
|
|
use Encore\Admin\Grid\Displayers; |
|
9
|
|
|
use Encore\Admin\Grid\Exporter; |
|
10
|
|
|
use Encore\Admin\Grid\Exporters\AbstractExporter; |
|
11
|
|
|
use Encore\Admin\Grid\Concerns; |
|
12
|
|
|
use Encore\Admin\Grid\Model; |
|
13
|
|
|
use Encore\Admin\Grid\Row; |
|
14
|
|
|
use Encore\Admin\Grid\Tools; |
|
15
|
|
|
use Illuminate\Database\Eloquent\Model as Eloquent; |
|
16
|
|
|
use Illuminate\Database\Eloquent\Relations; |
|
17
|
|
|
use Illuminate\Support\Collection; |
|
18
|
|
|
use Illuminate\Support\Facades\Input; |
|
19
|
|
|
use Illuminate\Support\Str; |
|
20
|
|
|
use Jenssegers\Mongodb\Eloquent\Model as MongodbModel; |
|
21
|
|
|
|
|
22
|
|
|
class Grid |
|
23
|
|
|
{ |
|
24
|
|
|
use Concerns\HasElementNames, |
|
25
|
|
|
Concerns\HasHeader, |
|
26
|
|
|
Concerns\HasFooter, |
|
27
|
|
|
Concerns\HasFilter, |
|
28
|
|
|
Concerns\HasTools, |
|
29
|
|
|
Concerns\HasTotalRow; |
|
30
|
|
|
|
|
31
|
|
|
/** |
|
32
|
|
|
* The grid data model instance. |
|
33
|
|
|
* |
|
34
|
|
|
* @var \Encore\Admin\Grid\Model |
|
35
|
|
|
*/ |
|
36
|
|
|
protected $model; |
|
37
|
|
|
|
|
38
|
|
|
/** |
|
39
|
|
|
* Collection of all grid columns. |
|
40
|
|
|
* |
|
41
|
|
|
* @var \Illuminate\Support\Collection |
|
42
|
|
|
*/ |
|
43
|
|
|
protected $columns; |
|
44
|
|
|
|
|
45
|
|
|
/** |
|
46
|
|
|
* Collection of all data rows. |
|
47
|
|
|
* |
|
48
|
|
|
* @var \Illuminate\Support\Collection |
|
49
|
|
|
*/ |
|
50
|
|
|
protected $rows; |
|
51
|
|
|
|
|
52
|
|
|
/** |
|
53
|
|
|
* Rows callable fucntion. |
|
54
|
|
|
* |
|
55
|
|
|
* @var \Closure |
|
56
|
|
|
*/ |
|
57
|
|
|
protected $rowsCallback; |
|
58
|
|
|
|
|
59
|
|
|
/** |
|
60
|
|
|
* All column names of the grid. |
|
61
|
|
|
* |
|
62
|
|
|
* @var array |
|
63
|
|
|
*/ |
|
64
|
|
|
public $columnNames = []; |
|
65
|
|
|
|
|
66
|
|
|
/** |
|
67
|
|
|
* Grid builder. |
|
68
|
|
|
* |
|
69
|
|
|
* @var \Closure |
|
70
|
|
|
*/ |
|
71
|
|
|
protected $builder; |
|
72
|
|
|
|
|
73
|
|
|
/** |
|
74
|
|
|
* Mark if the grid is builded. |
|
75
|
|
|
* |
|
76
|
|
|
* @var bool |
|
77
|
|
|
*/ |
|
78
|
|
|
protected $builded = false; |
|
79
|
|
|
|
|
80
|
|
|
/** |
|
81
|
|
|
* All variables in grid view. |
|
82
|
|
|
* |
|
83
|
|
|
* @var array |
|
84
|
|
|
*/ |
|
85
|
|
|
protected $variables = []; |
|
86
|
|
|
|
|
87
|
|
|
/** |
|
88
|
|
|
* Resource path of the grid. |
|
89
|
|
|
* |
|
90
|
|
|
* @var |
|
91
|
|
|
*/ |
|
92
|
|
|
protected $resourcePath; |
|
93
|
|
|
|
|
94
|
|
|
/** |
|
95
|
|
|
* Default primary key name. |
|
96
|
|
|
* |
|
97
|
|
|
* @var string |
|
98
|
|
|
*/ |
|
99
|
|
|
protected $keyName = 'id'; |
|
100
|
|
|
|
|
101
|
|
|
/** |
|
102
|
|
|
* Export driver. |
|
103
|
|
|
* |
|
104
|
|
|
* @var string |
|
105
|
|
|
*/ |
|
106
|
|
|
protected $exporter; |
|
107
|
|
|
|
|
108
|
|
|
/** |
|
109
|
|
|
* View for grid to render. |
|
110
|
|
|
* |
|
111
|
|
|
* @var string |
|
112
|
|
|
*/ |
|
113
|
|
|
protected $view = 'admin::grid.table'; |
|
114
|
|
|
|
|
115
|
|
|
/** |
|
116
|
|
|
* Per-page options. |
|
117
|
|
|
* |
|
118
|
|
|
* @var array |
|
119
|
|
|
*/ |
|
120
|
|
|
public $perPages = [10, 20, 30, 50, 100]; |
|
121
|
|
|
|
|
122
|
|
|
/** |
|
123
|
|
|
* Default items count per-page. |
|
124
|
|
|
* |
|
125
|
|
|
* @var int |
|
126
|
|
|
*/ |
|
127
|
|
|
public $perPage = 20; |
|
128
|
|
|
|
|
129
|
|
|
/** |
|
130
|
|
|
* Callback for grid actions. |
|
131
|
|
|
* |
|
132
|
|
|
* @var Closure |
|
133
|
|
|
*/ |
|
134
|
|
|
protected $actionsCallback; |
|
135
|
|
|
|
|
136
|
|
|
/** |
|
137
|
|
|
* Actions column display class. |
|
138
|
|
|
* |
|
139
|
|
|
* @var string |
|
140
|
|
|
*/ |
|
141
|
|
|
protected $actionsClass = Displayers\Actions::class; |
|
142
|
|
|
|
|
143
|
|
|
/** |
|
144
|
|
|
* Options for grid. |
|
145
|
|
|
* |
|
146
|
|
|
* @var array |
|
147
|
|
|
*/ |
|
148
|
|
|
protected $options = [ |
|
149
|
|
|
'show_pagination' => true, |
|
150
|
|
|
'show_tools' => true, |
|
151
|
|
|
'show_filter' => true, |
|
152
|
|
|
'show_exporter' => true, |
|
153
|
|
|
'show_actions' => true, |
|
154
|
|
|
'show_row_selector' => true, |
|
155
|
|
|
'show_create_btn' => true, |
|
156
|
|
|
'show_column_selector' => true, |
|
157
|
|
|
]; |
|
158
|
|
|
|
|
159
|
|
|
/** |
|
160
|
|
|
* @var string |
|
161
|
|
|
*/ |
|
162
|
|
|
public $tableID; |
|
163
|
|
|
|
|
164
|
|
|
/** |
|
165
|
|
|
* Initialization closure array. |
|
166
|
|
|
* |
|
167
|
|
|
* @var []Closure |
|
168
|
|
|
*/ |
|
169
|
|
|
protected static $initCallbacks = []; |
|
170
|
|
|
|
|
171
|
|
|
/** |
|
172
|
|
|
* Create a new grid instance. |
|
173
|
|
|
* |
|
174
|
|
|
* @param Eloquent $model |
|
175
|
|
|
* @param Closure $builder |
|
176
|
|
|
*/ |
|
177
|
|
|
public function __construct(Eloquent $model, Closure $builder = null) |
|
178
|
|
|
{ |
|
179
|
|
|
$this->keyName = $model->getKeyName(); |
|
180
|
|
|
$this->model = new Model($model); |
|
181
|
|
|
$this->columns = new Collection(); |
|
182
|
|
|
$this->rows = new Collection(); |
|
183
|
|
|
$this->builder = $builder; |
|
184
|
|
|
$this->tableID = uniqid('grid-table'); |
|
185
|
|
|
|
|
186
|
|
|
$this->model()->setGrid($this); |
|
187
|
|
|
|
|
188
|
|
|
$this->setupTools(); |
|
189
|
|
|
$this->setupFilter(); |
|
190
|
|
|
|
|
191
|
|
|
$this->handleExportRequest(); |
|
192
|
|
|
|
|
193
|
|
|
$this->callInitCallbacks(); |
|
194
|
|
|
} |
|
195
|
|
|
|
|
196
|
|
|
/** |
|
197
|
|
|
* Initialize with user pre-defined default disables and exporter, etc. |
|
198
|
|
|
* |
|
199
|
|
|
* @param Closure $callback |
|
200
|
|
|
*/ |
|
201
|
|
|
public static function init(Closure $callback = null) |
|
202
|
|
|
{ |
|
203
|
|
|
static::$initCallbacks[] = $callback; |
|
204
|
|
|
} |
|
205
|
|
|
|
|
206
|
|
|
/** |
|
207
|
|
|
* Call the initialization closure array in sequence. |
|
208
|
|
|
*/ |
|
209
|
|
|
protected function callInitCallbacks() |
|
210
|
|
|
{ |
|
211
|
|
|
if (empty(static::$initCallbacks)) { |
|
212
|
|
|
return; |
|
213
|
|
|
} |
|
214
|
|
|
|
|
215
|
|
|
foreach (static::$initCallbacks as $callback) { |
|
216
|
|
|
call_user_func($callback, $this); |
|
217
|
|
|
} |
|
218
|
|
|
} |
|
219
|
|
|
|
|
220
|
|
|
/** |
|
221
|
|
|
* Handle export request. |
|
222
|
|
|
* |
|
223
|
|
|
* @param bool $forceExport |
|
224
|
|
|
*/ |
|
225
|
|
|
protected function handleExportRequest($forceExport = false) |
|
226
|
|
|
{ |
|
227
|
|
|
if (!$scope = request(Exporter::$queryName)) { |
|
228
|
|
|
return; |
|
229
|
|
|
} |
|
230
|
|
|
|
|
231
|
|
|
// clear output buffer. |
|
232
|
|
|
if (ob_get_length()) { |
|
233
|
|
|
ob_end_clean(); |
|
234
|
|
|
} |
|
235
|
|
|
|
|
236
|
|
|
$this->model()->usePaginate(false); |
|
237
|
|
|
|
|
238
|
|
|
if ($this->builder) { |
|
239
|
|
|
call_user_func($this->builder, $this); |
|
240
|
|
|
|
|
241
|
|
|
$this->getExporter($scope)->export(); |
|
242
|
|
|
} |
|
243
|
|
|
|
|
244
|
|
|
if ($forceExport) { |
|
245
|
|
|
$this->getExporter($scope)->export(); |
|
246
|
|
|
} |
|
247
|
|
|
} |
|
248
|
|
|
|
|
249
|
|
|
/** |
|
250
|
|
|
* @param string $scope |
|
251
|
|
|
* |
|
252
|
|
|
* @return AbstractExporter |
|
253
|
|
|
*/ |
|
254
|
|
|
protected function getExporter($scope) |
|
255
|
|
|
{ |
|
256
|
|
|
return (new Exporter($this))->resolve($this->exporter)->withScope($scope); |
|
257
|
|
|
} |
|
258
|
|
|
|
|
259
|
|
|
/** |
|
260
|
|
|
* Get or set option for grid. |
|
261
|
|
|
* |
|
262
|
|
|
* @param string $key |
|
263
|
|
|
* @param mixed $value |
|
264
|
|
|
* |
|
265
|
|
|
* @return $this|mixed |
|
266
|
|
|
*/ |
|
267
|
|
|
public function option($key, $value = null) |
|
268
|
|
|
{ |
|
269
|
|
|
if (is_null($value)) { |
|
270
|
|
|
return $this->options[$key]; |
|
271
|
|
|
} |
|
272
|
|
|
|
|
273
|
|
|
$this->options[$key] = $value; |
|
274
|
|
|
|
|
275
|
|
|
return $this; |
|
276
|
|
|
} |
|
277
|
|
|
|
|
278
|
|
|
/** |
|
279
|
|
|
* Get primary key name of model. |
|
280
|
|
|
* |
|
281
|
|
|
* @return string |
|
282
|
|
|
*/ |
|
283
|
|
|
public function getKeyName() |
|
284
|
|
|
{ |
|
285
|
|
|
return $this->keyName ?: 'id'; |
|
286
|
|
|
} |
|
287
|
|
|
|
|
288
|
|
|
/** |
|
289
|
|
|
* Add column to Grid. |
|
290
|
|
|
* |
|
291
|
|
|
* @param string $name |
|
292
|
|
|
* @param string $label |
|
293
|
|
|
* |
|
294
|
|
|
* @return Column |
|
295
|
|
|
*/ |
|
296
|
|
|
public function column($name, $label = '') |
|
297
|
|
|
{ |
|
298
|
|
|
$relationName = $relationColumn = ''; |
|
299
|
|
|
|
|
300
|
|
|
if (strpos($name, '.') !== false) { |
|
301
|
|
|
list($relationName, $relationColumn) = explode('.', $name); |
|
302
|
|
|
|
|
303
|
|
|
$relation = $this->model()->eloquent()->$relationName(); |
|
304
|
|
|
|
|
305
|
|
|
$label = empty($label) ? ucfirst($relationColumn) : $label; |
|
306
|
|
|
|
|
307
|
|
|
$name = Str::snake($relationName).'.'.$relationColumn; |
|
308
|
|
|
} |
|
309
|
|
|
|
|
310
|
|
|
$column = $this->addColumn($name, $label); |
|
311
|
|
|
|
|
312
|
|
|
if (isset($relation) && $relation instanceof Relations\Relation) { |
|
313
|
|
|
$this->model()->with($relationName); |
|
314
|
|
|
$column->setRelation($relationName, $relationColumn); |
|
315
|
|
|
} |
|
316
|
|
|
|
|
317
|
|
|
return $column; |
|
318
|
|
|
} |
|
319
|
|
|
|
|
320
|
|
|
/** |
|
321
|
|
|
* Batch add column to grid. |
|
322
|
|
|
* |
|
323
|
|
|
* @example |
|
324
|
|
|
* 1.$grid->columns(['name' => 'Name', 'email' => 'Email' ...]); |
|
325
|
|
|
* 2.$grid->columns('name', 'email' ...) |
|
326
|
|
|
* |
|
327
|
|
|
* @param array $columns |
|
328
|
|
|
* |
|
329
|
|
|
* @return Collection|null |
|
330
|
|
|
*/ |
|
331
|
|
|
public function columns($columns = []) |
|
332
|
|
|
{ |
|
333
|
|
|
if (func_num_args() == 0) { |
|
334
|
|
|
return $this->columns; |
|
335
|
|
|
} |
|
336
|
|
|
|
|
337
|
|
|
if (func_num_args() == 1 && is_array($columns)) { |
|
338
|
|
|
foreach ($columns as $column => $label) { |
|
339
|
|
|
$this->column($column, $label); |
|
340
|
|
|
} |
|
341
|
|
|
|
|
342
|
|
|
return; |
|
343
|
|
|
} |
|
344
|
|
|
|
|
345
|
|
|
foreach (func_get_args() as $column) { |
|
346
|
|
|
$this->column($column); |
|
347
|
|
|
} |
|
348
|
|
|
} |
|
349
|
|
|
|
|
350
|
|
|
/** |
|
351
|
|
|
* Get all visible column instances. |
|
352
|
|
|
* |
|
353
|
|
|
* @return Collection|static |
|
354
|
|
|
*/ |
|
355
|
|
View Code Duplication |
public function visibleColumns() |
|
|
|
|
|
|
356
|
|
|
{ |
|
357
|
|
|
$visible = array_filter(explode(',', request(Tools\ColumnSelector::SELECT_COLUMN_NAME))); |
|
358
|
|
|
|
|
359
|
|
|
if (empty($visible)) { |
|
360
|
|
|
return $this->columns; |
|
361
|
|
|
} |
|
362
|
|
|
|
|
363
|
|
|
array_push($visible, '__row_selector__', '__actions__'); |
|
364
|
|
|
|
|
365
|
|
|
return $this->columns->filter(function (Column $column) use ($visible) { |
|
366
|
|
|
return in_array($column->getName(), $visible); |
|
367
|
|
|
}); |
|
368
|
|
|
} |
|
369
|
|
|
|
|
370
|
|
|
/** |
|
371
|
|
|
* Get all visible column names. |
|
372
|
|
|
* |
|
373
|
|
|
* @return array|static |
|
374
|
|
|
*/ |
|
375
|
|
View Code Duplication |
public function visibleColumnNames() |
|
|
|
|
|
|
376
|
|
|
{ |
|
377
|
|
|
$visible = array_filter(explode(',', request(Tools\ColumnSelector::SELECT_COLUMN_NAME))); |
|
378
|
|
|
|
|
379
|
|
|
if (empty($visible)) { |
|
380
|
|
|
return $this->columnNames; |
|
381
|
|
|
} |
|
382
|
|
|
|
|
383
|
|
|
array_push($visible, '__row_selector__', '__actions__'); |
|
384
|
|
|
|
|
385
|
|
|
return collect($this->columnNames)->filter(function ($column) use ($visible) { |
|
386
|
|
|
return in_array($column, $visible); |
|
387
|
|
|
}); |
|
388
|
|
|
} |
|
389
|
|
|
|
|
390
|
|
|
/** |
|
391
|
|
|
* Add column to grid. |
|
392
|
|
|
* |
|
393
|
|
|
* @param string $column |
|
394
|
|
|
* @param string $label |
|
395
|
|
|
* |
|
396
|
|
|
* @return Column |
|
397
|
|
|
*/ |
|
398
|
|
View Code Duplication |
protected function addColumn($column = '', $label = '') |
|
|
|
|
|
|
399
|
|
|
{ |
|
400
|
|
|
$column = new Column($column, $label); |
|
401
|
|
|
$column->setGrid($this); |
|
402
|
|
|
|
|
403
|
|
|
return tap($column, function ($value) { |
|
404
|
|
|
$this->columns->push($value); |
|
405
|
|
|
}); |
|
406
|
|
|
} |
|
407
|
|
|
|
|
408
|
|
|
/** |
|
409
|
|
|
* Prepend column to grid. |
|
410
|
|
|
* |
|
411
|
|
|
* @param string $column |
|
412
|
|
|
* @param string $label |
|
413
|
|
|
* |
|
414
|
|
|
* @return Column |
|
415
|
|
|
*/ |
|
416
|
|
View Code Duplication |
protected function prependColumn($column = '', $label = '') |
|
|
|
|
|
|
417
|
|
|
{ |
|
418
|
|
|
$column = new Column($column, $label); |
|
419
|
|
|
$column->setGrid($this); |
|
420
|
|
|
|
|
421
|
|
|
return tap($column, function ($value) { |
|
422
|
|
|
$this->columns->prepend($value); |
|
423
|
|
|
}); |
|
424
|
|
|
} |
|
425
|
|
|
|
|
426
|
|
|
/** |
|
427
|
|
|
* Get Grid model. |
|
428
|
|
|
* |
|
429
|
|
|
* @return Model |
|
430
|
|
|
*/ |
|
431
|
|
|
public function model() |
|
432
|
|
|
{ |
|
433
|
|
|
return $this->model; |
|
434
|
|
|
} |
|
435
|
|
|
|
|
436
|
|
|
/** |
|
437
|
|
|
* Paginate the grid. |
|
438
|
|
|
* |
|
439
|
|
|
* @param int $perPage |
|
440
|
|
|
* |
|
441
|
|
|
* @return void |
|
442
|
|
|
*/ |
|
443
|
|
|
public function paginate($perPage = 20) |
|
444
|
|
|
{ |
|
445
|
|
|
$this->perPage = $perPage; |
|
446
|
|
|
|
|
447
|
|
|
$this->model()->paginate($perPage); |
|
|
|
|
|
|
448
|
|
|
} |
|
449
|
|
|
|
|
450
|
|
|
/** |
|
451
|
|
|
* Get the grid paginator. |
|
452
|
|
|
* |
|
453
|
|
|
* @return mixed |
|
454
|
|
|
*/ |
|
455
|
|
|
public function paginator() |
|
456
|
|
|
{ |
|
457
|
|
|
return new Tools\Paginator($this); |
|
458
|
|
|
} |
|
459
|
|
|
|
|
460
|
|
|
/** |
|
461
|
|
|
* Disable grid pagination. |
|
462
|
|
|
* |
|
463
|
|
|
* @return $this |
|
464
|
|
|
*/ |
|
465
|
|
|
public function disablePagination(bool $disable = true) |
|
466
|
|
|
{ |
|
467
|
|
|
$this->model->usePaginate(!$disable); |
|
468
|
|
|
|
|
469
|
|
|
return $this->option('show_pagination', !$disable); |
|
470
|
|
|
} |
|
471
|
|
|
|
|
472
|
|
|
/** |
|
473
|
|
|
* If this grid use pagination. |
|
474
|
|
|
* |
|
475
|
|
|
* @return bool |
|
476
|
|
|
*/ |
|
477
|
|
|
public function showPagination() |
|
478
|
|
|
{ |
|
479
|
|
|
return $this->option('show_pagination'); |
|
480
|
|
|
} |
|
481
|
|
|
|
|
482
|
|
|
/** |
|
483
|
|
|
* Set per-page options. |
|
484
|
|
|
* |
|
485
|
|
|
* @param array $perPages |
|
486
|
|
|
*/ |
|
487
|
|
|
public function perPages(array $perPages) |
|
488
|
|
|
{ |
|
489
|
|
|
$this->perPages = $perPages; |
|
490
|
|
|
} |
|
491
|
|
|
|
|
492
|
|
|
/** |
|
493
|
|
|
* Disable all actions. |
|
494
|
|
|
* |
|
495
|
|
|
* @return $this |
|
496
|
|
|
*/ |
|
497
|
|
|
public function disableActions(bool $disable = true) |
|
498
|
|
|
{ |
|
499
|
|
|
return $this->option('show_actions', !$disable); |
|
500
|
|
|
} |
|
501
|
|
|
|
|
502
|
|
|
/** |
|
503
|
|
|
* Set grid action callback. |
|
504
|
|
|
* |
|
505
|
|
|
* @param Closure|string $actions |
|
506
|
|
|
* |
|
507
|
|
|
* @return $this |
|
508
|
|
|
*/ |
|
509
|
|
|
public function actions($actions) |
|
510
|
|
|
{ |
|
511
|
|
|
if ($actions instanceof Closure) { |
|
512
|
|
|
$this->actionsCallback = $actions; |
|
513
|
|
|
} |
|
514
|
|
|
|
|
515
|
|
|
if (is_string($actions) && is_subclass_of($actions, Displayers\Actions::class)) { |
|
|
|
|
|
|
516
|
|
|
$this->actionsClass = $actions; |
|
517
|
|
|
} |
|
518
|
|
|
|
|
519
|
|
|
return $this; |
|
520
|
|
|
} |
|
521
|
|
|
|
|
522
|
|
|
/** |
|
523
|
|
|
* Add `actions` column for grid. |
|
524
|
|
|
* |
|
525
|
|
|
* @return void |
|
526
|
|
|
*/ |
|
527
|
|
|
protected function appendActionsColumn() |
|
528
|
|
|
{ |
|
529
|
|
|
if (!$this->option('show_actions')) { |
|
530
|
|
|
return; |
|
531
|
|
|
} |
|
532
|
|
|
|
|
533
|
|
|
$this->addColumn('__actions__', trans('admin.action')) |
|
534
|
|
|
->displayUsing($this->actionsClass, [$this->actionsCallback]); |
|
535
|
|
|
} |
|
536
|
|
|
|
|
537
|
|
|
/** |
|
538
|
|
|
* Disable row selector. |
|
539
|
|
|
* |
|
540
|
|
|
* @return Grid|mixed |
|
541
|
|
|
*/ |
|
542
|
|
|
public function disableRowSelector(bool $disable = true) |
|
543
|
|
|
{ |
|
544
|
|
|
$this->tools->disableBatchActions($disable); |
|
545
|
|
|
|
|
546
|
|
|
return $this->option('show_row_selector', !$disable); |
|
547
|
|
|
} |
|
548
|
|
|
|
|
549
|
|
|
/** |
|
550
|
|
|
* Prepend checkbox column for grid. |
|
551
|
|
|
* |
|
552
|
|
|
* @return void |
|
553
|
|
|
*/ |
|
554
|
|
|
protected function prependRowSelectorColumn() |
|
555
|
|
|
{ |
|
556
|
|
|
if (!$this->option('show_row_selector')) { |
|
557
|
|
|
return; |
|
558
|
|
|
} |
|
559
|
|
|
|
|
560
|
|
|
$this->prependColumn(Column::SELECT_COLUMN_NAME, ' ') |
|
561
|
|
|
->displayUsing(Displayers\RowSelector::class); |
|
562
|
|
|
} |
|
563
|
|
|
|
|
564
|
|
|
/** |
|
565
|
|
|
* Build the grid. |
|
566
|
|
|
* |
|
567
|
|
|
* @return void |
|
568
|
|
|
*/ |
|
569
|
|
|
public function build() |
|
570
|
|
|
{ |
|
571
|
|
|
if ($this->builded) { |
|
572
|
|
|
return; |
|
573
|
|
|
} |
|
574
|
|
|
|
|
575
|
|
|
$collection = $this->processFilter(false); |
|
576
|
|
|
|
|
577
|
|
|
$data = $collection->toArray(); |
|
578
|
|
|
|
|
579
|
|
|
$this->prependRowSelectorColumn(); |
|
580
|
|
|
$this->appendActionsColumn(); |
|
581
|
|
|
|
|
582
|
|
|
Column::setOriginalGridModels($collection); |
|
583
|
|
|
|
|
584
|
|
|
$this->columns->map(function (Column $column) use (&$data) { |
|
585
|
|
|
$data = $column->fill($data); |
|
586
|
|
|
|
|
587
|
|
|
$this->columnNames[] = $column->getName(); |
|
588
|
|
|
}); |
|
589
|
|
|
|
|
590
|
|
|
$this->buildRows($data); |
|
591
|
|
|
|
|
592
|
|
|
$this->builded = true; |
|
593
|
|
|
} |
|
594
|
|
|
|
|
595
|
|
|
/** |
|
596
|
|
|
* Build the grid rows. |
|
597
|
|
|
* |
|
598
|
|
|
* @param array $data |
|
599
|
|
|
* |
|
600
|
|
|
* @return void |
|
601
|
|
|
*/ |
|
602
|
|
|
protected function buildRows(array $data) |
|
603
|
|
|
{ |
|
604
|
|
|
$this->rows = collect($data)->map(function ($model, $number) { |
|
605
|
|
|
return new Row($number, $model); |
|
606
|
|
|
}); |
|
607
|
|
|
|
|
608
|
|
|
if ($this->rowsCallback) { |
|
609
|
|
|
$this->rows->map($this->rowsCallback); |
|
610
|
|
|
} |
|
611
|
|
|
} |
|
612
|
|
|
|
|
613
|
|
|
/** |
|
614
|
|
|
* Set grid row callback function. |
|
615
|
|
|
* |
|
616
|
|
|
* @param Closure $callable |
|
617
|
|
|
* |
|
618
|
|
|
* @return Collection|null |
|
619
|
|
|
*/ |
|
620
|
|
|
public function rows(Closure $callable = null) |
|
621
|
|
|
{ |
|
622
|
|
|
if (is_null($callable)) { |
|
623
|
|
|
return $this->rows; |
|
624
|
|
|
} |
|
625
|
|
|
|
|
626
|
|
|
$this->rowsCallback = $callable; |
|
627
|
|
|
} |
|
628
|
|
|
|
|
629
|
|
|
/** |
|
630
|
|
|
* Set exporter driver for Grid to export. |
|
631
|
|
|
* |
|
632
|
|
|
* @param $exporter |
|
633
|
|
|
* |
|
634
|
|
|
* @return $this |
|
635
|
|
|
*/ |
|
636
|
|
|
public function exporter($exporter) |
|
637
|
|
|
{ |
|
638
|
|
|
$this->exporter = $exporter; |
|
639
|
|
|
|
|
640
|
|
|
return $this; |
|
641
|
|
|
} |
|
642
|
|
|
|
|
643
|
|
|
/** |
|
644
|
|
|
* Get the export url. |
|
645
|
|
|
* |
|
646
|
|
|
* @param int $scope |
|
647
|
|
|
* @param null $args |
|
648
|
|
|
* |
|
649
|
|
|
* @return string |
|
650
|
|
|
*/ |
|
651
|
|
|
public function getExportUrl($scope = 1, $args = null) |
|
652
|
|
|
{ |
|
653
|
|
|
$input = array_merge(Input::all(), Exporter::formatExportQuery($scope, $args)); |
|
654
|
|
|
|
|
655
|
|
|
if ($constraints = $this->model()->getConstraints()) { |
|
656
|
|
|
$input = array_merge($input, $constraints); |
|
657
|
|
|
} |
|
658
|
|
|
|
|
659
|
|
|
return $this->resource().'?'.http_build_query($input); |
|
660
|
|
|
} |
|
661
|
|
|
|
|
662
|
|
|
/** |
|
663
|
|
|
* Get create url. |
|
664
|
|
|
* |
|
665
|
|
|
* @return string |
|
666
|
|
|
*/ |
|
667
|
|
|
public function getCreateUrl() |
|
668
|
|
|
{ |
|
669
|
|
|
$queryString = ''; |
|
670
|
|
|
|
|
671
|
|
|
if ($constraints = $this->model()->getConstraints()) { |
|
672
|
|
|
$queryString = http_build_query($constraints); |
|
673
|
|
|
} |
|
674
|
|
|
|
|
675
|
|
|
return sprintf('%s/create%s', |
|
676
|
|
|
$this->resource(), |
|
677
|
|
|
$queryString ? ('?'.$queryString) : '' |
|
678
|
|
|
); |
|
679
|
|
|
} |
|
680
|
|
|
|
|
681
|
|
|
/** |
|
682
|
|
|
* If grid show export btn. |
|
683
|
|
|
* |
|
684
|
|
|
* @return bool |
|
685
|
|
|
*/ |
|
686
|
|
|
public function showExportBtn() |
|
687
|
|
|
{ |
|
688
|
|
|
return $this->option('show_exporter'); |
|
689
|
|
|
} |
|
690
|
|
|
|
|
691
|
|
|
/** |
|
692
|
|
|
* Disable export. |
|
693
|
|
|
* |
|
694
|
|
|
* @return $this |
|
695
|
|
|
*/ |
|
696
|
|
|
public function disableExport(bool $disable = true) |
|
697
|
|
|
{ |
|
698
|
|
|
return $this->option('show_exporter', !$disable); |
|
699
|
|
|
} |
|
700
|
|
|
|
|
701
|
|
|
/** |
|
702
|
|
|
* Render export button. |
|
703
|
|
|
* |
|
704
|
|
|
* @return string |
|
705
|
|
|
*/ |
|
706
|
|
|
public function renderExportButton() |
|
707
|
|
|
{ |
|
708
|
|
|
return (new Tools\ExportButton($this))->render(); |
|
709
|
|
|
} |
|
710
|
|
|
|
|
711
|
|
|
/** |
|
712
|
|
|
* Alias for method `disableCreateButton`. |
|
713
|
|
|
* |
|
714
|
|
|
* @return $this |
|
715
|
|
|
* |
|
716
|
|
|
* @deprecated |
|
717
|
|
|
*/ |
|
718
|
|
|
public function disableCreation() |
|
719
|
|
|
{ |
|
720
|
|
|
return $this->disableCreateButton(); |
|
721
|
|
|
} |
|
722
|
|
|
|
|
723
|
|
|
/** |
|
724
|
|
|
* Remove create button on grid. |
|
725
|
|
|
* |
|
726
|
|
|
* @return $this |
|
727
|
|
|
*/ |
|
728
|
|
|
public function disableCreateButton(bool $disable = true) |
|
729
|
|
|
{ |
|
730
|
|
|
return $this->option('show_create_btn', !$disable); |
|
731
|
|
|
} |
|
732
|
|
|
|
|
733
|
|
|
/** |
|
734
|
|
|
* If allow creation. |
|
735
|
|
|
* |
|
736
|
|
|
* @return bool |
|
737
|
|
|
*/ |
|
738
|
|
|
public function showCreateBtn() |
|
739
|
|
|
{ |
|
740
|
|
|
return $this->option('show_create_btn'); |
|
741
|
|
|
} |
|
742
|
|
|
|
|
743
|
|
|
/** |
|
744
|
|
|
* Render create button for grid. |
|
745
|
|
|
* |
|
746
|
|
|
* @return string |
|
747
|
|
|
*/ |
|
748
|
|
|
public function renderCreateButton() |
|
749
|
|
|
{ |
|
750
|
|
|
return (new Tools\CreateButton($this))->render(); |
|
751
|
|
|
} |
|
752
|
|
|
|
|
753
|
|
|
/** |
|
754
|
|
|
* Remove column selector on grid. |
|
755
|
|
|
* |
|
756
|
|
|
* @param bool $disable |
|
757
|
|
|
* |
|
758
|
|
|
* @return Grid|mixed |
|
759
|
|
|
*/ |
|
760
|
|
|
public function disableColumnSelector(bool $disable = true) |
|
761
|
|
|
{ |
|
762
|
|
|
return $this->option('show_column_selector', !$disable); |
|
763
|
|
|
} |
|
764
|
|
|
|
|
765
|
|
|
/** |
|
766
|
|
|
* @return bool |
|
767
|
|
|
*/ |
|
768
|
|
|
public function showColumnSelector() |
|
769
|
|
|
{ |
|
770
|
|
|
return $this->option('show_column_selector'); |
|
771
|
|
|
} |
|
772
|
|
|
|
|
773
|
|
|
/** |
|
774
|
|
|
* @return string |
|
775
|
|
|
*/ |
|
776
|
|
|
public function renderColumnSelector() |
|
777
|
|
|
{ |
|
778
|
|
|
return (new Grid\Tools\ColumnSelector($this))->render(); |
|
779
|
|
|
} |
|
780
|
|
|
|
|
781
|
|
|
/** |
|
782
|
|
|
* Get current resource uri. |
|
783
|
|
|
* |
|
784
|
|
|
* @param string $path |
|
785
|
|
|
* |
|
786
|
|
|
* @return string |
|
787
|
|
|
*/ |
|
788
|
|
|
public function resource($path = null) |
|
789
|
|
|
{ |
|
790
|
|
|
if (!empty($path)) { |
|
791
|
|
|
$this->resourcePath = $path; |
|
792
|
|
|
|
|
793
|
|
|
return $this; |
|
|
|
|
|
|
794
|
|
|
} |
|
795
|
|
|
|
|
796
|
|
|
if (!empty($this->resourcePath)) { |
|
797
|
|
|
return $this->resourcePath; |
|
798
|
|
|
} |
|
799
|
|
|
|
|
800
|
|
|
return app('request')->getPathInfo(); |
|
801
|
|
|
} |
|
802
|
|
|
|
|
803
|
|
|
/** |
|
804
|
|
|
* Handle get mutator column for grid. |
|
805
|
|
|
* |
|
806
|
|
|
* @param string $method |
|
807
|
|
|
* @param string $label |
|
808
|
|
|
* |
|
809
|
|
|
* @return bool|Column |
|
810
|
|
|
*/ |
|
811
|
|
|
protected function handleGetMutatorColumn($method, $label) |
|
812
|
|
|
{ |
|
813
|
|
|
if ($this->model()->eloquent()->hasGetMutator($method)) { |
|
814
|
|
|
return $this->addColumn($method, $label); |
|
815
|
|
|
} |
|
816
|
|
|
|
|
817
|
|
|
return false; |
|
818
|
|
|
} |
|
819
|
|
|
|
|
820
|
|
|
/** |
|
821
|
|
|
* Handle relation column for grid. |
|
822
|
|
|
* |
|
823
|
|
|
* @param string $method |
|
824
|
|
|
* @param string $label |
|
825
|
|
|
* |
|
826
|
|
|
* @return bool|Column |
|
827
|
|
|
*/ |
|
828
|
|
|
protected function handleRelationColumn($method, $label) |
|
829
|
|
|
{ |
|
830
|
|
|
$model = $this->model()->eloquent(); |
|
831
|
|
|
|
|
832
|
|
|
if (!method_exists($model, $method)) { |
|
833
|
|
|
return false; |
|
834
|
|
|
} |
|
835
|
|
|
|
|
836
|
|
|
if (!($relation = $model->$method()) instanceof Relations\Relation) { |
|
837
|
|
|
return false; |
|
838
|
|
|
} |
|
839
|
|
|
|
|
840
|
|
|
if ($relation instanceof Relations\HasOne || |
|
841
|
|
|
$relation instanceof Relations\BelongsTo || |
|
842
|
|
|
$relation instanceof Relations\MorphOne |
|
843
|
|
|
) { |
|
844
|
|
|
$this->model()->with($method); |
|
845
|
|
|
|
|
846
|
|
|
return $this->addColumn($method, $label)->setRelation(Str::snake($method)); |
|
847
|
|
|
} |
|
848
|
|
|
|
|
849
|
|
|
if ($relation instanceof Relations\HasMany |
|
850
|
|
|
|| $relation instanceof Relations\BelongsToMany |
|
851
|
|
|
|| $relation instanceof Relations\MorphToMany |
|
852
|
|
|
) { |
|
853
|
|
|
$this->model()->with($method); |
|
854
|
|
|
|
|
855
|
|
|
return $this->addColumn(Str::snake($method), $label); |
|
856
|
|
|
} |
|
857
|
|
|
|
|
858
|
|
|
return false; |
|
859
|
|
|
} |
|
860
|
|
|
|
|
861
|
|
|
/** |
|
862
|
|
|
* Dynamically add columns to the grid view. |
|
863
|
|
|
* |
|
864
|
|
|
* @param $method |
|
865
|
|
|
* @param $arguments |
|
866
|
|
|
* |
|
867
|
|
|
* @return Column |
|
868
|
|
|
*/ |
|
869
|
|
|
public function __call($method, $arguments) |
|
870
|
|
|
{ |
|
871
|
|
|
$label = isset($arguments[0]) ? $arguments[0] : ucfirst($method); |
|
872
|
|
|
|
|
873
|
|
|
if ($this->model()->eloquent() instanceof MongodbModel) { |
|
|
|
|
|
|
874
|
|
|
return $this->addColumn($method, $label); |
|
875
|
|
|
} |
|
876
|
|
|
|
|
877
|
|
|
if ($column = $this->handleGetMutatorColumn($method, $label)) { |
|
878
|
|
|
return $column; |
|
879
|
|
|
} |
|
880
|
|
|
|
|
881
|
|
|
if ($column = $this->handleRelationColumn($method, $label)) { |
|
882
|
|
|
return $column; |
|
883
|
|
|
} |
|
884
|
|
|
|
|
885
|
|
|
return $this->addColumn($method, $label); |
|
886
|
|
|
} |
|
887
|
|
|
|
|
888
|
|
|
/** |
|
889
|
|
|
* Register column displayers. |
|
890
|
|
|
* |
|
891
|
|
|
* @return void. |
|
|
|
|
|
|
892
|
|
|
*/ |
|
893
|
|
|
public static function registerColumnDisplayer() |
|
894
|
|
|
{ |
|
895
|
|
|
$map = [ |
|
896
|
|
|
'editable' => Displayers\Editable::class, |
|
897
|
|
|
'switch' => Displayers\SwitchDisplay::class, |
|
898
|
|
|
'switchGroup' => Displayers\SwitchGroup::class, |
|
899
|
|
|
'select' => Displayers\Select::class, |
|
900
|
|
|
'image' => Displayers\Image::class, |
|
901
|
|
|
'label' => Displayers\Label::class, |
|
902
|
|
|
'button' => Displayers\Button::class, |
|
903
|
|
|
'link' => Displayers\Link::class, |
|
904
|
|
|
'badge' => Displayers\Badge::class, |
|
905
|
|
|
'progressBar' => Displayers\ProgressBar::class, |
|
906
|
|
|
'radio' => Displayers\Radio::class, |
|
907
|
|
|
'checkbox' => Displayers\Checkbox::class, |
|
908
|
|
|
'orderable' => Displayers\Orderable::class, |
|
909
|
|
|
'table' => Displayers\Table::class, |
|
910
|
|
|
'expand' => Displayers\Expand::class, |
|
911
|
|
|
'modal' => Displayers\Modal::class, |
|
912
|
|
|
]; |
|
913
|
|
|
|
|
914
|
|
|
foreach ($map as $abstract => $class) { |
|
915
|
|
|
Column::extend($abstract, $class); |
|
916
|
|
|
} |
|
917
|
|
|
} |
|
918
|
|
|
|
|
919
|
|
|
/** |
|
920
|
|
|
* Add variables to grid view. |
|
921
|
|
|
* |
|
922
|
|
|
* @param array $variables |
|
923
|
|
|
* |
|
924
|
|
|
* @return $this |
|
925
|
|
|
*/ |
|
926
|
|
|
public function with($variables = []) |
|
927
|
|
|
{ |
|
928
|
|
|
$this->variables = $variables; |
|
929
|
|
|
|
|
930
|
|
|
return $this; |
|
931
|
|
|
} |
|
932
|
|
|
|
|
933
|
|
|
/** |
|
934
|
|
|
* Get all variables will used in grid view. |
|
935
|
|
|
* |
|
936
|
|
|
* @return array |
|
937
|
|
|
*/ |
|
938
|
|
|
protected function variables() |
|
939
|
|
|
{ |
|
940
|
|
|
$this->variables['grid'] = $this; |
|
941
|
|
|
|
|
942
|
|
|
return $this->variables; |
|
943
|
|
|
} |
|
944
|
|
|
|
|
945
|
|
|
/** |
|
946
|
|
|
* Set a view to render. |
|
947
|
|
|
* |
|
948
|
|
|
* @param string $view |
|
949
|
|
|
* @param array $variables |
|
950
|
|
|
*/ |
|
951
|
|
|
public function setView($view, $variables = []) |
|
952
|
|
|
{ |
|
953
|
|
|
if (!empty($variables)) { |
|
954
|
|
|
$this->with($variables); |
|
955
|
|
|
} |
|
956
|
|
|
|
|
957
|
|
|
$this->view = $view; |
|
958
|
|
|
} |
|
959
|
|
|
|
|
960
|
|
|
/** |
|
961
|
|
|
* Set grid title. |
|
962
|
|
|
* |
|
963
|
|
|
* @param string $title |
|
964
|
|
|
* |
|
965
|
|
|
* @return $this |
|
966
|
|
|
*/ |
|
967
|
|
|
public function setTitle($title) |
|
968
|
|
|
{ |
|
969
|
|
|
$this->variables['title'] = $title; |
|
970
|
|
|
|
|
971
|
|
|
return $this; |
|
972
|
|
|
} |
|
973
|
|
|
|
|
974
|
|
|
/** |
|
975
|
|
|
* Set relation for grid. |
|
976
|
|
|
* |
|
977
|
|
|
* @param Relations\Relation $relation |
|
978
|
|
|
* |
|
979
|
|
|
* @return $this |
|
980
|
|
|
*/ |
|
981
|
|
|
public function setRelation(Relations\Relation $relation) |
|
982
|
|
|
{ |
|
983
|
|
|
$this->model()->setRelation($relation); |
|
984
|
|
|
|
|
985
|
|
|
return $this; |
|
986
|
|
|
} |
|
987
|
|
|
|
|
988
|
|
|
/** |
|
989
|
|
|
* Set resource path for grid. |
|
990
|
|
|
* |
|
991
|
|
|
* @param string $path |
|
992
|
|
|
* |
|
993
|
|
|
* @return $this |
|
994
|
|
|
*/ |
|
995
|
|
|
public function setResource($path) |
|
996
|
|
|
{ |
|
997
|
|
|
$this->resourcePath = $path; |
|
998
|
|
|
|
|
999
|
|
|
return $this; |
|
1000
|
|
|
} |
|
1001
|
|
|
|
|
1002
|
|
|
/** |
|
1003
|
|
|
* Get the string contents of the grid view. |
|
1004
|
|
|
* |
|
1005
|
|
|
* @return string |
|
1006
|
|
|
*/ |
|
1007
|
|
|
public function render() |
|
1008
|
|
|
{ |
|
1009
|
|
|
$this->handleExportRequest(true); |
|
1010
|
|
|
|
|
1011
|
|
|
try { |
|
1012
|
|
|
$this->build(); |
|
1013
|
|
|
} catch (\Exception $e) { |
|
1014
|
|
|
return Handler::renderException($e); |
|
1015
|
|
|
} |
|
1016
|
|
|
|
|
1017
|
|
|
return view($this->view, $this->variables())->render(); |
|
|
|
|
|
|
1018
|
|
|
} |
|
1019
|
|
|
} |
|
1020
|
|
|
|
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.