Completed
Push — master ( 6e7f58...9ff4ca )
by Stanislav
02:23
created

TableUtils::limitRows()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 7
rs 9.4285
cc 3
eloc 4
nc 2
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
        $rowsSorted = $rows;
94
        $columnsTotal = count(end($rows));
95
96
        $sortOrder = $columnNumber > 0 ? 1 : -1;
97
98
        $columnIndex = max(1, min(
99
            $columnsTotal,
100
            abs($columnNumber)
101
        )) - 1;
102
103
        usort($rowsSorted, function ($first, $second) use ($columnIndex, $sortOrder) {
104
            return $first[$columnIndex] > $second[$columnIndex] ? $sortOrder : $sortOrder * -1;
105
        });
106
107
        return $rowsSorted;
108
    }
109
110
    public static function limitRows(array $rows, $limit)
111
    {
112
        if ($limit && $limit < count($rows)) {
113
            $rows = array_slice($rows, 0, $limit);
114
        }
115
        return $rows;
116
    }
117
118
    public static function printTable(array $tableData, OutputInterface $output)
119
    {
120
        $table = new Table($output);
121
        $table->setHeaders($tableData['headers']);
122
        $table->setRows($tableData['rows']);
123
        $table->addRow(new TableSeparator());
124
        if (isset($tableData['totals'])) {
125
            $table->addRow($tableData['totals']);
126
        }
127
        $table->render();
128
    }
129
}
130