DataGrid::getIdentifierColumnName()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
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
    const EVENT_GRID_UPDATE_PRE = 'at-datagrid.grid.update.pre';
19
    const EVENT_GRID_UPDATE_POST = 'at-datagrid.grid.update.post';
20
    const EVENT_GRID_PERSIST_PRE = 'at-datagrid.grid.persist.pre';
21
    const EVENT_GRID_PERSIST_POST = 'at-datagrid.grid.persist.post';
22
    const EVENT_GRID_DELETE_PRE = 'at-datagrid.grid.delete.pre';
23
    const EVENT_GRID_DELETE_POST = 'at-datagrid.grid.delete.post';
24
25
    /**
26
     * @var string
27
     */
28
    private $title;
29
30
    /**
31
     * @var DataSource\AbstractDataSource
32
     */
33
    private $dataSource;
34
35
    /**
36
     * Data grid columns
37
     *
38
     * @var array
39
     */
40
    private $columns = [];
41
42
    /**
43
     * @var string
44
     */
45
    private $identifierColumnName = 'id';
46
47
    /**
48
     * @var Paginator
49
     */
50
    private $paginator;
51
52
    /**
53
     * Order in format ['id' => 'desc']
54
     *
55
     * @var array
56
     */
57
    private $order;
58
59
    /**
60
     * Current page
61
     *
62
     * @var integer
63
     */
64
    private $currentPage = 1;
65
66
    /**
67
     * Items per page
68
     *
69
     * @var integer
70
     */
71
    private $itemsPerPage = 20;
72
73
    /**
74
     * Page range
75
     *
76
     * @var integer
77
     */
78
    private $pageRange = 10;
79
80
    /**
81
     * Array of column filters
82
     *
83
     * @var array
84
     */
85
    private $filters = [];
86
87
    /**
88
     * Array of rows from data source
89
     *
90
     * @var array
91
     */
92
    private $data = [];
93
94
    /**
95
     * @param $dataSource
96
     * @param string $title
97
     */
98
    public function __construct($dataSource, $title = '')
99
    {
100
        $this->setDataSource($dataSource);
101
        $this->setTitle($title);
102
103
        // Collect column names from data source and create default column objects
104
        $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...
105
    }
106
    
107
    // METADATA
108
109
    /**
110
     * @param string $title
111
     * @return $this
112
     */
113
    public function setTitle($title)
114
    {
115
        $this->title = $title;
116
        return $this;
117
    }
118
119
    /**
120
     * @return string
121
     */
122
    public function getTitle()
123
    {
124
        return $this->title;
125
    }
126
127
    // COLUMNS
128
129
    /**
130
     * @param $name
131
     * @return $this
132
     */
133
    public function setIdentifierColumnName($name)
134
    {
135
        $this->identifierColumnName = (string) $name;
136
        $this->getDataSource()->setIdentifierFieldName($this->identifierColumnName);
137
138
        return $this;
139
    }
140
141
    /**
142
     * @return string
143
     */
144
    public function getIdentifierColumnName()
145
    {
146
        return $this->identifierColumnName;
147
    }
148
149
    /**
150
     * Check if grid has column by the given name
151
     *
152
     * @param $name
153
     * @return bool
154
     */
155
    protected function hasColumn($name)
156
    {
157
        return array_key_exists($name, $this->columns);
158
    }
159
160
    /**
161
     * Add a column to data grid
162
     *
163
     * @param Column $column
164
     * @return $this
165
     * @throws \Exception
166
     */
167
    public function addColumn(Column $column)
168
    {
169
        $columnName = $column->getName();
170
        if ($this->hasColumn($columnName) ) {
171
            throw new \Exception('Column `' . $columnName . '` already presents in grid.');
172
        }    
173
        
174
        $this->columns[$columnName] = $column;
175
    	return $this;
176
    }
177
178
    /**
179
     * Set column by given name with overwriting.
180
     *
181
     * @param Column $column
182
     * @return $this
183
     */
184
    public function setColumn(Column $column)
185
    {
186
        $this->columns[$column->getName()] = $column;
187
        return $this;
188
    }
189
190
    /**
191
     * Return column object specified by it name
192
     *
193
     * @param $name
194
     * @return Column
195
     * @throws \Exception
196
     */
197
    public function getColumn($name)
