Completed
Push — master ( de0724...bff5ff )
by Pavel
02:29
created

DibiFluentDataSource::processAggregation()   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 1
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 Dibi;
12
use DibiFluent;
13
use Nette\Utils\Callback;
14
use Nette\Utils\Strings;
15
use Ublaboo\DataGrid\Filter;
16
use Ublaboo\DataGrid\Utils\DateTimeHelper;
17
use Ublaboo\DataGrid\Utils\Sorting;
18
19
class DibiFluentDataSource extends FilterableDataSource implements IDataSource
20
{
21
22
	/**
23
	 * @var DibiFluent
24
	 */
25
	protected $data_source;
26
27
	/**
28
	 * @var array
29
	 */
30
	protected $data = [];
31
32
	/**
33
	 * @var string
34
	 */
35
	protected $primary_key;
36
37
38
	/**
39
	 * @param DibiFluent $data_source
40
	 * @param string $primary_key
41
	 */
42
	public function __construct(DibiFluent $data_source, $primary_key)
43
	{
44
		$this->data_source = $data_source;
45
		$this->primary_key = $primary_key;
46
	}
47
48
49
	/********************************************************************************
50
	 *                          IDataSource implementation                          *
51
	 ********************************************************************************/
52
53
54
	/**
55
	 * Get count of data
56
	 * @return int
57
	 */
58
	public function getCount()
59
	{
60
		return $this->data_source->count();
61
	}
62
63
64
	/**
65
	 * Get the data
66
	 * @return array
67
	 */
68
	public function getData()
69
	{
70
		return $this->data ?: $this->data_source->fetchAll();
71
	}
72
73
74
	/**
75
	 * Filter data - get one row
76
	 * @param array $condition
77
	 * @return static
78
	 */
79
	public function filterOne(array $condition)
80
	{
81
		$this->data_source->where($condition)->limit(1);
82
83
		return $this;
84
	}
85
86
87
	/**
88
	 * Filter by date
89
	 * @param  Filter\FilterDate $filter
90
	 * @return void
91
	 */
92 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...
93
	{
94
		$conditions = $filter->getCondition();
95
96
		$date = DateTimeHelper::tryConvertToDateTime($conditions[$filter->getColumn()], [$filter->getPhpFormat()]);
97
98
		$this->data_source->where('DATE(%n) = ?', $filter->getColumn(), $date->format('Y-m-d'));
99
	}
100
101
102
	/**
103
	 * Filter by date range
104
	 * @param  Filter\FilterDateRange $filter
105
	 * @return void
106
	 */
107
	public function applyFilterDateRange(Filter\FilterDateRange $filter)
108
	{
109
		$conditions = $filter->getCondition();
110
111
		$value_from = $conditions[$filter->getColumn()]['from'];
112
		$value_to   = $conditions[$filter->getColumn()]['to'];
113
114
		if ($value_from) {
115
			$date_from = DateTimeHelper::tryConvertToDateTime($value_from, [$filter->getPhpFormat()]);
116
			$date_from->setTime(0, 0, 0);
117
118
			$this->data_source->where('DATE(%n) >= ?', $filter->getColumn(), $date_from);
119
		}
120
121
		if ($value_to) {
122
			$date_to = DateTimeHelper::tryConvertToDateTime($value_to, [$filter->getPhpFormat()]);
123
			$date_to->setTime(23, 59, 59);
124
125
			$this->data_source->where('DATE(%n) <= ?', $filter->getColumn(), $date_to);
126
		}
127
	}
128
129
130
	/**
131
	 * Filter by range
132
	 * @param  Filter\FilterRange $filter
133
	 * @return void
134
	 */
135
	public function applyFilterRange(Filter\FilterRange $filter)
136
	{
137
		$conditions = $filter->getCondition();
138
139
		$value_from = $conditions[$filter->getColumn()]['from'];
140
		$value_to   = $conditions[$filter->getColumn()]['to'];
141
142
		if ($value_from || $value_from != '') {
143
			$this->data_source->where('%n >= ?', $filter->getColumn(), $value_from);
144
		}
145
146
		if ($value_to || $value_to != '') {
147
			$this->data_source->where('%n <= ?', $filter->getColumn(), $value_to);
148
		}
149
	}
150
151
152
	/**
153
	 * Filter by keyword
154
	 * @param  Filter\FilterText $filter
155
	 * @return void
156
	 */
157
	public function applyFilterText(Filter\FilterText $filter)
158
	{
159
		$condition = $filter->getCondition();
160
		$or = [];
161
162
		foreach ($condition as $column => $value) {
163
			$column = Dibi\Helpers::escape(
164
				$this->data_source->getConnection()->getDriver(),
165
				$column,
166
				\dibi::IDENTIFIER
167
			);
168
169
			if ($filter->isExactSearch()){
170
				$this->data_source->where("$column = %s", $value);
171
				continue;
172
			}
173
174 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...
175
				$words = [$value];
176
			} else {
177
				$words = explode(' ', $value);
178
			}
179
180
			foreach ($words as $word) {
181
				$escaped = $this->data_source->getConnection()->getDriver()->escapeLike($word, 0);
182
183
				if (preg_match("/[\x80-\xFF]/", $escaped)) {
184
					$or[] = "$column LIKE $escaped COLLATE utf8_bin";
185
				} else {
186
					$escaped = Strings::toAscii($escaped);
187
					$or[] = "$column LIKE $escaped COLLATE utf8_general_ci";
188
				}
189
			}
190
		}
191
192 View Code Duplication
		if (sizeof($or) > 1) {
193
			$this->data_source->where('(%or)', $or);
194
		} else {
195
			$this->data_source->where($or);
196
		}
197
	}
