Completed
Pull Request — master (#300)
by Martin
02:49
created

DoctrineCollectionDataSource   A

Complexity

Total Complexity 26

Size/Duplication

Total Lines 255
Duplicated Lines 8.24 %

Coupling/Cohesion

Components 1
Dependencies 8

Importance

Changes 1
Bugs 0 Features 1
Metric Value
wmc 26
c 1
b 0
f 1
lcom 1
cbo 8
dl 21
loc 255
rs 10

13 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A getMatched() 0 8 2
A getCount() 0 4 1
A getData() 0 4 1
A filterOne() 0 9 2
A applyFilterDate() 0 12 2
A applyFilterDateRange() 16 22 3
A applyFilterRange() 0 14 3
A applyFilterText() 5 19 4
A applyFilterMultiSelect() 0 7 1
A applyFilterSelect() 0 7 2
A limit() 0 6 1
A sort() 0 21 3

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      Jakub Kontra <[email protected]>
6
 * @author      Pavel Janda <[email protected]>
7
 * @package     Ublaboo
8
 */
9
10
namespace Ublaboo\DataGrid\DataSource;
11
12
use Doctrine\Common\Collections\Collection;
13
use Doctrine\Common\Collections\Criteria;
14
use Ublaboo\DataGrid\Filter;
15
use Ublaboo\DataGrid\Utils\Sorting;
16
17
final class DoctrineCollectionDataSource extends FilterableDataSource implements IDataSource
18
{
19
20
	/**
21
	 * @var Collection
22
	 */
23
	private $data_source;
24
25
	/**
26
	 * @var string
27
	 */
28
	private $primary_key;
29
30
	/**
31
	 * @var Criteria
32
	 */
33
	private $criteria;
34
35
	/**
36
	 * @var Collection
37
	 */
38
	private $matched;
39
40
41
	/**
42
	 * @param Collection  $collection
43
	 * @param string      $primary_key
44
	 */
45
	public function __construct(Collection $collection, $primary_key)
46
	{
47
		$this->criteria = Criteria::create();
48
		$this->data_source = $collection;
49
		$this->primary_key = $primary_key;
50
	}
51
52
53
	/**
54
	 * @return Collection
55
	 */
56
	private function getMatched()
57
	{
58
		if (!isset($this->matched)) {
59
			$this->matched = $this->data_source->matching($this->criteria);
60
		}
61
62
		return $this->matched;
63
	}
64
65
66
	/********************************************************************************
67
	 *                          IDataSource implementation                          *
68
	 ********************************************************************************/
69
70
71
	/**
72
	 * Get count of data
73
	 * @return int
74
	 */
75
	public function getCount()
76
	{
77
		return $this->getMatched()->count();
78
	}
79
80
81
	/**
82
	 * Get the data
83
	 * @return array
84
	 */
85
	public function getData()
86
	{
87
		return $this->getMatched()->toArray();
88
	}
89
90
91
	/**
92
	 * Filter data - get one row
93
	 * @param array $condition
94
	 * @return static
95
	 */
96
	public function filterOne(array $condition)
97
	{
98
		foreach ($condition as $column => $value) {
99
			$expr = Criteria::expr()->eq($column, $value);
100
			$this->criteria->andWhere($expr);
101
		}
102
103
		return $this;
104
	}
105
106
107
	/**
108
	 * Filter by date
109
	 * @param  Filter\FilterDate $filter
110
	 * @return void
111
	 */
112
	public function applyFilterDate(Filter\FilterDate $filter)
113
	{
114
		foreach ($filter->getCondition() as $column => $value) {
115
			$date = \DateTime::createFromFormat($filter->getPhpFormat(), $value)
116
				->format('Y-m-d H:i:s');
117
118
			$from = Criteria::expr()->gte($filter->getColumn(), $date->format('Y-m-d 00:00:00'));
119
			$to = Criteria::expr()->lte($filter->getColumn(), $date->format('Y-m-d 23:59:59'));
120
121
			$this->criteria->andWhere($from)->andWhere($to);
122
		}
123
	}
124
125
126
	/**
127
	 * Filter by date range
128
	 * @param  Filter\FilterDateRange $filter
129
	 * @return void
130
	 */
131
	public function applyFilterDateRange(Filter\FilterDateRange $filter)
132
	{
133
		$values = $conditions[$filter->getColumn()];
0 ignored issues
show
Bug introduced by
The variable $conditions does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
134
135 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...
136
			$date_from = \DateTime::createFromFormat($filter->getPhpFormat(), $value_from)
137
				->setTime(0, 0, 0)
138
				->format('Y-m-d H:i:s');
139
140
			$expr = Criteria::expr()->gte($filter->getColumn(), $date_from);
141
			$this->criteria->andWhere($expr);
142
		}
143
144 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...
145
			$date_to = \DateTime::createFromFormat($filter->getPhpFormat(), $value_to)
146
				->setTime(23, 59, 59)
147
				->format('Y-m-d H:i:s');
148
149
			$expr = Criteria::expr()->lte($filter->getColumn(), $date_to);
150
			$this->criteria->andWhere($expr);
151
		}
152
	}
