Completed
Push — master ( 467d47...6f2bb4 )
by Anton
14s
created

ArraySource   A

Complexity

Total Complexity 27

Size/Duplication

Total Lines 139
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 92.75%

Importance

Changes 0
Metric Value
dl 0
loc 139
ccs 64
cts 69
cp 0.9275
c 0
b 0
f 0
rs 10
wmc 27
lcom 1
cbo 3

4 Methods

Rating   Name   Duplication   Size   Complexity  
A setSource() 0 7 3
A process() 0 19 1
C applyFilters() 0 53 17
B applyOrders() 0 29 6
1
<?php
2
/**
3
 * Bluz Framework Component
4
 *
5
 * @copyright Bluz PHP Team
6
 * @link      https://github.com/bluzphp/framework
7
 */
8
9
declare(strict_types=1);
10
11
namespace Bluz\Grid\Source;
12
13
use Bluz\Grid;
14
use Bluz\Grid\Data;
15
16
/**
17
 * Array Source Adapter for Grid package
18
 *
19
 * @package  Bluz\Grid
20
 * @author   Anton Shevchuk
21
 *
22
 * @method   array getSource()
23
 */
24
class ArraySource extends AbstractSource
25
{
26
    /**
27
     * Set array source
28
     *
29
     * @param  array $source
30
     *
31
     * @return void
32
     * @throws Grid\GridException
33
     */
34 33
    public function setSource($source) : void
35
    {
36 33
        if (!is_array($source) && !($source instanceof \ArrayAccess)) {
37 1
            throw new Grid\GridException('Source of `ArraySource` should be array or implement ArrayAccess interface');
38
        }
39 32
        parent::setSource($source);
40 32
    }
41
42
    /**
43
     * {@inheritdoc}
44
     */
45 13
    public function process(int $page, int $limit, array $filters = [], array $orders = []) : Data
46
    {
47
        // process filters
48 13
        $this->applyFilters($filters);
49
50
        // process orders
51 13
        $this->applyOrders($orders);
52
53 13
        $data = $this->getSource();
54
55 13
        $total = count($data);
56
57
        // process pages
58 13
        $data = array_slice($data, $limit * ($page - 1), $limit);
59
60 13
        $gridData = new Data($data);
61 13
        $gridData->setTotal($total);
62 13
        return $gridData;
63
    }
64
65
    /**
66
     * Apply filters to array
67
     *
68
     * @param  array $settings
69
     *
70
     * @return void
71
     */
72 13
    private function applyFilters(array $settings) : void
73
    {
74 13
        $data = $this->getSource();
75 13
        $data = array_filter(
76 13
            $data,
77 13
            function ($row) use ($settings) {
78 13
                foreach ($settings as $column => $filters) {
79 5
                    foreach ($filters as $filter => $value) {
80
                        // switch statement for filter
81
                        switch ($filter) {
82 5
                            case Grid\Grid::FILTER_EQ:
83 2
                                if ($row[$column] != $value) {
84 2
                                    return false;
85
                                }
86 2
                                break;
87 4
                            case Grid\Grid::FILTER_NE:
88 2
                                if ($row[$column] == $value) {
89 1
                                    return false;
90
                                }
91 2
                                break;
92 2
                            case Grid\Grid::FILTER_GT:
93 1
                                if ($row[$column] <= $value) {
94 1
                                    return false;
95
                                }
96 1
                                break;
97 2
                            case Grid\Grid::FILTER_GE:
98 1
                                if ($row[$column] < $value) {
99
                                    return false;
100
                                }
101 1
                                break;
102 2
                            case Grid\Grid::FILTER_LT:
103 1
                                if ($row[$column] >= $value) {
104 1
                                    return false;
105
                                }
106 1
                                break;
107 2
                            case Grid\Grid::FILTER_LE:
108 1
                                if ($row[$column] > $value) {
109
                                    return false;
110
                                }
111 1
                                break;
112 1
                            case Grid\Grid::FILTER_LIKE:
113 1
                                if (!preg_match('/' . $value . '/', $row[$column])) {
114 1
                                    return false;
115
                                }
116 5
                                break;
117
                        }
118
                    }
119
                }
120 13
                return true;
121 13
            }
122
        );
123 13
        $this->setSource($data);
124 13
    }
125
126
    /**
127
     * Apply order to array
128
     *
129
     * @param  array $settings
130
     *
131
     * @return void
132
     */
133 13
    private function applyOrders(array $settings) : void
134
    {
135 13
        $data = $this->getSource();
136
        // Create empty column stack
137 13
        $orders = [];
138 13
        foreach ($settings as $column => $order) {
139
            $orders[$column] = [];
140
        }
141
142
        // Obtain a list of columns
143 13
        foreach ($data as $key => $row) {
144 13
            foreach ($settings as $column => $order) {
145 13
                $orders[$column][$key] = $row[$column];
146
            }
147
        }
148
149
        // Prepare array of arguments
150 13
        $funcArgs = [];
151 13
        foreach ($settings as $column => $order) {
152
            $funcArgs[] = $orders[$column];
153
            $funcArgs[] = ($order === Grid\Grid::ORDER_ASC) ? SORT_ASC : SORT_DESC;
154
        }
155 13
        $funcArgs[] = &$data;
156
157
        // Sort the data with volume descending, edition ascending
158
        // Add $data as the last parameter, to sort by the common key
159 13
        array_multisort(...$funcArgs);
160 13
        $this->setSource($data);
161 13
    }
162
}
163