Completed
Push — master ( f4415a...651f7b )
by Anton
12s
created

SelectSource   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 104
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 89.74%

Importance

Changes 0
Metric Value
dl 0
loc 104
ccs 35
cts 39
cp 0.8974
rs 10
c 0
b 0
f 0
wmc 10
lcom 1
cbo 5

4 Methods

Rating   Name   Duplication   Size   Complexity  
A setSource() 0 7 2
A process() 0 46 2
A applyFilters() 0 11 4
A applyOrders() 0 7 2
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\Db;
14
use Bluz\Grid;
15
use Bluz\Grid\Data;
16
use Bluz\Proxy;
17
18
/**
19
 * SQL Source Adapter for Grid package
20
 *
21
 * @package  Bluz\Grid
22
 * @author   Anton Shevchuk
23
 *
24
 * @method   Db\Query\Select getSource()
25
 */
26
class SelectSource extends AbstractSource
27
{
28
    /**
29
     * Set Select source
30
     *
31
     * @param  Db\Query\Select $source
32
     *
33
     * @throws Grid\GridException
34
     * @return void
35
     */
36 2
    public function setSource($source) : void
37
    {
38 2
        if (!$source instanceof Db\Query\Select) {
39 1
            throw new Grid\GridException('Source of `SelectSource` should be `Db\\Query\\Select` object');
40
        }
41 1
        parent::setSource($source);
42 1
    }
43
44
    /**
45
     * {@inheritdoc}
46
     */
47 1
    public function process(int $page, int $limit, array $filters = [], array $orders = []) : Data
48
    {
49
        // process filters
50 1
        $this->applyFilters($filters);
51
52
        // process orders
53 1
        $this->applyOrders($orders);
54
55
        // process pages
56 1
        $this->getSource()->setLimit($limit);
57 1
        $this->getSource()->setPage($page);
58
59
        // prepare query
60 1
        $type = Proxy\Db::getOption('connect', 'type');
61
62 1
        if (strtolower($type) === 'mysql') {
63
            // MySQL
64 1
            $selectPart = $this->getSource()->getSelect();
65 1
            $selectPart[0] = 'SQL_CALC_FOUND_ROWS ' . $selectPart[0];
66 1
            $this->getSource()->select(...$selectPart);
67
68 1
            $totalSql = 'SELECT FOUND_ROWS()';
69
        } else {
70
            // other
71
            $totalSource = clone $this->getSource();
72
            $totalSource->select('COUNT(*)');
73
74
            $totalSql = $totalSource->getSql();
75
        }
76
77 1
        $data = [];
78 1
        $total = 0;
79
80
        // run queries
81
        // use transaction to avoid errors
82 1
        Proxy\Db::transaction(
83
            function () use (&$data, &$total, $totalSql) {
84 1
                $data = $this->source->execute();
85 1
                $total = (int)Proxy\Db::fetchOne($totalSql);
86 1
            }
87
        );
88
89 1
        $gridData = new Data($data);
90 1
        $gridData->setTotal($total);
91 1
        return $gridData;
92
    }
93
94
    /**
95
     * Apply filters to Select
96
     *
97
     * @param  array $settings
98
     *
99
     * @return void
100
     * @throws Grid\GridException
101
     */
102 1
    private function applyFilters(array $settings) : void
103
    {
104 1
        foreach ($settings as $column => $filters) {
105 1
            foreach ($filters as $filter => $value) {
106 1
                if ($filter === Grid\Grid::FILTER_LIKE) {
107 1
                    $value = '%' . $value . '%';
108
                }
109 1
                $this->getSource()->andWhere($column . ' ' . $this->filters[$filter] . ' ?', $value);
110
            }
111
        }
112 1
    }
113
114
    /**
115
     * Apply order to Select
116
     *
117
     * @param  array $settings
118
     *
119
     * @return void
120
     * @throws Grid\GridException
121
     */
122 1
    private function applyOrders(array $settings) : void
123
    {
124
        // Obtain a list of columns
125 1
        foreach ($settings as $column => $order) {
126
            $this->getSource()->addOrderBy($column, $order);
127
        }
128 1
    }
129
}
130