Completed
Push — master ( d292ba...467d47 )
by Anton
15s
created

ArraySource::applyOrders()   B

Complexity

Conditions 6
Paths 18

Size

Total Lines 28
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

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