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

NetteDatabaseTableDataSource::getData()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
rs 10
cc 2
eloc 2
nc 2
nop 0
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 Nette\Database\Table\Selection;
12
use Ublaboo\DataGrid\Filter;
13
use Ublaboo\DataGrid\Utils\DateTimeHelper;
14
use Ublaboo\DataGrid\Utils\Sorting;
15
16
class NetteDatabaseTableDataSource extends FilterableDataSource implements IDataSource
17
{
18
19
	/**
20
	 * @var Selection
21
	 */
22
	protected $data_source;
23
24
	/**
25
	 * @var array
26
	 */
27
	protected $data = [];
28
29
	/**
30
	 * @var string
31
	 */
32
	protected $primary_key;
33
34
35
	/**
36
	 * @param Selection $data_source
37
	 * @param string $primary_key
38
	 */
39
	public function __construct(Selection $data_source, $primary_key)
40
	{
41
		$this->data_source = $data_source;
42
		$this->primary_key = $primary_key;
43
	}
44
45
46
	/********************************************************************************
47
	 *                          IDataSource implementation                          *
48
	 ********************************************************************************/
49
50
51
	/**
52
	 * Get count of data
53
	 * @return int
54
	 */
55
	public function getCount()
56
	{
57
		try {
58
			$primary = $this->data_source->getPrimary();
59
		} catch (\LogicException $e) {
60
			return $this->data_source->count('*');
61
		}
62
63
		return $this->data_source->count(
64
			$this->data_source->getName() . '.' . (is_array($primary) ? reset($primary) : $primary)
65
		);
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 = DateTimeHelper::tryConvertToDateTime($conditions[$filter->getColumn()], [$filter->getPhpFormat()]);
102
103
		$this->data_source->where("DATE({$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)
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...
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 = DateTimeHelper::tryConvertToDateTime($value_from, [$filter->getPhpFormat()]);
121
			$date_from->setTime(0, 0, 0);
122
123
			$this->data_source->where("DATE({$filter->getColumn()}) >= ?", $date_from->format('Y-m-d'));
124
		}
125
126
		if ($value_to) {
127
			$date_to = DateTimeHelper::tryConvertToDateTime($value_to, [$filter->getPhpFormat()]);
128
			$date_to->setTime(23, 59, 59);
129
130
			$this->data_source->where("DATE({$filter->getColumn()}) <= ?", $date_to->format('Y-m-d'));
131
		}
132
	}
133
134
135
	/**
136
	 * Filter by range
137
	 * @param  Filter\FilterRange $filter
138
	 * @return void
139
	 */
140 View Code Duplication
	public function applyFilterRange(Filter\FilterRange $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...
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) {
148
			$this->data_source->where("{$filter->getColumn()} >= ?", $value_from);
149
		}
150
151
		if ($value_to) {
152
			$this->data_source->where("{$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
		$or = [];
165
		$args = [];
166
		$big_or = '(';
167
		$big_or_args = [];
168
		$condition = $filter->getCondition();
169
170
		foreach ($condition as $column => $value) {
171
172
			$like = '(';
173
			$args = [];
174
175
			if($filter->isExactSearch()){
176
				$like .=  "$column = ? OR ";
177
				$args[] = "$value";
178
			} else {
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
				foreach ($words as $word) {
185
					$like .= "$column LIKE ? OR ";
186
					$args[] = "%$word%";
187
				}
188
			}
189
			$like = substr($like, 0, strlen($like) - 4) . ')';
190
191
			$or[] = $like;
192
			$big_or .= "$like OR ";
193
			$big_or_args = array_merge($big_or_args, $args);
194
		}
195
196
		if (sizeof($or) > 1) {
197
			$big_or = substr($big_or, 0, strlen($big_or) - 4).')';
198
199
			$query = array_merge([$big_or], $big_or_args);
200
201
			call_user_func_array([$this->data_source, 'where'], $query);
202
		} else {
203
			$query = array_merge($or, $args);
204
205
			call_user_func_array([$this->data_source, 'where'], $query);
206
		}
207
	}
208
209
210
	/**
211
	 * Filter by multi select value
212
	 * @param  Filter\FilterMultiSelect $filter
213
	 * @return void
214
	 */
215
	public function applyFilterMultiSelect(Filter\FilterMultiSelect $filter)
216
	{
217
		$condition = $filter->getCondition();
218
		$values = $condition[$filter->getColumn()];
219
		$or = '(';
220
221
		if (sizeof($values) > 1) {
222
			$length = sizeof($values);
223
			$i = 1;
224
		
225
			foreach ($values as $value) {
226
				if ($i == $length) {
227
					$or .= $filter->getColumn() . ' = ?)';
228
				} else {
229
					$or .= $filter->getColumn() . ' = ? OR ';
230
				}
231
232
				$i++;
233
			}
234
235
			array_unshift($values, $or);
236
237
			call_user_func_array([$this->data_source, 'where'], $values);
238
		} else {
239
			$this->data_source->where($filter->getColumn() . ' = ?', reset($values));
240
		}
241
	}
242
243
244
	/**
245
	 * Filter by select value
246
	 * @param  Filter\FilterSelect $filter
247
	 * @return void
248
	 */
249
	public function applyFilterSelect(Filter\FilterSelect $filter)
250
	{
251
		$this->data_source->where($filter->getCondition());
252
	}
253
254
255
	/**
256
	 * Apply limit and offset on data
257
	 * @param int $offset
258
	 * @param int $limit
259
	 * @return static
260
	 */
261
	public function limit($offset, $limit)
262
	{
263
		$this->data = $this->data_source->limit($limit, $offset)->fetchAll();
264
265
		return $this;
266
	}
267
268
269
	/**
270
	 * Sort data
271
	 * @param  Sorting $sorting
272
	 * @return static
273
	 */
274 View Code Duplication
	public function sort(Sorting $sorting)
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...
275
	{
276
		if (is_callable($sorting->getSortCallback())) {
277
			call_user_func(
278
				$sorting->getSortCallback(),
279
				$this->data_source,
280
				$sorting->getSort()
281
			);
282
283
			return $this;
284
		}
285
286
		$sort = $sorting->getSort();
287
288
		if (!empty($sort)) {
289
			$this->data_source->getSqlBuilder()->setOrder([], []);
290
291
			foreach ($sort as $column => $order) {
292
				$this->data_source->order("$column $order");
293
			}
294
		} else {
295
			/**
296
			 * Has the statement already a order by clause?
297
			 */
298
			if (!$this->data_source->getSqlBuilder()->getOrder()) {
299
				$this->data_source->order($this->primary_key);
300
			}
301
		}
302
303
		return $this;
304
	}
305
306
307
	/**
308
	 * @param  callable $aggregationCallback
309
	 * @return void
310
	 */
311
	public function processAggregation(callable $aggregationCallback)
312
	{
313
		call_user_func($aggregationCallback, $this->data_source);
314
	}
315
316
}
317