153
154
155
	/**
156
	 * Filter by range
157
	 * @param  Filter\FilterRange $filter
158
	 * @return void
159
	 */
160
	public function applyFilterRange(Filter\FilterRange $filter)
161
	{
162
		$values = $conditions[$filter->getColumn()];
0 ignored issues
show
Bug introduced by
The variable $conditions does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
163
164
		if ($value_from = $values['from']) {
165
			$expr = Criteria::expr()->gte($filter->getColumn(), $value_from);
166
			$this->criteria->andWhere($expr);
167
		}
168
169
		if ($value_to = $values['to']) {
170
			$expr = Criteria::expr()->lte($filter->getColumn(), $value_to);
171
			$this->criteria->andWhere($expr);
172
		}
173
	}
174
175
176
	/**
177
	 * Filter by keyword
178
	 * @param  Filter\FilterText $filter
179
	 * @return void
180
	 */
181
	public function applyFilterText(Filter\FilterText $filter)
182
	{
183
		$exprs = [];
184
185
		foreach ($filter->getCondition() as $column => $value) {
186 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...
187
				$words = [$value];
188
			} else {
189
				$words = explode(' ', $value);
190
			}
191
192
			foreach ($words as $word) {
193
				$exprs[] = Criteria::expr()->contains($column, $word);
194
			}
195
		}
196
197
		$expr = call_user_func_array([Criteria::expr(), 'orX'], $exprs);
198
		$this->criteria->andWhere($expr);
199
	}
200
201
202
	/**
203
	 * Filter by multi select value
204
	 * @param  Filter\FilterMultiSelect $filter
205
	 * @return void
206
	 */
207
	public function applyFilterMultiSelect(Filter\FilterMultiSelect $filter)
208
	{
209
		$values = $filter->getCondition()[$filter->getColumn()];
210
211
		$expr = Criteria::expr()->in($filter->getColumn(), $values);
212
		$this->criteria->andWhere($expr);
213
	}
214
215
216
	/**
217
	 * Filter by select value
218
	 * @param  Filter\FilterSelect $filter
219
	 * @return void
220
	 */
221
	public function applyFilterSelect(Filter\FilterSelect $filter)
222
	{
223
		foreach ($filter->getCondition() as $column => $value) {
224
			$expr = Criteria::expr()->eq($column, $value);
225
			$this->criteria->andWhere($expr);
226
		}
227
	}
228
229
230
	/**
231
	 * Apply limit and offset on data
232
	 * @param int $offset
233
	 * @param int $limit
234
	 * @return static
235
	 */
236
	public function limit($offset, $limit)
237
	{
238
		$this->criteria->setFirstResult($offset)->setMaxResults($limit);
239
240
		return $this;
241
	}
242
243
244
	/**
245
	 * Sort data
246
	 * @param Sorting $sorting
247
	 * @return static
248
	 */
249
	public function sort(Sorting $sorting)
250
	{
251
		if (is_callable($sorting->getSortCallback())) {
252
			call_user_func(
253
				$sorting->getSortCallback(),
254
				$this->criteria,
255
				$sorting->getSort()
256
			);
257
258
			return $this;
259
		}
260
261
		if ($sort = $sorting->getSort()) {
262
			$this->criteria->orderBy($sort);
263
			return $this;
264
		}
265
266
		$this->criteria->orderBy([$this->primary_key => 'ASC']);
267
268
		return $this;
269
	}
270
271
}
272