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