DoctrineCollectionDataSource   A
last analyzed

Complexity

Total Complexity 27

Size/Duplication

Total Lines 259
Duplicated Lines 7.34 %

Coupling/Cohesion

Components 1
Dependencies 9

Importance

Changes 0
Metric Value
wmc 27
c 0
b 0
f 0
lcom 1
cbo 9
dl 19
loc 259
rs 10

14 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A getFilteredCollection() 0 4 1
A getCount() 0 4 1
A getData() 0 4 1
A filterOne() 0 9 2
A applyFilterDate() 0 11 2
A applyFilterDateRange() 14 21 3
A applyFilterRange() 0 15 3
B applyFilterText() 5 24 5
A applyFilterMultiSelect() 0 7 1
A applyFilterSelect() 0 7 2
A limit() 0 6 1
A sort() 0 21 3
A processAggregation() 0 4 1

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      Martin Procházka <[email protected]>
6
 * @package     Ublaboo
7
 */
8
9
namespace Ublaboo\DataGrid\DataSource;
10
11
use Doctrine\Common\Collections\Collection;
12
use Doctrine\Common\Collections\Criteria;
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
final class DoctrineCollectionDataSource extends FilterableDataSource implements IDataSource, IAggregatable
19
{
20
21
	/**
22
	 * @var Collection
23
	 */
24
	private $data_source;
25
26
	/**
27
	 * @var string
28
	 */
29
	private $primary_key;
30
31
	/**
32
	 * @var Criteria
33
	 */
34
	private $criteria;
35
36
37
	/**
38
	 * @param Collection  $collection
39
	 * @param string      $primary_key
40
	 */
41
	public function __construct(Collection $collection, $primary_key)
42
	{
43
		$this->criteria = Criteria::create();
44
		$this->data_source = $collection;
45
		$this->primary_key = $primary_key;
46
	}
47
48
49
	/**
50
	 * @return Collection
51
	 */
52
	private function getFilteredCollection()
53
	{
54
		return $this->data_source->matching($this->criteria);
55
	}
56
57
58
	/********************************************************************************
59
	 *                          IDataSource implementation                          *
60
	 ********************************************************************************/
61
62
63
	/**
64
	 * Get count of data
65
	 * @return int
66
	 */
67
	public function getCount()
68
	{
69
		return $this->getFilteredCollection()->count();
70
	}
71
72
73
	/**
74
	 * Get the data
75
	 * @return array
76
	 */
77
	public function getData()
78
	{
79
		return $this->getFilteredCollection()->toArray();
80
	}
81
82
83
	/**
84
	 * Filter data - get one row
85
	 * @param array $condition
86
	 * @return static
87
	 */
88
	public function filterOne(array $condition)
89
	{
90
		foreach ($condition as $column => $value) {
91
			$expr = Criteria::expr()->eq($column, $value);
92
			$this->criteria->andWhere($expr);
93
		}
94
95
		return $this;
96
	}
97
98
99
	/**
100
	 * Filter by date
101
	 * @param  Filter\FilterDate $filter
102
	 * @return void
103
	 */
104
	public function applyFilterDate(Filter\FilterDate $filter)
105
	{
106
		foreach ($filter->getCondition() as $column => $value) {
107
			$date = DateTimeHelper::tryConvertToDateTime($value, [$filter->getPhpFormat()]);
108
109
			$from = Criteria::expr()->gte($filter->getColumn(), $date->format('Y-m-d 00:00:00'));
110
			$to = Criteria::expr()->lte($filter->getColumn(), $date->format('Y-m-d 23:59:59'));
111
112
			$this->criteria->andWhere($from)->andWhere($to);
113
		}
114
	}
115
116
117
	/**
118
	 * Filter by date range
119
	 * @param  Filter\FilterDateRange $filter
120
	 * @return void
121
	 */
122
	public function applyFilterDateRange(Filter\FilterDateRange $filter)
123
	{
124
		$conditions = $filter->getCondition();
125
		$values = $conditions[$filter->getColumn()];
126
127 View Code Duplication
		if ($value_from = $values['from']) {
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...
128
			$date_from = DateTimeHelper::tryConvertToDateTime($value_from, [$filter->getPhpFormat()]);
129
			$date_from->setTime(0, 0, 0);
130
131
			$expr = Criteria::expr()->gte($filter->getColumn(), $date_from->format('Y-m-d H:i:s'));
132
			$this->criteria->andWhere($expr);
133
		}
134
135 View Code Duplication
		if ($value_to = $values['to']) {
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...
136
			$date_to = DateTimeHelper::tryConvertToDateTime($value_to, [$filter->getPhpFormat()]);
137
			$date_to->setTime(23, 59, 59);
138
139
			$expr = Criteria::expr()->lte($filter->getColumn(), $date_to->format('Y-m-d H:i:s'));
140
			$this->criteria->andWhere($expr);
141
		}
142
	}
143
144
145
	/**
146
	 * Filter by range
147
	 * @param  Filter\FilterRange $filter
148
	 * @return void
149
	 */
150
	public function applyFilterRange(Filter\FilterRange $filter)
151
	{
152
		$conditions = $filter->getCondition();
153
		$values = $conditions[$filter->getColumn()];
154
155
		if ($value_from = $values['from']) {
156
			$expr = Criteria::expr()->gte($filter->getColumn(), $value_from);
157
			$this->criteria->andWhere($expr);
158
		}
159
160
		if ($value_to = $values['to']) {
161
			$expr = Criteria::expr()->lte($filter->getColumn(), $value_to);
162
			$this->criteria->andWhere($expr);
163
		}
164
	}
165
166
167
	/**
168
	 * Filter by keyword
169
	 * @param  Filter\FilterText $filter
170
	 * @return void
171
	 */
172
	public function applyFilterText(Filter\FilterText $filter)
173
	{
174
		$exprs = [];
175
176
		foreach ($filter->getCondition() as $column => $value) {
177
			if ($filter->isExactSearch()) {
178
				$exprs[] = Criteria::expr()->eq($column, $value);
179
				continue;
180
			}
181
182 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...
183
				$words = [$value];
184
			} else {
185
				$words = explode(' ', $value);
186
			}
187
188
			foreach ($words as $word) {
189
				$exprs[] = Criteria::expr()->contains($column, $word);
190
			}
191
		}
192
193
		$expr = call_user_func_array([Criteria::expr(), 'orX'], $exprs);
194
		$this->criteria->andWhere($expr);
195
	}
