DibiFluentDataSource   A
last analyzed

Complexity

Total Complexity 32

Size/Duplication

Total Lines 293
Duplicated Lines 10.24 %

Coupling/Cohesion

Components 1
Dependencies 9

Test Coverage

Coverage 47.92%

Importance

Changes 0
Metric Value
wmc 32
c 0
b 0
f 0
lcom 1
cbo 9
dl 30
loc 293
rs 9.6
ccs 46
cts 96
cp 0.4792

13 Methods

Rating   Name   Duplication   Size   Complexity  
A applyFilterSelect() 0 4 1
A limit() 0 8 1
A processAggregation() 0 4 1
B applyFilterMultiSelect() 0 26 4
B sort() 0 35 4
A applyFilterDate() 8 8 1
A applyFilterDateRange() 0 21 3
A __construct() 0 5 1
A getCount() 0 4 1
A getData() 0 4 2
A filterOne() 0 6 1
B applyFilterRange() 0 15 5
C applyFilterText() 22 42 7

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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\Fluent;
12
use Dibi\Helpers;
13
use Ublaboo\DataGrid\AggregationFunction\IAggregatable;
14
use Ublaboo\DataGrid\Filter;
15
use Ublaboo\DataGrid\Utils\DateTimeHelper;
16
use Ublaboo\DataGrid\Utils\Sorting;
17
18 1
class DibiFluentDataSource extends FilterableDataSource implements IDataSource, IAggregatable
19
{
20
21
	/**
22
	 * @var Fluent
23
	 */
24
	protected $data_source;
25
26
	/**
27
	 * @var array
28
	 */
29
	protected $data = [];
30
31
	/**
32
	 * @var string
33
	 */
34
	protected $primary_key;
35
36
37
	/**
38
	 * @param Fluent $data_source
39
	 * @param string $primary_key
40
	 */
41
	public function __construct(Fluent $data_source, $primary_key)
42
	{
43 1
		$this->data_source = $data_source;
44 1
		$this->primary_key = $primary_key;
45 1
	}
46
47
48
	/********************************************************************************
49
	 *                          IDataSource implementation                          *
50
	 ********************************************************************************/
51
52
53
	/**
54
	 * Get count of data
55
	 * @return int
56
	 */
57
	public function getCount()
58
	{
59 1
		return $this->data_source->count();
60
	}
61
62
63
	/**
64
	 * Get the data
65
	 * @return array
66
	 */
67
	public function getData()
68
	{
69 1
		return $this->data ?: $this->data_source->fetchAll();
70
	}
71
72
73
	/**
74
	 * Filter data - get one row
75
	 * @param array $condition
76
	 * @return static
77
	 */
78
	public function filterOne(array $condition)
79
	{
80 1
		$this->data_source->where($condition)->limit(1);
81
82 1
		return $this;
83
	}
84
85
86
	/**
87
	 * Filter by date
88
	 * @param  Filter\FilterDate $filter
89
	 * @return void
90
	 */
91 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...
92
	{
93
		$conditions = $filter->getCondition();
94
95
		$date = DateTimeHelper::tryConvertToDateTime($conditions[$filter->getColumn()], [$filter->getPhpFormat()]);
96
97
		$this->data_source->where('DATE(%n) = ?', $filter->getColumn(), $date->format('Y-m-d'));
98
	}
99
100
101
	/**
102
	 * Filter by date range
103
	 * @param  Filter\FilterDateRange $filter
104
	 * @return void
105
	 */
106
	public function applyFilterDateRange(Filter\FilterDateRange $filter)
107
	{
108
		$conditions = $filter->getCondition();
109
110
		$value_from = $conditions[$filter->getColumn()]['from'];
111
		$value_to = $conditions[$filter->getColumn()]['to'];
112
113
		if ($value_from) {
114
			$date_from = DateTimeHelper::tryConvertToDateTime($value_from, [$filter->getPhpFormat()]);
115
			$date_from->setTime(0, 0, 0);
116
117
			$this->data_source->where('DATE(%n) >= ?', $filter->getColumn(), $date_from);
118
		}
119
120
		if ($value_to) {
121
			$date_to = DateTimeHelper::tryConvertToDateTime($value_to, [$filter->getPhpFormat()]);
122
			$date_to->setTime(23, 59, 59);
123
124
			$this->data_source->where('DATE(%n) <= ?', $filter->getColumn(), $date_to);
125
		}
126
	}
127
128
129
	/**
130
	 * Filter by range
131
	 * @param  Filter\FilterRange $filter
132
	 * @return void
133
	 */
134
	public function applyFilterRange(Filter\FilterRange $filter)
135
	{
136 1
		$conditions = $filter->getCondition();
137
138 1
		$value_from = $conditions[$filter->getColumn()]['from'];
139 1
		$value_to = $conditions[$filter->getColumn()]['to'];
140
141 1
		if ($value_from || $value_from != '') {
142 1
			$this->data_source->where('%n >= ?', $filter->getColumn(), $value_from);
143
		}
144
145 1
		if ($value_to || $value_to != '') {
146 1
			$this->data_source->where('%n <= ?', $filter->getColumn(), $value_to);
147
		}
148 1
	}
149
150
151
	/**
152
	 * Filter by keyword
153
	 * @param  Filter\FilterText $filter
154
	 * @return void
155
	 */
156
	public function applyFilterText(Filter\FilterText $filter)
157
	{
158 1
		$condition = $filter->getCondition();
159 1
		$driver = $this->data_source->getConnection()->getDriver();
160 1
		$or = [];
161
162 1
		foreach ($condition as $column => $value) {
163 1 View Code Duplication
			if (class_exists(Helpers::class) === true) {
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...
164 1
				$column = Helpers::escape(
165 1
					$driver,
166 1
					$column,
167 1
					\dibi::IDENTIFIER
168
				);
169
			} else {
170
				$column = $driver->escape(
171
					$column,
172
					\dibi::IDENTIFIER
173
				);
174
			}
175
176 1
			if ($filter->isExactSearch()) {
177 1
				$this->data_source->where("$column = %s", $value);
178 1
				continue;
179
			}
180
181 1 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...
182 1
				$words = [$value];
183
			} else {
184 1
				$words = explode(' ', $value);
185
			}
186
187 1
			foreach ($words as $word) {
188 1
				$or[] = ["$column LIKE %~like~", $word];
189
			}
190
		}
191
192 1 View Code Duplication
		if (sizeof($or) > 1) {
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...
193 1
			$this->data_source->where('(%or)', $or);
194
		} else {
195 1
			$this->data_source->where($or);
196
		}
197 1
	}
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 1
		$this->data_source->limit($limit)->offset($offset);
253
254 1
		$this->data = $this->data_source->fetchAll();
255
256 1
		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 1
		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 1
		$sort = $sorting->getSort();
278
279 1
		if (!empty($sort)) {
280 1
			$this->data_source->removeClause('ORDER BY');
281 1
			$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(Fluent::class);
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 1
		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, clone $this->data_source);
309
	}
310
}
311