198
    {
199
        if ($this->hasColumn($name)) {
200
            return $this->columns[$name];
201
        }
202
203
        throw new \Exception("Column '" . $name . "' not found.");
204
    }
205
206
    /**
207
     * Return all column objects
208
     *
209
     * @return array
210
     */
211
    public function getColumns()
212
    {
213
        return $this->columns;
214
    }
215
216
    /**
217
     * Remove column specified by it name
218
     *
219
     * @param $name
220
     * @return DataGrid
221
     */
222
    public function removeColumn($name)
223
    {
224
        if ($this->hasColumn($name)) {
225
            unset($this->columns[$name]);
226
        }
227
228
    	return $this;	
229
    }
230
231
    /**
232
     * Remove columns specified by its names
233
     *
234
     * @param array $names
235
     * @return DataGrid
236
     */
237
    public function removeColumns(array $names)
238
    {
239
        foreach ($names as $name) {
240
	        $this->removeColumn($name);
241
        }
242
243
        return $this;
244
    }
245
246
    /**
247
     * Set columns invisible in grid
248
     *
249
     * @param array $names
250
     * @return DataGrid
251
     */
252
    public function hideColumns(array $names)
253
    {
254
        foreach ($names as $name) {
255
            $this->getColumn($name)->setVisible(false);
256
        }
257
258
        return $this;                   
259
    }
260
261
    /**
262
     * Set columns invisible in form
263
     *
264
     * @param $names
265
     * @return DataGrid
266
     */
267
    public function hideColumnsInForm(array $names)
268
    {
269
        foreach ($names as $name) {
270
            $this->getColumn($name)->setVisibleInForm(false);
271
        }
272
273
        return $this;
274
    }
275
276
    /**
277
     * Set columns visible in grid
278
     *
279
     * @param array $names
280
     * @return DataGrid
281
     */
282
    public function showColumns(array $names)
283
    {
284
        foreach ($names as $name) {
285
            $this->getColumn($name)->setVisible(true);
286
        }
287
288
        return $this;
289
    }
290
291
    /**
292
     * Set columns visible in form
293
     *
294
     * @param $names
295
     * @return DataGrid
296
     */
297
    public function showColumnsInForm(array $names)
298
    {
299
        foreach ($names as $name) {
300
            $this->getColumn($name)->setVisibleInForm(true);
301
        }
302
303
        return $this;
304
    }
305
306
    // SORTING
307
308
    /**
309
     * @param array $order
310
     */
311
    public function setOrder(array $order)
312
    {
313
        $column = key($order);
314
        $direction = $order[$column];
315
        if ($this->hasColumn($column) && in_array(strtolower($direction), ['asc', 'desc'])) {
316
            $this->order = $order;
317
        }
318
    }
319
320
    /**
321
     * @return array
322
     */
323
    public function getOrder()
324
    {
325
        return $this->order;
326
    }
327
328
    /**
329
     * @return mixed
330
     */
331
    public function getOrderColumn()
332
    {
333
        if (!empty($this->order)) {
334
            return key($this->order);
335
        }
336
337
        return null;
338
    }
339
340
    /**
341
     * @return string|null
342
     */
343
    public function getOrderDirection()
344
    {
345
        if (!empty($this->order)) {
346
            return strtolower($this->order[key($this->order)]);
347
        }
348
349
        return null;
350
    }
351
352
    /**
353
     * @return string
354
     */
355
    public function getRevertOrderDirection()
356
    {
357
        return ($this->getOrderDirection() == 'asc') ? 'desc' : 'asc';
358
    }
359
360
    // DATA SOURCE
361
362
    /**
363
     * @param DataSource\AbstractDataSource $dataSource
364
     * @return $this
365
     */
366
    public function setDataSource(DataSource\AbstractDataSource $dataSource)
367
    {
368
        $this->dataSource = $dataSource;
369
    	return $this;
370
    }
371
372
    /**
373
     * @return DataSource\AbstractDataSource
374
     */
375
    public function getDataSource()
376
    {
377
        return $this->dataSource;
378
    }
379
    
380
    /**
381
     * Find row by primary key
382
     *
383
     * @param $key
384
     * @return mixed
385
     */
386
    public function getRow($key)
387
    {
388
        return $this->getDataSource()->find($key);
389
    }
