Completed
Pull Request — master (#363)
by Anton
05:32
created

SqlSource::setSource()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 1
dl 0
loc 9
ccs 5
cts 5
cp 1
crap 2
rs 9.6666
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
/**
10
 * @namespace
11
 */
12
namespace Bluz\Grid\Source;
13
14
use Bluz\Db;
15
use Bluz\Grid;
16
use Bluz\Proxy;
17
18
/**
19
 * SQL Source Adapter for Grid package
20
 *
21
 * @package  Bluz\Grid
22
 * @author   Anton Shevchuk
23
 */
24
class SqlSource extends AbstractSource
25
{
26
    /**
27
     * @var string SQL
28
     */
29
    protected $source;
30
31
    /**
32
     * Set SQL source
33
     *
34
     * @param  string $source
35
     * @return self
36
     * @throws \Bluz\Grid\GridException
37
     */
38 2
    public function setSource($source)
39
    {
40 2
        if (!is_string($source)) {
41 1
            throw new Grid\GridException("Source of `SqlSource` should be string with SQL query");
42
        }
43 1
        $this->source = $source;
44
45 1
        return $this;
46
    }
47
48
    /**
49
     * Process
50
     *
51
     * @param  array $settings
52
     * @return \Bluz\Grid\Data
53
     */
54 1
    public function process(array $settings = [])
55
    {
56
        // process filters
57 1
        $where = [];
58 1
        if (!empty($settings['filters'])) {
59 1
            foreach ($settings['filters'] as $column => $filters) {
60 1
                foreach ($filters as $filter => $value) {
61 1
                    if ($filter == Grid\Grid::FILTER_LIKE) {
62 1
                        $value = '%'.$value.'%';
63
                    }
64 1
                    $where[] = $column .' '.
65 1
                        $this->filters[$filter].' '.
66 1
                        Proxy\Db::quote($value);
67
                }
68
            }
69
        }
70
71
        // process orders
72 1
        $orders = [];
73 1
        if (!empty($settings['orders'])) {
74
            // Obtain a list of columns
75 1
            foreach ($settings['orders'] as $column => $order) {
76 1
                $column = Proxy\Db::quoteIdentifier($column);
77 1
                $orders[] = $column . ' ' . $order;
78
            }
79
        }
80
81
        // process pages
82 1
        $limit = ' LIMIT ' . ($settings['page'] - 1) * $settings['limit'] . ', ' . $settings['limit'];
83
84
        // prepare query
85 1
        $type = Proxy\Db::getOption('connect', 'type');
86
87 1
        if (strtolower($type) == 'mysql') {
88
            // MySQL
89 1
            $dataSql = preg_replace('/SELECT\s(.*?)\sFROM/is', 'SELECT SQL_CALC_FOUND_ROWS $1 FROM', $this->source, 1);
90 1
            $totalSql = 'SELECT FOUND_ROWS()';
91
        } else {
92
            // other
93
            $dataSql = $this->source;
94
            $totalSql = preg_replace('/SELECT\s(.*?)\sFROM/is', 'SELECT COUNT(*) FROM', $this->source, 1);
95
            if (sizeof($where)) {
96
                $totalSql .= ' WHERE ' . (join(' AND ', $where));
97
            }
98
        }
99
100 1
        if (sizeof($where)) {
101 1
            $dataSql .= ' WHERE ' . (join(' AND ', $where));
102
        }
103 1
        if (sizeof($orders)) {
104 1
            $dataSql .= ' ORDER BY ' . (join(', ', $orders));
105
        }
106 1
        $dataSql .= $limit;
107
108
        // run queries
109
        // use transaction to avoid errors
110 1
        Proxy\Db::transaction(function () use (&$data, &$total, $dataSql, $totalSql) {
111 1
            $data = Proxy\Db::fetchAll($dataSql);
112 1
            $total = Proxy\Db::fetchOne($totalSql);
113 1
        });
114
        
115 1
        $gridData = new Grid\Data($data);
116 1
        $gridData->setTotal($total);
117 1
        return $gridData;
118
119
    }
120
}
121