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