196
197
198
	/**
199
	 * Filter by multi select value
200
	 * @param  Filter\FilterMultiSelect $filter
201
	 * @return void
202
	 */
203
	public function applyFilterMultiSelect(Filter\FilterMultiSelect $filter)
204
	{
205
		$values = $filter->getCondition()[$filter->getColumn()];
206
207
		$expr = Criteria::expr()->in($filter->getColumn(), $values);
208
		$this->criteria->andWhere($expr);
209
	}
210
211
212
	/**
213
	 * Filter by select value
214
	 * @param  Filter\FilterSelect $filter
215
	 * @return void
216
	 */
217
	public function applyFilterSelect(Filter\FilterSelect $filter)
218
	{
219
		foreach ($filter->getCondition() as $column => $value) {
220
			$expr = Criteria::expr()->eq($column, $value);
221
			$this->criteria->andWhere($expr);
222
		}
223
	}
224
225
226
	/**
227
	 * Apply limit and offset on data
228
	 * @param int $offset
229
	 * @param int $limit
230
	 * @return static
231
	 */
232
	public function limit($offset, $limit)
233
	{
234
		$this->criteria->setFirstResult($offset)->setMaxResults($limit);
235
236
		return $this;
237
	}
238
239
240
	/**
241
	 * Sort data
242
	 * @param Sorting $sorting
243
	 * @return static
244
	 */
245
	public function sort(Sorting $sorting)
246
	{
247
		if (is_callable($sorting->getSortCallback())) {
248
			call_user_func(
249
				$sorting->getSortCallback(),
250
				$this->criteria,
251
				$sorting->getSort()
252
			);
253
254
			return $this;
255
		}
256
257
		if ($sort = $sorting->getSort()) {
258
			$this->criteria->orderBy($sort);
259
			return $this;
260
		}
261
262
		$this->criteria->orderBy([$this->primary_key => 'ASC']);
263
264
		return $this;
265
	}
266
267
268
	/**
269
	 * @param  callable  $aggregationCallback
270
	 * @return void
271
	 */
272
	public function processAggregation(callable $aggregationCallback)
273
	{
274
		call_user_func($aggregationCallback, clone $this->data_source);
275
	}
276
}
277