198
199
200
	/**
201
	 * Filter by multi select value
202
	 * @param  Filter\FilterMultiSelect $filter
203
	 * @return void
204
	 */
205
	public function applyFilterMultiSelect(Filter\FilterMultiSelect $filter)
206
	{
207
		$condition = $filter->getCondition();
208
		$values = $condition[$filter->getColumn()];
209
		$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...
210
211
		if (sizeof($values) > 1) {
212
			$value1 = array_shift($values);
213
			$length = sizeof($values);
214
			$i = 1;
215
216
			$this->data_source->where('(%n = ?', $filter->getColumn(), $value1);
217
218
			foreach ($values as $value) {
219
				if ($i == $length) {
220
					$this->data_source->or('%n = ?)', $filter->getColumn(), $value);
221
				} else {
222
					$this->data_source->or('%n = ?', $filter->getColumn(), $value);
223
				}
224
225
				$i++;
226
			}
227
		} else {
228
			$this->data_source->where('%n = ?', $filter->getColumn(), reset($values));
229
		}
230
	}
231
232
233
	/**
234
	 * Filter by select value
235
	 * @param  Filter\FilterSelect $filter
236
	 * @return void
237
	 */
238
	public function applyFilterSelect(Filter\FilterSelect $filter)
239
	{
240
		$this->data_source->where($filter->getCondition());
241
	}
242
243
244
	/**
245
	 * Apply limit and offset on data
246
	 * @param int $offset
247
	 * @param int $limit
248
	 * @return static
249
	 */
250
	public function limit($offset, $limit)
251
	{
252
		$this->data_source->limit($limit)->offset($offset);
253
254
		$this->data = $this->data_source->fetchAll();
255
256
		return $this;
257
	}
258
259
260
	/**
261
	 * Sort data
262
	 * @param  Sorting $sorting
263
	 * @return static
264
	 */
265
	public function sort(Sorting $sorting)
266
	{
267
		if (is_callable($sorting->getSortCallback())) {
268
			call_user_func(
269
				$sorting->getSortCallback(),
270
				$this->data_source,
271
				$sorting->getSort()
272
			);
273
274
			return $this;
275
		}
276
277
		$sort = $sorting->getSort();
278
279
		if (!empty($sort)) {
280
			$this->data_source->removeClause('ORDER BY');
281
			$this->data_source->orderBy($sort);
282
		} else {
283
			/**
284
			 * Has the statement already a order by clause?
285
			 */
286
			$this->data_source->clause('ORDER BY');
287
288
			$reflection = new \ReflectionClass('DibiFluent');
289
			$cursor_property = $reflection->getProperty('cursor');
290
			$cursor_property->setAccessible(TRUE);
291
			$cursor = $cursor_property->getValue($this->data_source);
292
293
			if (!$cursor) {
294
				$this->data_source->orderBy($this->primary_key);
295
			}
296
		}
297
298
		return $this;
299
	}
300
301
302
	/**
303
	 * @param  callable $aggregationCallback
304
	 * @return void
305
	 */
306
	public function processAggregation(callable $aggregationCallback)
307
	{
308
		call_user_func($aggregationCallback, $this->data_source);
309
	}
310
311
}
312