Completed
Push — master ( 8e3308...28700d )
by Pavel
02:52
created

NextrasDataSource::getPlaceholder()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 6
rs 9.4285
cc 1
eloc 3
nc 1
nop 0
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 Ublaboo\DataGrid\Filter;
12
use Nette\Utils\Callback;
13
use Nette\Utils\Strings;
14
use Ublaboo\DataGrid\Utils\Sorting;
15
use Nextras\Orm\Collection\ICollection;
16
use Ublaboo\DataGrid\Utils\ArraysHelper;
17
18
class NextrasDataSource extends FilterableDataSource implements IDataSource
19
{
20
21
	/**
22
	 * @var QueryBuilder
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 ICollection  $data_source
39
	 * @param string       $primary_key
40
	 */
41
	public function __construct(ICollection $data_source, $primary_key)
42
	{
43
		$this->data_source = $data_source;
0 ignored issues
show
Documentation Bug introduced by
It seems like $data_source of type object<Nextras\Orm\Collection\ICollection> is incompatible with the declared type object<Ublaboo\DataGrid\DataSource\QueryBuilder> of property $data_source.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
44
		$this->primary_key = $primary_key;
45
	}
46
47
48
	/**
49
	 * @return Doctrine\ORM\Query
50
	*/
51
	public function getQuery()
52
	{
53
		return $this->data_source->getQuery();
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->data_source->countStored();
69
70
		return $count;
0 ignored issues
show
Unused Code introduced by
return $count; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
71
	}
72
73
	/**
74
	 * Get the data
75
	 * @return array
76
	 */
77
	public function getData()
78
	{
79
		/**
80
		 * Paginator is better if the query uses ManyToMany associations
81
		 */
82
		return $this->data ?: $this->data_source->fetchAll();
83
	}
84
85
86
	/**
87
	 * Filter data - get one row
88
	 * @param array $condition
89
	 * @return static
90
	 */
91
	public function filterOne(array $condition)
92
	{
93
		$this->data_source = $this->data_source->findBy($condition);
94
95
		return $this;
96
	}
97
98
99
	/**
100
	 * Filter by date
101
	 * @param  Filter\FilterDate $filter
102
	 * @return static
103
	 */
104
	public function applyFilterDate(Filter\FilterDate $filter)
0 ignored issues
show
Unused Code introduced by
The parameter $filter is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
105
	{
106
		/*foreach ($filter->getCondition() as $column => $value) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
65% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
107
			$date = \DateTime::createFromFormat($filter->getPhpFormat(), $value);
108
				->andWhere("$c <= ?$p2")
109
				->setParameter($p1, $date->format('Y-m-d 00:00:00'))
110
				->setParameter($p2, $date->format('Y-m-d 23:59:59'));
111
		}
112
113
		return $this;*/
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)
0 ignored issues
show
Unused Code introduced by
The parameter $filter is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
123
	{
124
		/*$conditions = $filter->getCondition();
0 ignored issues
show
Unused Code Comprehensibility introduced by
64% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
125
		$c = $this->checkAliases($filter->getColumn());
126
127
		$value_from = $conditions[$filter->getColumn()]['from'];
128
		$value_to   = $conditions[$filter->getColumn()]['to'];
129
130
		if ($value_from) {
131
			$date_from = \DateTime::createFromFormat($filter->getPhpFormat(), $value_from);
132
			$date_from->setTime(0, 0, 0);
133
134
			$p = $this->getPlaceholder();
135
136
			$this->data_source->andWhere("$c >= ?$p")->setParameter($p, $date_from->format('Y-m-d H:i:s'));
137
		}
138
139
		if ($value_to) {
140
			$date_to = \DateTime::createFromFormat($filter->getPhpFormat(), $value_to);
141
			$date_to->setTime(23, 59, 59);
142
143
			$p = $this->getPlaceholder();
144
145
			$this->data_source->andWhere("$c <= ?$p")->setParameter($p, $date_to->format('Y-m-d H:i:s'));
146
		}*/
147
	}
148
149
150
	/**
151
	 * Filter by range
152
	 * @param  Filter\FilterRange $filter
153
	 * @return void
154
	 */
155 View Code Duplication
	public function applyFilterRange(Filter\FilterRange $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...
156
	{
157
		$conditions = $filter->getCondition();
158
159
		$value_from = $conditions[$filter->getColumn()]['from'];
160
		$value_to   = $conditions[$filter->getColumn()]['to'];
161
162
		if ($value_from) {
163
			$this->data_source->getQueryBuilder()->andWhere("%column >= %any", $filter->getColumn(), $value_from);
164
		}
165
166
		if ($value_to) {
167
			$this->data_source->getQueryBuilder()->andWhere("%column <= %any", $filter->getColumn(), $value_to);
168
		}
169
	}
170
171
172
	/**
173
	 * Filter by keyword
174
	 * @param  Filter\FilterText $filter
175
	 * @return void
176
	 */
177
	public function applyFilterText(Filter\FilterText $filter)
178
	{
179
		$condition = $filter->getCondition();
180
		$expr = '(';
181
		$params = [];
182
183
		foreach ($condition as $column => $value) {
184
			$words = explode(' ', $value);
185
186
			foreach ($words as $word) {
187
				$expr .= "%column LIKE %s OR ";
188
				$params[] = $column;
189
				$params[] = "%$word%";
190
			}
191
		}
192
193
		$expr = preg_replace('/ OR $/', ')', $expr);
194
195
		array_unshift($params, $expr);
196
197
		call_user_func_array([$this->data_source->getQueryBuilder(), 'andWhere'], $params);
198
	}
199
200
201
	/**
202
	 * Filter by multi select value
203
	 * @param  Filter\FilterMultiSelect $filter
204
	 * @return void
205
	 */
206
	public function applyFilterMultiSelect(Filter\FilterMultiSelect $filter)
207
	{
208
		$condition = $filter->getCondition();
209
		$values = $condition[$filter->getColumn()];
210
		$expr = '(';
211
212
		foreach ($values as $value) {
213
			$expr .= "%column = %any OR ";
214
			$params[] = $filter->getColumn();
0 ignored issues
show
Coding Style Comprehensibility introduced by
$params was never initialized. Although not strictly required by PHP, it is generally a good practice to add $params = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
215
			$params[] = "$value";
216
		}
217
218
		$expr = preg_replace('/ OR $/', ')', $expr);
219
220
		array_unshift($params, $expr);
221
222
		call_user_func_array([$this->data_source->getQueryBuilder(), 'andWhere'], $params);
223
	}
224
225
226
	/**
227
	 * Filter by select value
228
	 * @param  Filter\FilterSelect $filter
229
	 * @return void
230
	 */
231
	public function applyFilterSelect(Filter\FilterSelect $filter)
232
	{
233
		foreach ($filter->getCondition() as $column => $value) {
234
			$this->data_source->getQueryBuilder()->andWhere("%column = %any", $column, $value);
235
		}
236
	}
237
238
239
	/**
240
	 * Apply limit and offset on data
241
	 * @param int $offset
242
	 * @param int $limit
243
	 * @return static
244
	 */
245
	public function limit($offset, $limit)
246
	{
247
		$this->data_source = $this->data_source->limitBy($limit, $offset);
248
249
		return $this;
250
	}
251
252
253
	/**
254
	 * Sort data
255
	 * @param  Sorting $sorting
256
	 * @return static
257
	 */
258
	public function sort(Sorting $sorting)
259
	{
260
		if (is_callable($sorting->getSortCallback())) {
261
			call_user_func(
262
				$sorting->getSortCallback(),
263
				$this->data_source,
264
				$sorting->getSort()
265
			);
266
267
			return $this;
268
		}
269
270
		$sort = $sorting->getSort();
271
272
		if (!empty($sort)) {
273
			foreach ($sort as $column => $order) {
274
				$this->data_source = $this->data_source->orderBy($column, $order);
275
			}
276
		} else {
277
			/**
278
			 * Has the statement already a order by clause?
279
			 */
280
			$order = $this->data_source->getQueryBuilder()->getClause('order');
281
282
			if (ArraysHelper::testEmpty($order)) {
283
				$this->data_source = $this->data_source->orderBy($this->primary_key);
284
			}
285
		}
286
287
		return $this;
288
	}
289
290
}
291