390
391
    /**
392
     * @return mixed
393
     * @throws \Exception
394
     */
395
    public function getData()
396
    {
397
        // Prepare data source for fetching data
398
    	$this->getDataSource()->prepare($this->getOrder(), $this->getFilters());
399
400
        // Load data using paginator
401
        $this->paginator = new Paginator($this->getDataSource()->getPaginatorAdapter());
402
        $this->paginator->setCurrentPageNumber($this->currentPage);
403
        $this->paginator->setItemCountPerPage($this->itemsPerPage);
404
        $this->paginator->setPageRange($this->pageRange);
405
        $data = $this->paginator->getCurrentItems();
406
407
        // Convert data to array
408
        if (!is_array($data)) {
409
            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...
410
                $data = $data->toArray();
411
            } elseif ($data instanceof \ArrayIterator || $data instanceof \ArrayObject) {
412
                $data = $data->getArrayCopy();
413
            } else {
414
                throw new \RuntimeException('Result data couldn\'t be converted to array');
415
            }
416
        }
417
418
        $this->data = $data;
419
        return $this->data;
420
    }
421
422
    /**
423
     * @return Paginator
424
     */
425
    public function getPaginator()
426
    {
427
        return $this->paginator;
428
    }
429
430
    // CRUD
431
432
    /**
433
     * @param $data
434
     * @return mixed
435
     */
436
    public function save($data, $identifier = null)
437
    {
438
        $eventResult = $this->getEventManager()->trigger(self::EVENT_GRID_PERSIST_PRE, $this, $data)->last();
439
        if ($eventResult) {
440
            $data = $eventResult;
441
        }
442
443
        if (!$identifier) {
444
            $id = $this->insert($data);
445
        } else {
446
            $id = $this->update($data, $identifier);
447
        }
448
449
        $data[$this->getIdentifierColumnName()] = $id;
450
451
        $this->getEventManager()->trigger(self::EVENT_GRID_PERSIST_POST, $this, $data);
452
453
        return $this->getRow($id);
454
    }
455
456
    /**
457
     * @param $data
458
     * @return mixed
459
     */
460
    public function insert($data)
461
    {
462
        $eventResult = $this->getEventManager()->trigger(self::EVENT_GRID_INSERT_PRE, $this, $data)->last();
463
        if ($eventResult) {
464
            $data = $eventResult;
465
        }
466
467
        $id = $this->getDataSource()->insert($data);
468
469
        $data[$this->getIdentifierColumnName()] = $id;
470
        $this->getEventManager()->trigger(self::EVENT_GRID_INSERT_POST, $this, $data);
471
472
        return $id;
473
    }
474
475
    /**
476
     * @param $data
477
     * @param $primary
478
     * @return mixed
479
     */
480
    public function update($data, $primary)
481
    {
482
        $eventResult = $this->getEventManager()->trigger(self::EVENT_GRID_UPDATE_PRE, $this, $data)->last();
483
        if ($eventResult) {
484
            $data = $eventResult;
485
        }
486
487
        $this->getDataSource()->update($data, $primary);
488
        $data[$this->getIdentifierColumnName()] = $primary;
489
490
        $this->getEventManager()->trigger(self::EVENT_GRID_UPDATE_POST, $this, $data);
491
492
        return $primary;
493
    }
494
495
    /**
496
     * @param $id
497
     */
498
    public function delete($id)
499
    {
500
        $identifierColumnName = $this->getIdentifierColumnName();
501
502
        $this->getEventManager()->trigger(self::EVENT_GRID_DELETE_PRE, $this, [$identifierColumnName => $id]);
503
        $this->getDataSource()->delete($id);
504
        $this->getEventManager()->trigger(self::EVENT_GRID_DELETE_POST, $this, [$identifierColumnName => $id]);
505
    }
506
507
    // FILTERS
508
509
    /**
510
     * @param FilterInterface $filter
511
     * @param string|Column $column
512
     * @return $this
513
     */
514
    public function addFilter(FilterInterface $filter, $column)
515
    {
516
        if (!$column instanceof Column) {
517
            $column = $this->getColumn($column);
518
        }
519
520
        if (!$filter->getName()) {
521
            $filter->setName($column->getName());
522
        }
523
524
        if (!$filter->getLabel()) {
525
            $filter->setLabel($column->getLabel());
526
        }
527
528
        $this->filters[$filter->getName()] = $filter;
529
530
        return $this;
531
    }
