Completed
Push — master ( 83cea8...e47c19 )
by Anton
17s queued 12s
created

SelectSource::process()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 45
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 21
CRAP Score 2.0078

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 23
c 1
b 0
f 0
nc 2
nop 4
dl 0
loc 45
ccs 21
cts 24
cp 0.875
crap 2.0078
rs 9.552
1
<?php
2
3
/**
4
 * Bluz Framework Component
5
 *
6
 * @copyright Bluz PHP Team
7
 * @link      https://github.com/bluzphp/framework
8
 */
9
10
declare(strict_types=1);
11
12
namespace Bluz\Grid\Source;
13
14
use Bluz\Db;
15
use Bluz\Grid;
16
use Bluz\Grid\Data;
17
use Bluz\Proxy;
18
19
/**
20
 * SQL Source Adapter for Grid package
21
 *
22
 * @package  Bluz\Grid
23
 * @author   Anton Shevchuk
24
 *
25
 * @method   Db\Query\Select getSource()
26
 */
27
class SelectSource extends AbstractSource
28
{
29
    /**
30
     * Set Select source
31
     *
32
     * @param  Db\Query\Select $source
33
     *
34
     * @throws Grid\GridException
35
     * @return void
36
     */
37 2
    public function setSource($source): void
38
    {
39 2
        if (!$source instanceof Db\Query\Select) {
0 ignored issues
show
introduced by
$source is always a sub-type of Bluz\Db\Query\Select.
Loading history...
40 1
            throw new Grid\GridException('Source of `SelectSource` should be `Db\\Query\\Select` object');
41
        }
42 1
        parent::setSource($source);
43 1
    }
44
45
    /**
46
     * {@inheritdoc}
47
     *
48
     * @throws Grid\GridException
49
     * @throws Db\Exception\DbException
50
     */
51 1
    public function process(int $page, int $limit, array $filters = [], array $orders = []): Data
52
    {
53
        // process filters
54 1
        $this->applyFilters($filters);
55
56
        // process orders
57 1
        $this->applyOrders($orders);
58
59
        // process pages
60 1
        $this->getSource()->setLimit($limit);
61 1
        $this->getSource()->setPage($page);
62
63
        // prepare query
64 1
        $type = Proxy\Db::getOption('connect', 'type');
65
66 1
        if (strtolower($type) === 'mysql') {
67
            // MySQL
68 1
            $selectPart = $this->getSource()->getSelect();
69 1
            $selectPart[0] = 'SQL_CALC_FOUND_ROWS ' . $selectPart[0];
0 ignored issues
show
Bug introduced by
Are you sure $selectPart[0] of type array can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

69
            $selectPart[0] = 'SQL_CALC_FOUND_ROWS ' . /** @scrutinizer ignore-type */ $selectPart[0];
Loading history...
70 1
            $this->getSource()->select(...$selectPart);
0 ignored issues
show
Bug introduced by
$selectPart of type array is incompatible with the type string expected by parameter $select of Bluz\Db\Query\Select::select(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

70
            $this->getSource()->select(/** @scrutinizer ignore-type */ ...$selectPart);
Loading history...
71
72 1
            $totalSql = 'SELECT FOUND_ROWS()';
73
        } else {
74
            // other
75
            $totalSource = clone $this->getSource();
76
            $totalSource->select('COUNT(*)');
77
78
            $totalSql = $totalSource->getSql();
79
        }
80
81 1
        $data = [];
82 1
        $total = 0;
83
84
        // run queries
85
        // use transaction to avoid errors
86 1
        Proxy\Db::transaction(
87 1
            function () use (&$data, &$total, $totalSql) {
88 1
                $data = $this->source->execute();
89 1
                $total = (int)Proxy\Db::fetchOne($totalSql);
90 1
            }
91
        );
92
93 1
        $gridData = new Data($data);
94 1
        $gridData->setTotal($total);
95 1
        return $gridData;
96
    }
97
98
    /**
99
     * Apply filters to Select
100
     *
101
     * @param  array $settings
102
     *
103
     * @return void
104
     * @throws Grid\GridException
105
     */
106 1
    private function applyFilters(array $settings): void
107
    {
108 1
        foreach ($settings as $column => $filters) {
109 1
            foreach ($filters as $filter => $value) {
110 1
                if ($filter === Grid\Grid::FILTER_LIKE) {
111 1
                    $value = '%' . $value . '%';
112
                }
113 1
                $this->getSource()->andWhere($column . ' ' . $this->filters[$filter] . ' ?', $value);
114
            }
115
        }
116 1
    }
117
118
    /**
119
     * Apply order to Select
120
     *
121
     * @param  array $settings
122
     *
123
     * @return void
124
     * @throws Grid\GridException
125
     */
126 1
    private function applyOrders(array $settings): void
127
    {
128
        // Obtain a list of columns
129 1
        foreach ($settings as $column => $order) {
130 1
            $this->getSource()->addOrderBy($column, $order);
131
        }
132 1
    }
133
}
134