Completed
Push — master ( 719ac8...779e62 )
by Stanislav
02:21 queued 41s
created

TableUtils::sortRowsByColumnNumber()   B

Complexity

Conditions 4
Paths 3

Size

Total Lines 25
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 25
rs 8.5806
c 0
b 0
f 0
cc 4
eloc 15
nc 3
nop 2
1
<?php
2
3
namespace Popstas\Transmission\Console\Helpers;
4
5
use Symfony\Component\Console\Helper\Table;
6
use Symfony\Component\Console\Helper\TableSeparator;
7
use Symfony\Component\Console\Output\OutputInterface;
8
9
class TableUtils
10
{
11
    public static function parseFilters(array $filters)
12
    {
13
        foreach ($filters as $columnKey => $filter) {
14
            if (is_array($filter) && !isset($filter['type'])) {
15
                throw new \InvalidArgumentException('Unknown filter type');
16
            }
17
            if (!isset($filter) || !isset($filter['value'])) {
18
                unset($filters[$columnKey]);
19
                continue;
20
            }
21
            $filters[$columnKey] = self::parseFilter($filter['type'], $filter['value']) + $filters[$columnKey];
22
        }
23
        return $filters;
24
    }
25
26
    private static function parseFilter($type, $filterString)
27
    {
28
        switch ($type) {
29
            case 'numeric':
30
                $filter = [];
31
                preg_match_all('/([<>=])\s?([\d\.]+)/', $filterString, $results, PREG_SET_ORDER);
32
                if ($results) {
33
                    foreach ($results as $result) {
34
                        $operator = $result[1];
35
                        $value = $result[2];
36
                        $operatorMap = [
37
                            '<' => 'max',
38
                            '>' => 'min',
39
                            '=' => 'equals',
40
                        ];
41
                        $filterCondition = $operatorMap[$operator];
42
                        $filter[$filterCondition] = $value;
43
                    }
44
                }
45
                return $filter;
46
47
            case 'regex':
48
                return ['regex' => str_replace(['/', '.', '*'], ['\/', '\.', '.*?'], $filterString)];
49
        }
50
        throw new \InvalidArgumentException('Unknown filter type');
51
    }
52
53
    /**
54
     * @param array $rows
55
     * @param array $filters
56
     * @return bool
57
     * @throws \RuntimeException
58
     */
59
    public static function filterRows(array $rows, array $filters)
60
    {
61
        $filters = self::parseFilters($filters);
62
63
        return array_filter($rows, function ($row) use ($filters) {
64
            foreach ($filters as $columnKey => $filter) {
65
                if (!isset($row[$columnKey])) {
66
                    throw new \RuntimeException('Column ' . $columnKey . ' not exists, cannot filter');
67
                }
68
                $columnValue = $row[$columnKey];
69
70
                if (!self::filterRow($columnValue, $filter)) {
71
                    return false;
72
                }
73
            }
74
            return true;
75
        });
76
    }
77
78
    private static function filterRow($value, $filter)
79
    {
80
        if ((isset($filter['min']) && $value <= $filter['min']) ||
81
            (isset($filter['max']) && $value >= $filter['max']) ||
82
            (isset($filter['equals']) && $value != $filter['equals']) ||
83
            (isset($filter['regex']) && !preg_match('/' . $filter['regex'] . '/i', $value))
84
        ) {
85
            return false;
86
        }
87
88
        return true;
89
    }
90
91
    public static function sortRowsByColumnNumber(array $rows, $columnNumber)
92
    {
93
        if (count($rows) == 0) {
94
            return $rows;
95
        }
96
        $rowsSorted = $rows;
97
        $columnsTotal = count(end($rows));
98
99
        $sortOrder = $columnNumber > 0 ? 1 : -1;
100
101
        $columnIndex = max(
102
            1,
103
            min(
104
                $columnsTotal,
105
                abs($columnNumber)
106
            )
107
        );
108
        $columnIndex--;
109
110
        usort($rowsSorted, function ($first, $second) use ($columnIndex, $sortOrder) {
111
            return $first[$columnIndex] > $second[$columnIndex] ? $sortOrder : $sortOrder * -1;
112
        });
113
114
        return $rowsSorted;
115
    }
116
117
    public static function limitRows(array $rows, $limit)
118
    {
119
        if ($limit && $limit < count($rows)) {
120
            $rows = array_slice($rows, 0, $limit);
121
        }
122
        return $rows;
123
    }
124
125
    public static function printTable(array $tableData, OutputInterface $output)
126
    {
127
        $table = new Table($output);
128
        $table->setHeaders($tableData['headers']);
129
        $table->setRows($tableData['rows']);
130
        $table->addRow(new TableSeparator());
131
        if (isset($tableData['totals'])) {
132
            $table->addRow($tableData['totals']);
133
        }
134
        $table->render();
135
    }
136
}
137