532
533
    /**
534
     * @param $columnName
535
     * @return bool
536
     */
537
    public function hasFilter($columnName)
538
    {
539
        return array_key_exists($columnName, $this->filters);
540
    }
541
542
    /**
543
     * @param $columnName
544
     * @return null
545
     */
546
    public function getFilter($columnName)
547
    {
548
        if ($this->hasFilter($columnName)) {
549
            return $this->filters[$columnName];
550
        }
551
552
        return null;
553
    }
554
555
    /**
556
     * @return array
557
     */
558
    public function getFilters()
559
    {
560
        return $this->filters;
561
    }
562
563
    /**
564
     * @return bool
565
     */
566
    public function hasFilters()
567
    {
568
        return count($this->getFilters()) > 0;
569
    }
570
571
    /**
572
     * @param $values
573
     */
574
    public function setFiltersData($values)
575
    {
576
        /** @var FilterInterface $filter */
577
        foreach ($this->getFilters() as $filter) {
578
            $filter->setValue($values[$filter->getName()]);
579
        }
580
    }
581
582
    // PAGINATOR
583
584
    /**
585
     * @param $number
586
     * @return $this
587
     */
588
    public function setCurrentPage($number)
589
    {
590
        $this->currentPage = (int) $number;
591
        return $this;
592
    }
593
594
    /**
595
     * @return int
596
     */
597
    public function getCurrentPage()
598
    {
599
        return $this->currentPage;
600
    }
601
602
603
    /**
604
     * @param $count
605
     * @return $this
606
     */
607
    public function setItemsPerPage($count)
608
    {
609
        $this->itemsPerPage = (int) $count;
610
        return $this;
611
    }
612
613
    /**
614
     * @return int
615
     */
616
    public function getItemsPerPage()
617
    {
618
        return $this->itemsPerPage;
619
    }
620
621
    /**
622
     * @param $count
623
     * @return $this
624
     */
625
    public function setPageRange($count)
626
    {
627
        $this->pageRange = (int) $count;
628
        return $this;
629
    }
630
631
    // INTERFACES IMPLEMENTATION
632
633
    /**
634
     * @return mixed
635
     */
636
    public function current()
637
    {
638
        return current($this->columns);
639
    }
640
641
    /**
642
     * @return bool
643
     */
644
    public function valid()
645
    {
646
        return ($this->current() !== false);
647
    }
648
649
    /**
650
     * @return mixed
651
     */
652
    public function next()
653
    {
654
        return next($this->columns);
655
    }
656
657
    /**
658
     * @return mixed
659
     */
660
    public function key()
661
    {
662
        return key($this->columns);
663
    }
664
665
    /**
666
     * @return mixed
667
     */
668
    public function rewind()
669
    {
670
        return reset($this->columns);
671
    }
672
673
    /**
674
     * @return int
675
     */
676
    public function count()
677
    {
678
        return count($this->columns);
679
    }
680
681
    /**
682
     * @param mixed $offset
683
     * @return bool
684
     */
685
    public function offsetExists($offset)
686
    {
687
        return isset($this->columns[$offset]);
688
    }
689
690
    /**
691
     * @param mixed $offset
692
     * @return bool|mixed
693
     */
694
    public function offsetGet($offset)
695
    {
696
        if(isset($this->columns[$offset])) {
697
            return $this->columns[$offset];
698
        }
699
700
        return false;
701
    }
702
703
    /**
704
     * @param mixed $offset
705
     * @param mixed $column
706
     */
707
    public function offsetSet($offset, $column)
708
    {
709
        if ($offset !== null) {
710
            $this->columns[$offset] = $column;
711
        } else {
712
            $this->columns[] = $column;
713
        }
714
    }
715
716
    /**
717
     * @param mixed $offset
718
     */
719
    public function offsetUnset($offset)
720
    {
721
        if (isset($this->columns[$offset])) {
722
            unset($this->columns[$offset]);
723
        }
724
    }
725
726
    /**
727
     * Get an iterator for iterating over the elements in the collection.
728
     *
729
     * @return \ArrayIterator|\Traversable
730
     */
731
    public function getIterator()
732
    {
733
        return new \ArrayIterator($this->columns);
734
    }
735
}