Completed
Push — master ( 14f10a...6ec6b5 )
by Adam
02:31
created

Grid::getHtmlBuilder()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 4
rs 10
1
<?php
2
3
namespace Boduch\Grid;
4
5
use Boduch\Grid\Components\RowAction;
6
use Boduch\Grid\Source\SourceInterface;
7
use Illuminate\Pagination\LengthAwarePaginator;
8
use Illuminate\Pagination\Paginator;
9
10
class Grid
11
{
12
    /**
13
     * @var string
14
     */
15
    protected $template = 'laravel-grid::grid';
16
17
    /**
18
     * @var GridHelper
19
     */
20
    protected $gridHelper;
21
22
    /**
23
     * @var SourceInterface
24
     */
25
    protected $source;
26
27
    /**
28
     * @var Column[]
29
     */
30
    protected $columns = [];
31
32
    /**
33
     * @var int
34
     */
35
    protected $perPage = 15;
36
37
    /**
38
     * @var string
39
     */
40
    protected $emptyMessage = 'Brak danych do wyświetlenia.';
41
42
    /**
43
     * @var Rows
44
     */
45
    protected $rows;
46
47
    /**
48
     * Total number of records.
49
     *
50
     * @var int
51
     */
52
    protected $total = 0;
53
54
    /**
55
     * @var RowAction[]
56
     */
57
    protected $rowActions = [];
58
59
    /**
60
     * @var array
61
     */
62
    protected $defaultOrder = [
63
        'column' => 'id',
64
        'direction' => 'desc'
65
    ];
66
67
    /**
68
     * @var Order
69
     */
70
    protected $order;
71
72
    /**
73
     * @var bool
74
     */
75
    protected $enablePagination = true;
76
77
    /**
78
     * @var callable
79
     */
80
    protected $eachCallback;
81
82
    /**
83
     * @var array
84
     */
85
    protected $data = [];
86
87
    /**
88
     * @param GridHelper $gridHelper
89
     */
90
    public function __construct(GridHelper $gridHelper)
91
    {
92
        $this->gridHelper = $gridHelper;
93
94
        $this->makeDefaultOrder();
95
    }
96
97
    public function buildGrid()
98
    {
99
        //
100
    }
101
102
    /**
103
     * @return GridHelper
104
     */
105
    public function getGridHelper()
106
    {
107
        return $this->gridHelper;
108
    }
109
110
    /**
111
     * @param SourceInterface $source
112
     * @return $this
113
     */
114
    public function setSource(SourceInterface $source)
115
    {
116
        $this->source = $source;
117
118
        return $this;
119
    }
120
121
    /**
122
     * @param string $name
123
     * @param array $options
124
     * @return $this
125
     */
126
    public function addColumn($name, array $options = [])
127
    {
128
        if ($name instanceof Column) {
129
            $column = $name;
130
        } else {
131
            $column = $this->makeColumn($name, $options);
132
        }
133
134
        $column->setGrid($this);
135
        $this->columns[$column->getName()] = $column;
136
137
        return $this;
138
    }
139
140
    /**
141
     * @return Column[]
142
     */
143
    public function getColumns()
144
    {
145
        return $this->columns;
146
    }
147
148
    /**
149
     * @param Order $order
150
     * @return $this
151
     */
152
    public function setDefaultOrder(Order $order)
153
    {
154
        $this->order = $order;
155
156
        return $this;
157
    }
158
159
    /**
160
     * @return Order
161
     */
162
    public function getOrder()
163
    {
164
        return $this->order;
165
    }
166
167
    /**
168
     * @param int $perPage
169
     * @return $this
170
     */
171
    public function setPerPage($perPage)
172
    {
173
        $this->perPage = $perPage;
174
175
        return $this;
176
    }
177
178
    /**
179
     * @return int
180
     */
181
    public function getPerPage()
182
    {
183
        return $this->perPage;
184
    }
185
186
    /**
187
     * @return string
188
     */
189
    public function getEmptyMessage()
190
    {
191
        return $this->emptyMessage;
192
    }
193
194
    /**
195
     * @param string $emptyMessage
196
     */
197
    public function setEmptyMessage($emptyMessage)
198
    {
199
        $this->emptyMessage = $emptyMessage;
200
    }
201
202
    /**
203
     * @param RowAction $rowAction
204
     * @return $this
205
     */
206
    public function addRowAction(RowAction $rowAction)
207
    {
208
        $rowAction->setGrid($this);
209
        $this->rowActions[] = $rowAction;
210
211
        return $this;
212
    }
213
214
    /**
215
     * @param bool $flag
216
     * @return $this
217
     */
218
    public function setEnablePagination($flag)
219
    {
220
        $this->enablePagination = (bool) $flag;
221
        $this->setPerPage(null);
222
223
        return $this;
224
    }
225
226
    /**
227
     * @return bool
228
     */
229
    public function isPaginationEnabled()
230
    {
231
        return $this->enablePagination;
232
    }
233
234
    /**
235
     * @param callable $callback
236
     */
237
    public function each(callable $callback)
238
    {
239
        $this->eachCallback = $callback;
240
    }
241
242
    /**
243
     * @param array $data
244
     * @return $this
245
     */
246
    public function setData($data)
247
    {
248
        $this->data = $data;
249
250
        return $this;
251
    }
252
253
    /**
254
     * @return \Illuminate\View\View;
0 ignored issues
show
Documentation introduced by
The doc-type \Illuminate\View\View; could not be parsed: Expected "|" or "end of type", but got ";" at position 21. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
255
     */
256
    public function render()
257
    {
258
        $rows = $this->getRows();
259
        $pagination = null;
260
261
        if ($this->enablePagination) {
262
            $pagination = $this->getPaginator($rows)->appends($this->gridHelper->getRequest()->except('page'));
263
        }
264
265
        return $this->gridHelper->getView()->make($this->template, [
266
            'columns'       => $this->columns,
267
            'rows'          => $rows,
268
            'pagination'    => $pagination,
269
            'grid'          => $this,
270
            'is_filterable' => $this->isFilterable()
271
        ], $this->data);
272
    }
273
274
    /**
275
     * Is table filterable?
276
     *
277
     * @return bool
278
     */
279
    public function isFilterable()
280
    {
281
        $hasFilters = false;
282
283
        foreach ($this->columns as $column) {
284
            if ($column->isFilterable()) {
285
                $hasFilters = true;
286
                break;
287
            }
288
        }
289
290
        return $hasFilters;
291
    }
292
293
    /**
294
     * @return Rows
295
     */
296
    public function getRows()
297
    {
298
        if (empty($this->source)) {
299
            throw new \InvalidArgumentException('You MUST set the data grid source by calling setSource() method.');
300
        }
301
302
        if (!empty($this->rows)) {
303
            return $this->rows;
304
        }
305
306
        if ($this->gridHelper->getRequest()->has('column') && !empty($this->defaultOrder)) {
307
            $this->order = new Order(
308
                $this->gridHelper->getRequest()->get('column', $this->defaultOrder['column']),
309
                $this->gridHelper->getRequest()->get('direction', $this->defaultOrder['direction'])
310
            );
311
312
            $validator = $this->gridHelper->getValidatorInstance($this->getValidatorRules());
313
314
            if ($validator->fails()) {
315
                $this->makeDefaultOrder();
316
            }
317
        }
318
319
        $data = $this->execute();
320
        $this->rows = new Rows();
321
322
        // special column for action buttons
323
        $actions = new Column(['name' => '__actions__']);
324
        $actions->setGrid($this);
325
326
        foreach ($data as $mixed) {
327
            $row = new Row($mixed);
328
            $row->setGrid($this);
329
330
            foreach ($this->columns as $column) {
331
                $row->addCell(new Cell($column, $mixed));
332
            }
333
334
            $row->addCell((new Action($actions, $mixed))->setRowActions($this->rowActions));
335
336
            if ($this->eachCallback) {
337
                $this->eachCallback->call($this, $row);
338
            }
339
            $this->rows->addRow($row);
340
        }
341
342
        $this->columns[] = $actions;
343
344
        return $this->rows;
345
    }
346
347
    /**
348
     * @param Rows $rows
349
     * @return LengthAwarePaginator
350
     */
351
    protected function getPaginator(Rows $rows)
352
    {
353
        return new LengthAwarePaginator($rows, $this->total, $this->perPage, $this->resolveCurrentPage(), [
354
            'path' => $this->resolveCurrentPath(),
355
        ]);
356
    }
357
358
    /**
359
     * @return mixed
360
     */
361
    protected function execute()
362
    {
363
        $this->source->applyFilters($this->columns, $this->gridHelper->getRequest());
364
365
        if ($this->enablePagination) {
366
            $this->total = $this->source->total();
367
        }
368
369
        return $this->source->execute($this->perPage, $this->resolveCurrentPage(), $this->order);
370
    }
371
372
    /**
373
     * @return int
374
     */
375
    protected function resolveCurrentPage()
376
    {
377
        return Paginator::resolveCurrentPage();
378
    }
379
380
    /**
381
     * @return string
382
     */
383
    protected function resolveCurrentPath()
384
    {
385
        return Paginator::resolveCurrentPath();
386
    }
387
388
    /**
389
     * @return array
390
     */
391
    protected function getValidatorRules()
392
    {
393
        $allowed = [];
394
395
        foreach ($this->columns as $column) {
396
            if ($column->isSortable()) {
397
                $allowed[] = $column->getName();
398
            }
399
        }
400
401
        return [
402
            'column' => 'sometimes|in:' . implode(',', $allowed),
403
            'direction' => 'sometimes|in:asc,desc'
404
        ];
405
    }
406
407
    protected function makeDefaultOrder()
408
    {
409
        $this->order = $this->defaultOrder
410
            ? new Order($this->defaultOrder['column'], $this->defaultOrder['direction'])
411
            : new Order();
412
    }
413
414
    /**
415
     * @param string $name
416
     * @param array $options
417
     * @return Column
418
     */
419
    protected function makeColumn($name, array $options = [])
420
    {
421
        $options = $this->setupColumnOptions($name, $options);
422
423
        return new Column($options);
424
    }
425
426
    /**
427
     * @param string $name
428
     * @param array $options
429
     * @return array
430
     */
431
    protected function setupColumnOptions($name, array $options)
432
    {
433
        $default = ['name' => $name];
434
435
        return array_merge($default, $options);
436
    }
437
438
    /**
439
     * @return string
440
     */
441
    public function __toString()
442
    {
443
        return (string) $this->render();
444
    }
445
}
446