Completed
Push — master ( 4db62f...070a1e )
by Anton
10s
created

ArraySource::process()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 23
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 3.0067

Importance

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