|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
namespace ZfcDatagrid\DataSource; |
|
4
|
|
|
|
|
5
|
|
|
use Doctrine\ORM; |
|
6
|
|
|
use Doctrine\ORM\Query\Expr; |
|
7
|
|
|
use ZfcDatagrid\Column; |
|
8
|
|
|
use ZfcDatagrid\Column\Type; |
|
9
|
|
|
use ZfcDatagrid\DataSource\Doctrine2\Paginator as PaginatorAdapter; |
|
10
|
|
|
|
|
11
|
|
|
class Doctrine2 extends AbstractDataSource |
|
12
|
|
|
{ |
|
13
|
|
|
/** |
|
14
|
|
|
* @var ORM\QueryBuilder |
|
15
|
|
|
*/ |
|
16
|
|
|
private $qb; |
|
17
|
|
|
|
|
18
|
|
|
/** |
|
19
|
|
|
* Data source. |
|
20
|
|
|
* |
|
21
|
|
|
* @param mixed $data |
|
22
|
|
|
*/ |
|
23
|
|
View Code Duplication |
public function __construct($data) |
|
|
|
|
|
|
24
|
|
|
{ |
|
25
|
|
|
if ($data instanceof ORM\QueryBuilder) { |
|
26
|
|
|
$this->qb = $data; |
|
27
|
|
|
} else { |
|
28
|
|
|
$return = $data; |
|
29
|
|
|
if (is_object($data)) { |
|
30
|
|
|
$return = get_class($return); |
|
31
|
|
|
} |
|
32
|
|
|
throw new \InvalidArgumentException('Unknown data input...'.$return); |
|
33
|
|
|
} |
|
34
|
|
|
} |
|
35
|
|
|
|
|
36
|
|
|
/** |
|
37
|
|
|
* @return ORM\QueryBuilder |
|
38
|
|
|
*/ |
|
39
|
|
|
public function getData() |
|
40
|
|
|
{ |
|
41
|
|
|
return $this->qb; |
|
42
|
|
|
} |
|
43
|
|
|
|
|
44
|
|
|
/** |
|
45
|
|
|
* @throws \Exception |
|
46
|
|
|
*/ |
|
47
|
|
|
public function execute() |
|
48
|
|
|
{ |
|
49
|
|
|
$qb = $this->getData(); |
|
50
|
|
|
|
|
51
|
|
|
/* |
|
52
|
|
|
* Step 1) Apply needed columns |
|
53
|
|
|
*/ |
|
54
|
|
|
$selectColumns = []; |
|
55
|
|
View Code Duplication |
foreach ($this->getColumns() as $col) { |
|
|
|
|
|
|
56
|
|
|
if (!$col instanceof Column\Select) { |
|
57
|
|
|
continue; |
|
58
|
|
|
} |
|
59
|
|
|
|
|
60
|
|
|
$colString = $col->getSelectPart1(); |
|
61
|
|
|
if ($col->getSelectPart2() != '') { |
|
62
|
|
|
$colString .= '.'.$col->getSelectPart2(); |
|
63
|
|
|
} |
|
64
|
|
|
$colString .= ' '.$col->getUniqueId(); |
|
65
|
|
|
|
|
66
|
|
|
$selectColumns[] = $colString; |
|
67
|
|
|
} |
|
68
|
|
|
$qb->resetDQLPart('select'); |
|
69
|
|
|
$qb->select($selectColumns); |
|
70
|
|
|
|
|
71
|
|
|
/* |
|
72
|
|
|
* Step 2) Apply sorting |
|
73
|
|
|
*/ |
|
74
|
|
|
if (!empty($this->getSortConditions())) { |
|
75
|
|
|
// Minimum one sort condition given -> so reset the default orderBy |
|
76
|
|
|
$qb->resetDQLPart('orderBy'); |
|
77
|
|
|
|
|
78
|
|
|
foreach ($this->getSortConditions() as $key => $sortCondition) { |
|
79
|
|
|
/* @var $col \ZfcDatagrid\Column\AbstractColumn */ |
|
80
|
|
|
$col = $sortCondition['column']; |
|
81
|
|
|
|
|
82
|
|
|
if (!$col instanceof Column\Select) { |
|
83
|
|
|
throw new \Exception('This column cannot be sorted: '.$col->getUniqueId()); |
|
84
|
|
|
} |
|
85
|
|
|
|
|
86
|
|
|
/* @var $col \ZfcDatagrid\Column\Select */ |
|
87
|
|
|
$colString = $col->getSelectPart1(); |
|
88
|
|
|
if ($col->getSelectPart2() != '') { |
|
89
|
|
|
$colString .= '.'.$col->getSelectPart2(); |
|
90
|
|
|
} |
|
91
|
|
|
|
|
92
|
|
|
if ($col->getType() instanceof Type\Number) { |
|
93
|
|
|
$qb->addSelect('ABS('.$colString.') sortColumn'.$key); |
|
94
|
|
|
$qb->add('orderBy', new Expr\OrderBy('sortColumn'.$key, $sortCondition['sortDirection']), true); |
|
|
|
|
|
|
95
|
|
|
} else { |
|
96
|
|
|
$qb->add('orderBy', new Expr\OrderBy($col->getUniqueId(), $sortCondition['sortDirection']), true); |
|
|
|
|
|
|
97
|
|
|
} |
|
98
|
|
|
} |
|
99
|
|
|
} |
|
100
|
|
|
|
|
101
|
|
|
/* |
|
102
|
|
|
* Step 3) Apply filters |
|
103
|
|
|
*/ |
|
104
|
|
|
$filterColumn = new Doctrine2\Filter($qb); |
|
105
|
|
|
foreach ($this->getFilters() as $filter) { |
|
106
|
|
|
/* @var $filter \ZfcDatagrid\Filter */ |
|
107
|
|
|
if ($filter->isColumnFilter() === true) { |
|
108
|
|
|
$filterColumn->applyFilter($filter); |
|
109
|
|
|
} |
|
110
|
|
|
} |
|
111
|
|
|
|
|
112
|
|
|
/* |
|
113
|
|
|
* Step 4) Pagination |
|
114
|
|
|
*/ |
|
115
|
|
|
$this->setPaginatorAdapter(new PaginatorAdapter($qb)); |
|
116
|
|
|
} |
|
117
|
|
|
} |
|
118
|
|
|
|
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.