Completed
Pull Request — master (#375)
by Dalibor
05:23
created

DibiFluentDataSource::addAggregationColumn()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 2
1
<?php
2
3
/**
4
 * @copyright   Copyright (c) 2015 ublaboo <[email protected]>
5
 * @author      Pavel Janda <[email protected]>
6
 * @package     Ublaboo
7
 */
8
9
namespace Ublaboo\DataGrid\DataSource;
10
11
use DibiFluent;
12
use Nette\Utils\Callback;
13
use Nette\Utils\Strings;
14
use Ublaboo\DataGrid\Filter;
15
use Ublaboo\DataGrid\Utils\Sorting;
16
use Dibi;
17
18
class DibiFluentDataSource extends FilterableDataSource implements IDataSource
19
{
20
21
	/**
22
	 * @var DibiFluent
23
	 */
24
	protected $data_source;
25
26
	/**
27
	 * @var DibiFluent
28
	 */
29
	protected $aggregation_data_source;
30
31
	/**
32
	 * @var array
33
	 */
34
	protected $data = [];
35
36
	/**
37
	 * @var string
38
	 */
39
	protected $primary_key;
40
41
42
	/**
43
	 * @param DibiFluent $data_source
44
	 * @param string $primary_key
45
	 */
46
	public function __construct(\Dibi\Fluent $data_source, $primary_key)
47
	{
48
		$this->data_source = $data_source;
0 ignored issues
show
Documentation Bug introduced by
It seems like $data_source of type object<Dibi\Fluent> is incompatible with the declared type object<DibiFluent> of property $data_source.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
49
		$this->aggregation_data_source = $data_source->getConnection();
0 ignored issues
show
Documentation Bug introduced by
It seems like $data_source->getConnection() of type object<Dibi\Connection> is incompatible with the declared type object<DibiFluent> of property $aggregation_data_source.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
50
		$this->primary_key = $primary_key;
51
	}
52
53
54
	/********************************************************************************
55
	 *                          IDataSource implementation                          *
56
	 ********************************************************************************/
57
58
59
	/**
60
	 * Get count of data
61
	 * @return int
62
	 */
63
	public function getCount()
64
	{
65
		return $this->data_source->count();
66
	}
67
68
69
	/**
70
	 * Get the data
71
	 * @return array
72
	 */
73
	public function getData()
74
	{
75
		return $this->data ?: $this->data_source->fetchAll();
76
	}
77
78
79
	/**
80
	 * Filter data - get one row
81
	 * @param array $condition
82
	 * @return static
83
	 */
84
	public function filterOne(array $condition)
85
	{
86
		$this->data_source->where($condition)->limit(1);
87
88
		return $this;
89
	}
90
91
92
	/**
93
	 * Filter by date
94
	 * @param  Filter\FilterDate $filter
95
	 * @return void
96
	 */
97 View Code Duplication
	public function applyFilterDate(Filter\FilterDate $filter)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
98
	{
99
		$conditions = $filter->getCondition();
100
101
		$date = \DateTime::createFromFormat($filter->getPhpFormat(), $conditions[$filter->getColumn()]);
102
103
		$this->data_source->where('DATE(%n) = ?', $filter->getColumn(), $date->format('Y-m-d'));
104
	}
105
106
107
	/**
108
	 * Filter by date range
109
	 * @param  Filter\FilterDateRange $filter
110
	 * @return void
111
	 */
112 View Code Duplication
	public function applyFilterDateRange(Filter\FilterDateRange $filter)
113
	{
114
		$conditions = $filter->getCondition();
115
116
		$value_from = $conditions[$filter->getColumn()]['from'];
117
		$value_to   = $conditions[$filter->getColumn()]['to'];
118
119
		if ($value_from) {
120
			$date_from = \DateTime::createFromFormat($filter->getPhpFormat(), $value_from);
121
			$date_from->setTime(0, 0, 0);
122
123
			$this->data_source->where('DATE(%n) >= ?', $filter->getColumn(), $date_from);
124
		}
125
126
		if ($value_to) {
127
			$date_to = \DateTime::createFromFormat($filter->getPhpFormat(), $value_to);
128
			$date_to->setTime(23, 59, 59);
129
130
			$this->data_source->where('DATE(%n) <= ?', $filter->getColumn(), $date_to);
131
		}
132
	}
133
134
135
	/**
136
	 * Filter by range
137
	 * @param  Filter\FilterRange $filter
138
	 * @return void
139
	 */
140
	public function applyFilterRange(Filter\FilterRange $filter)
141
	{
142
		$conditions = $filter->getCondition();
143
144
		$value_from = $conditions[$filter->getColumn()]['from'];
145
		$value_to   = $conditions[$filter->getColumn()]['to'];
146
147
		if ($value_from || $value_from != '') {
148
			$this->data_source->where('%n >= ?', $filter->getColumn(), $value_from);
149
		}
150
151
		if ($value_to || $value_to != '') {
152
			$this->data_source->where('%n <= ?', $filter->getColumn(), $value_to);
153
		}
154
	}
155
156
157
	/**
158
	 * Filter by keyword
159
	 * @param  Filter\FilterText $filter
160
	 * @return void
161
	 */
162
	public function applyFilterText(Filter\FilterText $filter)
163
	{
164
		$condition = $filter->getCondition();
165
		$or = [];
166
167
		foreach ($condition as $column => $value) {
168
			$column = Dibi\Helpers::escape(
169
				$this->data_source->getConnection()->getDriver(),
170
				$column,
171
				\dibi::IDENTIFIER
172
			);
173
174
			if ($filter->isExactSearch()){
175
				$this->data_source->where("$column = %s", $value);
176
				continue;
177
			}
178
179 View Code Duplication
			if ($filter->hasSplitWordsSearch() === FALSE) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
180
				$words = [$value];
181
			} else {
182
				$words = explode(' ', $value);
183
			}
184
185
			foreach ($words as $word) {
186
				$escaped = $this->data_source->getConnection()->getDriver()->escapeLike($word, 0);
187
188
				if (preg_match("/[\x80-\xFF]/", $escaped)) {
189
					$or[] = "$column LIKE $escaped COLLATE utf8_bin";
190
				} else {
191
					$escaped = Strings::toAscii($escaped);
192
					$or[] = "$column LIKE $escaped COLLATE utf8_general_ci";
193
				}
194
			}
195
		}
196
197 View Code Duplication
		if (sizeof($or) > 1) {
198
			$this->data_source->where('(%or)', $or);
199
		} else {
200
			$this->data_source->where($or);
201
		}
202
	}
203
204
205
	/**
206
	 * Filter by multi select value
207
	 * @param  Filter\FilterMultiSelect $filter
208
	 * @return void
209
	 */
210
	public function applyFilterMultiSelect(Filter\FilterMultiSelect $filter)
211
	{
212
		$condition = $filter->getCondition();
213
		$values = $condition[$filter->getColumn()];
214
		$or = [];
0 ignored issues
show
Unused Code introduced by
$or is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
215
216
		if (sizeof($values) > 1) {
217
			$value1 = array_shift($values);
218
			$length = sizeof($values);
219
			$i = 1;
220
221
			$this->data_source->where('(%n = ?', $filter->getColumn(), $value1);
222
223
			foreach ($values as $value) {
224
				if ($i == $length) {
225
					$this->data_source->or('%n = ?)', $filter->getColumn(), $value);
226
				} else {
227
					$this->data_source->or('%n = ?', $filter->getColumn(), $value);
228
				}
229
230
				$i++;
231
			}
232
		} else {
233
			$this->data_source->where('%n = ?', $filter->getColumn(), reset($values));
234
		}
235
	}
236
237
238
	/**
239
	 * Filter by select value
240
	 * @param  Filter\FilterSelect $filter
241
	 * @return void
242
	 */
243
	public function applyFilterSelect(Filter\FilterSelect $filter)
244
	{
245
		$this->data_source->where($filter->getCondition());
246
	}
247
248
249
	/**
250
	 * Apply limit and offset on data
251
	 * @param int $offset
252
	 * @param int $limit
253
	 * @return static
254
	 */
255
	public function limit($offset, $limit)
256
	{
257
		$this->data = $this->data_source->fetchAll($offset, $limit);
258
259
		return $this;
260
	}
261
262
263
	/**
264
	 * Sort data
265
	 * @param  Sorting $sorting
266
	 * @return static
267
	 */
268
	public function sort(Sorting $sorting)
269
	{
270
		if (is_callable($sorting->getSortCallback())) {
271
			call_user_func(
272
				$sorting->getSortCallback(),
273
				$this->data_source,
274
				$sorting->getSort()
275
			);
276
277
			return $this;
278
		}
279
280
		$sort = $sorting->getSort();
281
282
		if (!empty($sort)) {
283
			$this->data_source->removeClause('ORDER BY');
284
			$this->data_source->orderBy($sort);
285
		} else {
286
			/**
287
			 * Has the statement already a order by clause?
288
			 */
289
			$this->data_source->clause('ORDER BY');
290
291
			$reflection = new \ReflectionClass('DibiFluent');
292
			$cursor_property = $reflection->getProperty('cursor');
293
			$cursor_property->setAccessible(TRUE);
294
			$cursor = $cursor_property->getValue($this->data_source);
295
296
			if (!$cursor) {
297
				$this->data_source->orderBy($this->primary_key);
298
			}
299
		}
300
301
		return $this;
302
	}
303
304
	public function addAggregationColumn($aggregation_type, $column)
305
	{
306
		$this->aggregation_data_source = $this->aggregation_data_source->select($aggregation_type .'(%n)', $column)->as($column);
307
	}
308
309
	public function getAggregationData()
310
	{
311
		$data = $this->aggregation_data_source->from($this->data_source)->as('data')->fetch();
312
		return $data;
313
	}
314
}
315