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

DoctrineCollectionDataSource   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 246
Duplicated Lines 8.54 %

Coupling/Cohesion

Components 1
Dependencies 8

Importance

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

13 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 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
	/**
37
	 * @param Collection  $collection
38
	 * @param string      $primary_key
39
	 */
40
	public function __construct(Collection $collection, $primary_key)
41
	{
42
		$this->criteria = Criteria::create();
43
		$this->data_source = $collection;
44
		$this->primary_key = $primary_key;
45
	}
46
47
48
	/**
49
	 * @return Collection
50
	 */
51
	private function getFilteredCollection()
52
	{
53
		return $this->data_source->matching($this->criteria);
54
	}
55
56
57
	/********************************************************************************
58
	 *                          IDataSource implementation                          *
59
	 ********************************************************************************/
60
61
62
	/**
63
	 * Get count of data
64
	 * @return int
65
	 */
66
	public function getCount()
67
	{
68
		return $this->getFilteredCollection()->count();
69
	}
70
71
72
	/**
73
	 * Get the data
74
	 * @return array
75
	 */
76
	public function getData()
77
	{
78
		return $this->getFilteredCollection()->toArray();
79
	}
80
81
82
	/**
83
	 * Filter data - get one row
84
	 * @param array $condition
85
	 * @return static
86
	 */
87
	public function filterOne(array $condition)
88
	{
89
		foreach ($condition as $column => $value) {
90
			$expr = Criteria::expr()->eq($column, $value);
91
			$this->criteria->andWhere($expr);
92
		}
93
94
		return $this;
95
	}
96
97
98
	/**
99
	 * Filter by date
100
	 * @param  Filter\FilterDate $filter
101
	 * @return void
102
	 */
103
	public function applyFilterDate(Filter\FilterDate $filter)
104
	{
105
		foreach ($filter->getCondition() as $column => $value) {
106
			$date = \DateTime::createFromFormat($filter->getPhpFormat(), $value)
107
				->format('Y-m-d H:i:s');
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
		$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...
125
126 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...
127
			$date_from = \DateTime::createFromFormat($filter->getPhpFormat(), $value_from)
128
				->setTime(0, 0, 0)
129
				->format('Y-m-d H:i:s');
130
131
			$expr = Criteria::expr()->gte($filter->getColumn(), $date_from);
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 = \DateTime::createFromFormat($filter->getPhpFormat(), $value_to)
137
				->setTime(23, 59, 59)
138
				->format('Y-m-d H:i:s');
139
140
			$expr = Criteria::expr()->lte($filter->getColumn(), $date_to);
141
			$this->criteria->andWhere($expr);
142
		}
143
	}
144
145
146
	/**
147
	 * Filter by range
148
	 * @param  Filter\FilterRange $filter
149
	 * @return void
150
	 */
151
	public function applyFilterRange(Filter\FilterRange $filter)
152
	{
153
		$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...
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 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...
178
				$words = [$value];
179
			} else {
180
				$words = explode(' ', $value);
181
			}
182
183
			foreach ($words as $word) {
184
				$exprs[] = Criteria::expr()->contains($column, $word);
185
			}
186
		}
187
188
		$expr = call_user_func_array([Criteria::expr(), 'orX'], $exprs);
189
		$this->criteria->andWhere($expr);
190
	}
191
192
193
	/**
194
	 * Filter by multi select value
195
	 * @param  Filter\FilterMultiSelect $filter
196
	 * @return void
197
	 */
198
	public function applyFilterMultiSelect(Filter\FilterMultiSelect $filter)
199
	{
200
		$values = $filter->getCondition()[$filter->getColumn()];
201
202
		$expr = Criteria::expr()->in($filter->getColumn(), $values);
203
		$this->criteria->andWhere($expr);
204
	}
205
206
207
	/**
208
	 * Filter by select value
209
	 * @param  Filter\FilterSelect $filter
210
	 * @return void
211
	 */
212
	public function applyFilterSelect(Filter\FilterSelect $filter)
213
	{
214
		foreach ($filter->getCondition() as $column => $value) {
215
			$expr = Criteria::expr()->eq($column, $value);
216
			$this->criteria->andWhere($expr);
217
		}
218
	}
219
220
221
	/**
222
	 * Apply limit and offset on data
223
	 * @param int $offset
224
	 * @param int $limit
225
	 * @return static
226
	 */
227
	public function limit($offset, $limit)
228
	{
229
		$this->criteria->setFirstResult($offset)->setMaxResults($limit);
230
231
		return $this;
232
	}
233
234
235
	/**
236
	 * Sort data
237
	 * @param Sorting $sorting
238
	 * @return static
239
	 */
240
	public function sort(Sorting $sorting)
241
	{
242
		if (is_callable($sorting->getSortCallback())) {
243
			call_user_func(
244
				$sorting->getSortCallback(),
245
				$this->criteria,
246
				$sorting->getSort()
247
			);
248
249
			return $this;
250
		}
251
252
		if ($sort = $sorting->getSort()) {
253
			$this->criteria->orderBy($sort);
254
			return $this;
255
		}
256
257
		$this->criteria->orderBy([$this->primary_key => 'ASC']);
258
259
		return $this;
260
	}
261
262
}
263