Completed
Push — master ( 177b6c...6783c1 )
by Alexander
08:06
created

DataGrid::getItemsPerPage()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 1 Features 1
Metric Value
c 4
b 1
f 1
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
namespace AtDataGrid;
4
5
use AtDataGrid\DataSource;
6
use AtDataGrid\Column\Column;
7
use AtDataGrid\Filter\FilterInterface;
8
use Zend\Db\ResultSet\ResultSet;
9
use Zend\EventManager\EventManagerAwareTrait;
10
use Zend\Paginator\Paginator;
11
12
class DataGrid implements \Countable, \IteratorAggregate, \ArrayAccess
13
{
14
    use EventManagerAwareTrait;
15
16
    const EVENT_GRID_INSERT_PRE = 'at-datagrid.grid.insert.pre';
17
    const EVENT_GRID_INSERT_POST = 'at-datagrid.grid.insert.post';
18
19
    const EVENT_GRID_UPDATE_PRE = 'at-datagrid.grid.update.pre';
20
    const EVENT_GRID_UPDATE_POST = 'at-datagrid.grid.update.post';
21
22
    const EVENT_GRID_PERSIST_PRE = 'at-datagrid.grid.persist.pre';
23
    const EVENT_GRID_PERSIST_POST = 'at-datagrid.grid.persist.post';
24
25
    const EVENT_GRID_DELETE_PRE = 'at-datagrid.grid.delete.pre';
26
    const EVENT_GRID_DELETE_POST = 'at-datagrid.grid.delete.post';
27
28
    /**
29
     * Grid title
30
     *
31
     * @var string
32
     */
33
    protected $title;
34
35
    /**
36
     * Data source
37
     *
38
     * @var DataSource\AbstractDataSource
39
     */
40
    protected $dataSource;
41
42
    /**
43
     * Data grid columns
44
     *
45
     * @var array
46
     */
47
    protected $columns = [];
48
49
    /**
50
     * @var string
51
     */
52
    protected $identifierColumnName = 'id';
53
54
    /**
55
     * @var Paginator
56
     */
57
    protected $paginator;
58
59
    /**
60
     * Order in format ['id' => 'desc']
61
     *
62
     * @var array
63
     */
64
    protected $order;
65
66
    /**
67
     * Current page
68
     *
69
     * @var integer
70
     */
71
    protected $currentPage = 1;
72
73
    /**
74
     * Items per page
75
     *
76
     * @var integer
77
     */
78
    protected $itemsPerPage = 20;
79
80
    /**
81
     * Page range
82
     *
83
     * @var integer
84
     */
85
    protected $pageRange = 10;
86
87
    /**
88
     * Array of column filters
89
     *
90
     * @var array
91
     */
92
    protected $filters = [];
93
94
    /**
95
     * Array of rows from data source
96
     *
97
     * @var array
98
     */
99
    protected $data = [];
100
101
    /**
102
     * @param $dataSource
103
     * @param string $title
104
     */
105
    public function __construct($dataSource, $title = '')
106
    {
107
        $this->setDataSource($dataSource);
108
        $this->setTitle($title);
109
110
        // Collect column names from data source and create default column objects
111
        $this->columns = $this->getDataSource()->loadColumns();
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->getDataSource()->loadColumns() of type * is incompatible with the declared type array of property $columns.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
112
    }
113
    
114
    // METADATA
115
116
    /**
117
     * @param $title
118
     * @return $this
119
     */
120
    public function setTitle($title)
121
    {
122
        $this->title = $title;
123
        return $this;
124
    }
125
126
    /**
127
     * @return string
128
     */
129
    public function getTitle()
130
    {
131
        return $this->title;
132
    }
133
134
    // COLUMNS
135
136
    /**
137
     * @param $name
138
     * @return $this
139
     */
140
    public function setIdentifierColumnName($name)
141
    {
142
        $this->identifierColumnName = (string) $name;
143
        $this->getDataSource()->setIdentifierFieldName($this->identifierColumnName);
144
145
        return $this;
146
    }
147
148
    /**
149
     * @return string
150
     */
151
    public function getIdentifierColumnName()
152
    {
153
        return $this->identifierColumnName;
154
    }
155
156
    /**
157
     * Check if grid has column by the given name
158
     *
159
     * @param $name
160
     * @return bool
161
     */
162
    protected function hasColumn($name)
163
    {
164
        return array_key_exists($name, $this->columns);
165
    }
166
167
    /**
168
     * Add a column to data grid
169
     *
170
     * @param Column $column
171
     * @return $this
172
     */
173
    public function addColumn(Column $column)
174
    {
175
        $columnName = $column->getName();
176
        if ($this->hasColumn($columnName) ) {
177
            throw new \Exception('Column `' . $columnName . '` already presents in grid.');
178
        }    
179
        
180
        $this->columns[$columnName] = $column;
181
    	return $this;
182
    }
183
184
    /**
185
     * Set column by given name with overwriting.
186
     *
187
     * @param Column $column
188
     * @return $this
189
     */
190
    public function setColumn(Column $column)
191
    {
192
        $this->columns[$column->getName()] = $column;
193
        return $this;
194
    }
195
196
    /**
197
     * Return column object specified by it name
198
     *
199
     * @param $name
200
     * @return Column
201
     * @throws \Exception
202
     */
203
    public function getColumn($name)
204
    {
205
        if ($this->hasColumn($name)) {
206
            return $this->columns[$name];
207
        }
208
209
        throw new \Exception("Column '" . $name . "' doesn't presents in grid.");
210
    }
211
212
    /**
213
     * Return all column objects
214
     *
215
     * @return array
216
     */
217
    public function getColumns()
218
    {
219
        return $this->columns;
220
    }
221
222
    /**
223
     * Remove column specified by it name
224
     *
225
     * @param $name
226
     * @return DataGrid
227
     */
228
    public function removeColumn($name)
229
    {
230
        if ($this->hasColumn($name)) {
231
            unset($this->columns[$name]);
232
        }
233
234
    	return $this;	
235
    }
236
237
    /**
238
     * Remove columns specified by its names
239
     *
240
     * @param array $names
241
     * @return DataGrid
242
     */
243
    public function removeColumns(array $names)
244
    {
245
        foreach ($names as $name) {
246
	        $this->removeColumn($name);
247
        }
248
249
        return $this;
250
    }
251
252
    /**
253
     * Set columns invisible in grid
254
     *
255
     * @param array $names
256
     * @return DataGrid
257
     */
258
    public function hideColumns(array $names)
259
    {
260
        foreach ($names as $name) {
261
            $this->getColumn($name)->setVisible(false);
262
        }
263
264
        return $this;                   
265
    }
266
267
    /**
268
     * Set columns invisible in form
269
     *
270
     * @param $names
271
     * @return DataGrid
272
     */
273
    public function hideColumnsInForm(array $names)
274
    {
275
        foreach ($names as $name) {
276
            $this->getColumn($name)->setVisibleInForm(false);
277
        }
278
279
        return $this;
280
    }
281
282
    /**
283
     * Set columns visible in grid
284
     *
285
     * @param array $names
286
     * @return DataGrid
287
     */
288
    public function showColumns(array $names)
289
    {
290
        foreach ($names as $name) {
291
            $this->getColumn($name)->setVisible(true);
292
        }
293
294
        return $this;
295
    }
296
297
    /**
298
     * Set columns visible in form
299
     *
300
     * @param $names
301
     * @return DataGrid
302
     */
303
    public function showColumnsInForm(array $names)
304
    {
305
        foreach ($names as $name) {
306
            $this->getColumn($name)->setVisibleInForm(true);
307
        }
308
309
        return $this;
310
    }
311
312
    // SORTING
313
314
    /**
315
     * @param array $order
316
     */
317
    public function setOrder(array $order)
318
    {
319
        $column = key($order);
320
        $direction = $order[$column];
321
        if ($this->hasColumn($column) && in_array(strtolower($direction), ['asc', 'desc'])) {
322
            $this->order = $order;
323
        }
324
    }
325
326
    /**
327
     * @return array
328
     */
329
    public function getOrder()
330
    {
331
        return $this->order;
332
    }
333
334
    /**
335
     * @return mixed
336
     */
337
    public function getOrderColumn()
338
    {
339
        if (!empty($this->order)) {
340
            return key($this->order);
341
        }
342
343
        return null;
344
    }
345
346
    /**
347
     * @return mixed
348
     */
349
    public function getOrderDirection()
350
    {
351
        if (!empty($this->order)) {
352
            return strtolower($this->order[key($this->order)]);
353
        }
354
355
        return null;
356
    }
357
358
    /**
359
     * @return string
360
     */
361
    public function getRevertOrderDirection()
362
    {
363
        return ($this->getOrderDirection() == 'asc') ? 'desc' : 'asc';
364
    }
365
366
    // DATA SOURCE
367
368
    /**
369
     * @param DataSource\AbstractDataSource $dataSource
370
     * @return $this
371
     */
372
    public function setDataSource(DataSource\AbstractDataSource $dataSource)
373
    {
374
        $this->dataSource = $dataSource;
375
    	return $this;
376
    }
377
378
    /**
379
     * @return DataSource\AbstractDataSource
380
     */
381
    public function getDataSource()
382
    {
383
        return $this->dataSource;
384
    }
385
    
386
    /**
387
     * Find row by primary key
388
     *
389
     * @param $key
390
     * @return mixed
391
     */
392
    public function getRow($key)
393
    {
394
        return $this->getDataSource()->find($key);
395
    }
396
397
    /**
398
     * @return mixed
399
     * @throws \Exception
400
     */
401
    public function getData()
402
    {
403
        // Prepare data source for fetching data
404
    	$this->getDataSource()->prepare($this->getOrder(), $this->getFilters());
405
406
        // Load data using paginator
407
        $this->paginator = new Paginator($this->getDataSource()->getPaginatorAdapter());
408
        $this->paginator->setCurrentPageNumber($this->currentPage);
409
        $this->paginator->setItemCountPerPage($this->itemsPerPage);
410
        $this->paginator->setPageRange($this->pageRange);
411
        $data = $this->paginator->getCurrentItems();
412
413
        // Convert data to array
414
        if (! is_array($data)) {
415
            if ($data instanceof ResultSet) {
0 ignored issues
show
Bug introduced by
The class Zend\Db\ResultSet\ResultSet does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
416
                $data = $data->toArray();
417
            } elseif ($data instanceof \ArrayIterator) {
418
                $data = $data->getArrayCopy();
419
            } else {
420
                throw new \RuntimeException('Result data couldn\'t be converted to array');
421
            }
422
        }
423
424
        $this->data = $data;
425
        return $this->data;
426
    }
427
428
    /**
429
     * @return Paginator
430
     */
431
    public function getPaginator()
432
    {
433
        return $this->paginator;
434
    }
435
436
    // CRUD
437
438
    /**
439
     * @param $data
440
     * @return mixed
441
     */
442
    public function save($data, $identifier = null)
443
    {
444
        $eventResult = $this->getEventManager()->trigger(self::EVENT_GRID_PERSIST_PRE, $this, $data)->last();
445
        if ($eventResult) {
446
            $data = $eventResult;
447
        }
448
449
        if (!$identifier) {
450
            $id = $this->insert($data);
451
        } else {
452
            $id = $this->update($data, $identifier);
453
        }
454
455
        $data[$this->getIdentifierColumnName()] = $id;
456
457
        $this->getEventManager()->trigger(self::EVENT_GRID_PERSIST_POST, $this, $data);
458
459
        return $this->getRow($id);
460
    }
461
462
    /**
463
     * @param $data
464
     * @return mixed
465
     */
466
    public function insert($data)
467
    {
468
        $eventResult = $this->getEventManager()->trigger(self::EVENT_GRID_INSERT_PRE, $this, $data)->last();
469
        if ($eventResult) {
470
            $data = $eventResult;
471
        }
472
473
        $id = $this->getDataSource()->insert($data);
474
475
        $data[$this->getIdentifierColumnName()] = $id;
476
        $this->getEventManager()->trigger(self::EVENT_GRID_INSERT_POST, $this, $data);
477
478
        return $id;
479
    }
480
481
    /**
482
     * @param $data
483
     * @param $primary
484
     * @return mixed
485
     */
486
    public function update($data, $primary)
487
    {
488
        $eventResult = $this->getEventManager()->trigger(self::EVENT_GRID_UPDATE_PRE, $this, $data)->last();
489
        if ($eventResult) {
490
            $data = $eventResult;
491
        }
492
493
        $this->getDataSource()->update($data, $primary);
494
        $data[$this->getIdentifierColumnName()] = $primary;
495
496
        $this->getEventManager()->trigger(self::EVENT_GRID_UPDATE_POST, $this, $data);
497
498
        return $primary;
499
    }
500
501
    /**
502
     * @param $id
503
     */
504
    public function delete($id)
505
    {
506
        $identifierColumnName = $this->getIdentifierColumnName();
507
508
        $this->getEventManager()->trigger(self::EVENT_GRID_DELETE_PRE, $this, [$identifierColumnName => $id]);
509
        $this->getDataSource()->delete($id);
510
        $this->getEventManager()->trigger(self::EVENT_GRID_DELETE_POST, $this, [$identifierColumnName => $id]);
511
    }
512
513
    // FILTERS
514
515
    /**
516
     * @param FilterInterface $filter
517
     * @param Column $column
518
     * @return $this
519
     */
520
    public function addFilter(FilterInterface $filter, Column $column)
521
    {
522
        if (! $filter->getName()) {
523
            $filter->setName($column->getName());
524
        }
525
526
        if (! $filter->getLabel()) {
527
            $filter->setLabel($column->getLabel());
528
        }
529
530
        $this->filters[$filter->getName()] = $filter;
531
532
        return $this;
533
    }
534
535
    /**
536
     * @param $columnName
537
     * @return bool
538
     */
539
    public function hasFilter($columnName)
540
    {
541
        return array_key_exists($columnName, $this->filters);
542
    }
543
544
    /**
545
     * @param $columnName
546
     * @return null
547
     */
548
    public function getFilter($columnName)
549
    {
550
        if ($this->hasFilter($columnName)) {
551
            return $this->filters[$columnName];
552
        }
553
554
        return null;
555
    }
556
557
    /**
558
     * @return array
559
     */
560
    public function getFilters()
561
    {
562
        return $this->filters;
563
    }
564
565
    /**
566
     * @return bool
567
     */
568
    public function hasFilters()
569
    {
570
        return count($this->getFilters()) > 0;
571
    }
572
573
    /**
574
     * @param $values
575
     */
576
    public function setFiltersData($values)
577
    {
578
        /** @var FilterInterface $filter */
579
        foreach ($this->getFilters() as $filter) {
580
            $filter->setValue($values[$filter->getName()]);
581
        }
582
    }
583
584
    // PAGINATOR
585
586
    /**
587
     * @param $number
588
     * @return $this
589
     */
590
    public function setCurrentPage($number)
591
    {
592
        $this->currentPage = (int) $number;
593
        return $this;
594
    }
595
596
    /**
597
     * @return int
598
     */
599
    public function getCurrentPage()
600
    {
601
        return $this->currentPage;
602
    }
603
604
605
    /**
606
     * @param $count
607
     * @return $this
608
     */
609
    public function setItemsPerPage($count)
610
    {
611
        $this->itemsPerPage = (int) $count;
612
        return $this;
613
    }
614
615
    /**
616
     * @return int
617
     */
618
    public function getItemsPerPage()
619
    {
620
        return $this->itemsPerPage;
621
    }
622
623
    /**
624
     * @param $count
625
     * @return $this
626
     */
627
    public function setPageRange($count)
628
    {
629
        $this->pageRange = (int) $count;
630
        return $this;
631
    }
632
633
    // INTERFACES IMPLEMENTATION
634
635
    /**
636
     * @return mixed
637
     */
638
    public function current()
639
    {
640
        return current($this->columns);
641
    }
642
643
    /**
644
     * @return bool
645
     */
646
    public function valid()
647
    {
648
        return ($this->current() !== false);
649
    }
650
651
    /**
652
     * @return mixed
653
     */
654
    public function next()
655
    {
656
        return next($this->columns);
657
    }
658
659
    /**
660
     * @return mixed
661
     */
662
    public function key()
663
    {
664
        return key($this->columns);
665
    }
666
667
    /**
668
     * @return mixed
669
     */
670
    public function rewind()
671
    {
672
        return reset($this->columns);
673
    }
674
675
    /**
676
     * @return int
677
     */
678
    public function count()
679
    {
680
        return count($this->columns);
681
    }
682
683
    /**
684
     * @param mixed $offset
685
     * @return bool
686
     */
687
    public function offsetExists($offset)
688
    {
689
        return isset($this->columns[$offset]);
690
    }
691
692
    /**
693
     * @param mixed $offset
694
     * @return bool|mixed
695
     */
696
    public function offsetGet($offset)
697
    {
698
        if(isset($this->columns[$offset])) {
699
            return $this->columns[$offset];
700
        }
701
702
        return false;
703
    }
704
705
    /**
706
     * @param mixed $offset
707
     * @param mixed $column
708
     */
709
    public function offsetSet($offset, $column)
710
    {
711
        if ($offset !== null) {
712
            $this->columns[$offset] = $column;
713
        } else {
714
            $this->columns[] = $column;
715
        }
716
    }
717
718
    /**
719
     * @param mixed $offset
720
     */
721
    public function offsetUnset($offset)
722
    {
723
        if (isset($this->columns[$offset])) {
724
            unset($this->columns[$offset]);
725
        }
726
    }
727
728
    /**
729
     * Get an iterator for iterating over the elements in the collection.
730
     *
731
     * @return \ArrayIterator|\Traversable
732
     */
733
    public function getIterator()
734
    {
735
        return new \ArrayIterator($this->columns);
736
    }
737
}