Completed
Push — master ( 26e409...a6375b )
by Anton
06:02 queued 03:57
created

ArraySource::applyOrders()   B

Complexity

Conditions 6
Paths 18

Size

Total Lines 29

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 6

Importance

Changes 0
Metric Value
cc 6
nc 18
nop 1
dl 0
loc 29
ccs 16
cts 16
cp 1
crap 6
rs 8.8337
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
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 31
    public function setSource($source): void
35
    {
36 31
        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 30
        parent::setSource($source);
40 30
    }
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
     * @throws Grid\GridException
72
     */
73 13
    private function applyFilters(array $settings): void
74
    {
75 13
        $data = $this->getSource();
76 13
        $data = array_filter(
77 13
            $data,
78
            function ($row) use ($settings) {
79 13
                foreach ($settings as $column => $filters) {
80 5
                    foreach ($filters as $filter => $value) {
81
                        // switch statement for filter
82 5
                        switch ($filter) {
83
                            case Grid\Grid::FILTER_EQ:
84 2
                                if ($row[$column] != $value) {
85 2
                                    return false;
86
                                }
87 2
                                break;
88
                            case Grid\Grid::FILTER_NE:
89 2
                                if ($row[$column] == $value) {
90 1
                                    return false;
91
                                }
92 2
                                break;
93
                            case Grid\Grid::FILTER_GT:
94 1
                                if ($row[$column] <= $value) {
95 1
                                    return false;
96
                                }
97 1
                                break;
98
                            case Grid\Grid::FILTER_GE:
99 1
                                if ($row[$column] < $value) {
100
                                    return false;
101
                                }
102 1
                                break;
103
                            case Grid\Grid::FILTER_LT:
104 1
                                if ($row[$column] >= $value) {
105 1
                                    return false;
106
                                }
107 1
                                break;
108
                            case Grid\Grid::FILTER_LE:
109 1
                                if ($row[$column] > $value) {
110
                                    return false;
111
                                }
112 1
                                break;
113
                            case Grid\Grid::FILTER_LIKE:
114 1
                                if (!preg_match('/' . $value . '/', $row[$column])) {
115 1
                                    return false;
116
                                }
117 5
                                break;
118
                        }
119
                    }
120
                }
121 13
                return true;
122 13
            }
123
        );
124 13
        $this->setSource($data);
125 13
    }
126
127
    /**
128
     * Apply order to array
129
     *
130
     * @param  array $settings
131
     *
132
     * @return void
133
     * @throws Grid\GridException
134
     */
135 13
    private function applyOrders(array $settings): void
136
    {
137 13
        $data = $this->getSource();
138
        // Create empty column stack
139 13
        $orders = [];
140 13
        foreach ($settings as $column => $order) {
141 1
            $orders[$column] = [];
142
        }
143
144
        // Obtain a list of columns
145 13
        foreach ($data as $key => $row) {
146 13
            foreach ($settings as $column => $order) {
147 13
                $orders[$column][$key] = $row[$column];
148
            }
149
        }
150
151
        // Prepare array of arguments
152 13
        $funcArgs = [];
153 13
        foreach ($settings as $column => $order) {
154 1
            $funcArgs[] = $orders[$column];
155 1
            $funcArgs[] = ($order === Grid\Grid::ORDER_ASC) ? SORT_ASC : SORT_DESC;
156
        }
157 13
        $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 13
        array_multisort(...$funcArgs);
162 13
        $this->setSource($data);
163 13
    }
164
}
165