|
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
|
|
|
|
|
16
|
|
|
/** |
|
17
|
|
|
* Dibi Fluent data source. |
|
18
|
|
|
* |
|
19
|
|
|
* @package Grido |
|
20
|
|
|
* @subpackage DataSources |
|
21
|
|
|
* @author Petr Bugyík |
|
22
|
|
|
* |
|
23
|
|
|
* @property-read \DibiFluent $fluent |
|
24
|
|
|
* @property-read int $limit |
|
25
|
|
|
* @property-read int $offset |
|
26
|
|
|
* @property-read int $count |
|
27
|
|
|
* @property-read array $data |
|
28
|
|
|
*/ |
|
29
|
1 |
|
class DibiFluent extends \Nette\Object implements IDataSource |
|
30
|
|
|
{ |
|
31
|
|
|
/** @var \DibiFluent */ |
|
32
|
|
|
protected $fluent; |
|
33
|
|
|
|
|
34
|
|
|
/** @var int */ |
|
35
|
|
|
protected $limit; |
|
36
|
|
|
|
|
37
|
|
|
/** @var int */ |
|
38
|
|
|
protected $offset; |
|
39
|
|
|
|
|
40
|
|
|
/** |
|
41
|
|
|
* @param \DibiFluent $fluent |
|
42
|
|
|
*/ |
|
43
|
|
|
public function __construct(\DibiFluent $fluent) |
|
44
|
|
|
{ |
|
45
|
1 |
|
$this->fluent = $fluent; |
|
46
|
1 |
|
} |
|
47
|
|
|
|
|
48
|
|
|
/** |
|
49
|
|
|
* @return \DibiFluent |
|
50
|
|
|
*/ |
|
51
|
|
|
public function getFluent() |
|
52
|
|
|
{ |
|
53
|
|
|
return $this->fluent; |
|
54
|
|
|
} |
|
55
|
|
|
|
|
56
|
|
|
/** |
|
57
|
|
|
* @return int |
|
58
|
|
|
*/ |
|
59
|
|
|
public function getLimit() |
|
60
|
|
|
{ |
|
61
|
|
|
return $this->limit; |
|
62
|
|
|
} |
|
63
|
|
|
|
|
64
|
|
|
/** |
|
65
|
|
|
* @return int |
|
66
|
|
|
*/ |
|
67
|
1 |
|
public function getOffset() |
|
68
|
|
|
{ |
|
69
|
|
|
return $this->offset; |
|
70
|
|
|
} |
|
71
|
|
|
|
|
72
|
|
|
/** |
|
73
|
|
|
* @param \Grido\Components\Filters\Condition $condition |
|
74
|
|
|
* @param \DibiFluent $fluent |
|
75
|
|
|
*/ |
|
76
|
|
|
protected function makeWhere(\Grido\Components\Filters\Condition $condition, \DibiFluent $fluent = NULL) |
|
77
|
|
|
{ |
|
78
|
|
|
$fluent = $fluent === NULL |
|
79
|
1 |
|
? $this->fluent |
|
80
|
1 |
|
: $fluent; |
|
81
|
|
|
|
|
82
|
1 |
|
if ($condition->callback) { |
|
83
|
1 |
|
call_user_func_array($condition->callback, [$condition->value, $fluent]); |
|
84
|
1 |
|
} else { |
|
85
|
1 |
|
call_user_func_array([$fluent, 'where'], $condition->__toArray('[', ']')); |
|
86
|
|
|
} |
|
87
|
1 |
|
} |
|
88
|
|
|
|
|
89
|
|
|
/********************************** inline editation helpers ************************************/ |
|
90
|
|
|
|
|
91
|
|
|
/** |
|
92
|
|
|
* Default callback used when an editable column has customRender. |
|
93
|
|
|
* @param mixed $id |
|
94
|
|
|
* @param string $idCol |
|
95
|
|
|
* @return \DibiRow |
|
96
|
|
|
*/ |
|
97
|
|
|
public function getRow($id, $idCol) |
|
98
|
|
|
{ |
|
99
|
|
|
$fluent = clone $this->fluent; |
|
100
|
|
|
return $fluent |
|
101
|
|
|
->where("%n = %s", $idCol, $id) |
|
|
|
|
|
|
102
|
|
|
->fetch(); |
|
103
|
|
|
} |
|
104
|
|
|
|
|
105
|
|
|
/*********************************** interface IDataSource ************************************/ |
|
106
|
|
|
|
|
107
|
|
|
/** |
|
108
|
|
|
* @return int |
|
109
|
|
|
*/ |
|
110
|
|
|
public function getCount() |
|
111
|
|
|
{ |
|
112
|
1 |
|
$fluent = clone $this->fluent; |
|
113
|
1 |
|
return $fluent->count(); |
|
114
|
|
|
} |
|
115
|
|
|
|
|
116
|
|
|
/** |
|
117
|
|
|
* @return array |
|
118
|
|
|
*/ |
|
119
|
|
|
public function getData() |
|
120
|
|
|
{ |
|
121
|
1 |
|
return $this->fluent->fetchAll($this->offset, $this->limit); |
|
122
|
|
|
} |
|
123
|
|
|
|
|
124
|
|
|
/** |
|
125
|
|
|
* @param array $conditions |
|
126
|
|
|
*/ |
|
127
|
|
|
public function filter(array $conditions) |
|
128
|
|
|
{ |
|
129
|
1 |
|
foreach ($conditions as $condition) { |
|
130
|
1 |
|
$this->makeWhere($condition); |
|
131
|
1 |
|
} |
|
132
|
1 |
|
} |
|
133
|
|
|
|
|
134
|
|
|
/** |
|
135
|
|
|
* @param int $offset |
|
136
|
|
|
* @param int $limit |
|
137
|
|
|
*/ |
|
138
|
|
|
public function limit($offset, $limit) |
|
139
|
|
|
{ |
|
140
|
1 |
|
$this->offset = $offset; |
|
141
|
1 |
|
$this->limit = $limit; |
|
142
|
1 |
|
} |
|
143
|
|
|
|
|
144
|
|
|
/** |
|
145
|
|
|
* @param array $sorting |
|
146
|
|
|
*/ |
|
147
|
|
|
public function sort(array $sorting) |
|
148
|
|
|
{ |
|
149
|
1 |
|
foreach ($sorting as $column => $sort) { |
|
150
|
1 |
|
$this->fluent->orderBy("%n", $column, $sort); |
|
|
|
|
|
|
151
|
1 |
|
} |
|
152
|
1 |
|
} |
|
153
|
|
|
|
|
154
|
|
|
/** |
|
155
|
|
|
* @param mixed $column |
|
156
|
|
|
* @param array $conditions |
|
157
|
|
|
* @param int $limit |
|
158
|
|
|
* @return array |
|
159
|
|
|
* @throws Exception |
|
160
|
|
|
*/ |
|
161
|
|
|
public function suggest($column, array $conditions, $limit) |
|
162
|
|
|
{ |
|
163
|
1 |
|
$fluent = clone $this->fluent; |
|
164
|
1 |
|
if (is_string($column)) { |
|
165
|
1 |
|
$fluent->removeClause('SELECT')->select("DISTINCT %n", $column)->orderBy("%n", $column, 'ASC'); |
|
|
|
|
|
|
166
|
1 |
|
} |
|
167
|
|
|
|
|
168
|
1 |
|
foreach ($conditions as $condition) { |
|
169
|
1 |
|
$this->makeWhere($condition, $fluent); |
|
170
|
1 |
|
} |
|
171
|
|
|
|
|
172
|
1 |
|
$items = []; |
|
173
|
1 |
|
$data = $fluent->fetchAll(0, $limit); |
|
174
|
1 |
|
foreach ($data as $row) { |
|
175
|
1 |
|
if (is_string($column)) { |
|
176
|
1 |
|
$value = (string) $row[$column]; |
|
177
|
1 |
|
} elseif (is_callable($column)) { |
|
178
|
|
|
$value = (string) $column($row); |
|
179
|
|
|
} else { |
|
180
|
|
|
$type = gettype($column); |
|
181
|
|
|
throw new Exception("Column of suggestion must be string or callback, $type given."); |
|
182
|
|
|
} |
|
183
|
|
|
|
|
184
|
1 |
|
$items[$value] = \Latte\Runtime\Filters::escapeHtml($value); |
|
185
|
1 |
|
} |
|
186
|
|
|
|
|
187
|
1 |
|
is_callable($column) && sort($items); |
|
188
|
1 |
|
return array_values($items); |
|
189
|
|
|
} |
|
190
|
|
|
} |
|
191
|
|
|
|
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.
In this case you can add the
@ignorePhpDoc annotation to the duplicate definition and it will be ignored.