Completed
Pull Request — master (#240)
by Tomáš
06:38
created

NetteDatabase   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 149
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 41.67%

Importance

Changes 7
Bugs 0 Features 1
Metric Value
wmc 21
c 7
b 0
f 1
lcom 1
cbo 5
dl 0
loc 149
ccs 20
cts 48
cp 0.4167
rs 10

11 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A getCount() 0 4 1
A getData() 0 4 1
A limit() 0 4 1
A getRow() 0 6 1
A filter() 0 6 2
A sort() 0 6 2
A makeWhere() 0 12 3
C suggest() 0 27 7
A getSelection() 0 4 1
A update() 0 6 1
1
<?php
2
3
/**
4
 * This file is part of the Grido (http://grido.bugyik.cz)
5
 *
6
 * Copyright (c) 2011 Petr Bugyík (http://petr.bugyik.cz)
7
 *
8
 * For the full copyright and license information, please view
9
 * the file LICENSE.md that was distributed with this source code.
10
 */
11
12
namespace Grido\DataSources;
13
14
use Grido\Exception;
15
use Grido\Components\Filters\Condition;
16
17
/**
18
 * Nette Database data source.
19
 *
20
 * @package     Grido
21
 * @subpackage  DataSources
22
 * @author      Petr Bugyík
23
 *
24
 * @property-read \Nette\Database\Table\Selection $selection
25
 * @property-read int $count
26
 * @property-read array $data
27
 */
28 1
class NetteDatabase extends \Nette\Object implements IDataSource
29
{
30
    /** @var \Nette\Database\Table\Selection */
31
    protected $selection;
32
33
    /**
34
     * @param \Nette\Database\Table\Selection $selection
35
     */
36
    public function __construct(\Nette\Database\Table\Selection $selection)
37
    {
38 1
        $this->selection = $selection;
39 1
    }
40
41
    /**
42
     * @return \Nette\Database\Table\Selection
43
     */
44
    public function getSelection()
45
    {
46
        return $this->selection;
47
    }
48
49
    /**
50
     * @param Condition $condition
51
     * @param \Nette\Database\Table\Selection $selection
52
     */
53
    protected function makeWhere(Condition $condition, \Nette\Database\Table\Selection $selection = NULL)
54
    {
55
        $selection = $selection === NULL
56 1
            ? $this->selection
57 1
            : $selection;
58
59 1
        if ($condition->callback) {
60
            call_user_func_array($condition->callback, [$condition->value, $selection]);
61
        } else {
62 1
            call_user_func_array([$selection, 'where'], $condition->__toArray());
63
        }
64 1
    }
65
66
    /********************************** inline editation helpers ************************************/
67
68
    /**
69
     * Default callback for an inline editation save.
70
     * @param mixed $id
71
     * @param array $values
72
     * @param string $idCol
73
     * @return bool
74
     */
75
    public function update($id, array $values, $idCol)
76
    {
77
        return (bool) $this->getSelection()
78
            ->where('?name = ?', $idCol, $id)
79
            ->update($values);
80
    }
81
82
    /**
83
     * Default callback used when an editable column has customRender.
84
     * @param mixed $id
85
     * @param string $idCol
86
     * @return \Nette\Database\Table\ActiveRow|bool
87
     */
88
    public function getRow($id, $idCol)
89
    {
90
        return $this->getSelection()
91
            ->where('?name = ?', $idCol, $id)
92
            ->fetch();
93
    }
94
95
    /********************************** interface IDataSource ************************************/
96
97
    /**
98
     * @return int
99
     */
100
    public function getCount()
101
    {
102 1
        return (int) $this->selection->count('*');
103
    }
104
105
    /**
106
     * @return array
107
     */
108
    public function getData()
109
    {
110 1
        return $this->selection;
111
    }
112
113
    /**
114
     * @param array $conditions
115
     */
116
    public function filter(array $conditions)
117
    {
118 1
        foreach ($conditions as $condition) {
119 1
            $this->makeWhere($condition);
120 1
        }
121 1
    }
122
123
    /**
124
     * @param int $offset
125
     * @param int $limit
126
     */
127
    public function limit($offset, $limit)
128
    {
129 1
        $this->selection->limit($limit, $offset);
130 1
    }
131
132
    /**
133
     * @param array $sorting
134
     */
135
    public function sort(array $sorting)
136
    {
137 1
        foreach ($sorting as $column => $sort) {
138 1
            $this->selection->order("$column $sort");
139 1
        }
140 1
    }
141
142
    /**
143
     * @param mixed $column
144
     * @param array $conditions
145
     * @param int $limit
146
     * @return array
147
     * @throws Exception
148
     */
149
    public function suggest($column, array $conditions, $limit)
150
    {
151
        $selection = clone $this->selection;
152
        is_string($column) && $selection->select("DISTINCT $column")->order($column);
153
        $selection->limit($limit);
154
155
        foreach ($conditions as $condition) {
156
            $this->makeWhere($condition, $selection);
157
        }
158
159
        $items = [];
160
        foreach ($selection as $row) {
161
            if (is_string($column)) {
162
                $value = (string) $row[$column];
163
            } elseif (is_callable($column)) {
164
                $value = (string) $column($row);
165
            } else {
166
                $type = gettype($column);
167
                throw new Exception("Column of suggestion must be string or callback, $type given.");
168
            }
169
170
            $items[$value] = \Latte\Runtime\Filters::escapeHtml($value);
171
        }
172
173
        is_callable($column) && sort($items);
174
        return array_values($items);
175
    }
176
}
177