1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace DoS\ResourceBundle\Doctrine\ORM; |
4
|
|
|
|
5
|
|
|
use Doctrine\ORM\Mapping\ClassMetadataInfo; |
6
|
|
|
use Doctrine\ORM\QueryBuilder; |
7
|
|
|
use DoS\ResourceBundle\Doctrine\RepositoryInterface; |
8
|
|
|
use Sylius\Bundle\ResourceBundle\Doctrine\ORM\EntityRepository as BaseEntityRepository; |
9
|
|
|
use Symfony\Component\HttpKernel\Exception\NotAcceptableHttpException; |
10
|
|
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; |
11
|
|
|
|
12
|
|
|
class EntityRepository extends BaseEntityRepository implements RepositoryInterface |
13
|
|
|
{ |
14
|
|
|
/** |
15
|
|
|
* @return \Doctrine\ORM\Query\Expr |
16
|
|
|
*/ |
17
|
|
|
public function expr() |
18
|
|
|
{ |
19
|
|
|
return $this->_em->getExpressionBuilder(); |
20
|
|
|
} |
21
|
|
|
|
22
|
|
|
/** |
23
|
|
|
* @return \Doctrine\ORM\EntityManager |
24
|
|
|
*/ |
25
|
|
|
public function getManager() |
26
|
|
|
{ |
27
|
|
|
return $this->_em; |
28
|
|
|
} |
29
|
|
|
|
30
|
|
|
/** |
31
|
|
|
* @return string |
32
|
|
|
*/ |
33
|
|
|
public function getEntityName() |
34
|
|
|
{ |
35
|
|
|
return $this->_entityName; |
36
|
|
|
} |
37
|
|
|
|
38
|
|
|
/** |
39
|
|
|
* @deprecated Remove all resource creation logics to ResourceFactory. |
40
|
|
|
*/ |
41
|
|
|
public function createNew() |
42
|
|
|
{ |
43
|
|
|
$className = $this->getClassName(); |
44
|
|
|
|
45
|
|
|
return new $className(); |
46
|
|
|
} |
47
|
|
|
|
48
|
|
|
/** |
49
|
|
|
* @param QueryBuilder $queryBuilder |
50
|
|
|
* @param $value |
51
|
|
|
* @param $properties |
52
|
|
|
*/ |
53
|
|
|
protected function applySearchCriteria(QueryBuilder $queryBuilder, $value, $properties) |
54
|
|
|
{ |
55
|
|
|
if (empty($value) || empty($properties)) { |
56
|
|
|
return; |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
// TODO: use SearchBundle |
60
|
|
|
$xor = array(); |
61
|
|
|
$properties = is_array($properties) ? $properties : array($properties); |
62
|
|
|
|
63
|
|
|
foreach($properties as $field) { |
64
|
|
|
if ($assoc = $this->addAssociation($queryBuilder, $field, false)) { |
65
|
|
|
$fieldPath = sprintf('%s.%s', $assoc[0], $holder = $assoc[1]); |
66
|
|
|
} else { |
67
|
|
|
$fieldPath = $this->getPropertyName($holder = $field); |
68
|
|
|
} |
69
|
|
|
|
70
|
|
|
$xor[] = $this->expr()->like(sprintf('LOWER(%s)', $fieldPath), sprintf(':%s', $holder)); |
71
|
|
|
$queryBuilder->setParameter($holder, '%'.strtolower($value).'%'); |
72
|
|
|
} |
73
|
|
|
|
74
|
|
|
$queryBuilder->andWhere(call_user_func_array(array($this->expr(), 'orX'), $xor)); |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* {@inheritdoc} |
79
|
|
|
*/ |
80
|
|
|
protected function applyCriteria(QueryBuilder $queryBuilder, array $criteria = array()) |
81
|
|
|
{ |
82
|
|
|
// TODO: can be config `_search_` key |
83
|
|
|
if (array_key_exists('_search_', $criteria)) { |
84
|
|
|
$search = $criteria['_search_']; |
85
|
|
|
unset($criteria['_search_']); |
86
|
|
|
|
87
|
|
|
$this->applySearchCriteria($queryBuilder, $search['value'], $search['properties']); |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
parent::applyCriteria($queryBuilder, $criteria); |
91
|
|
|
} |
92
|
|
|
|
93
|
|
|
/** |
94
|
|
|
* {@inheritdoc} |
95
|
|
|
*/ |
96
|
|
View Code Duplication |
public function createUserList(array $criteria = null, array $orderBy = null) |
|
|
|
|
97
|
|
|
{ |
98
|
|
|
if (empty($criteria['user'])) { |
99
|
|
|
throw new NotFoundHttpException('Not found user.'); |
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
return parent::createPaginator($criteria, $orderBy); |
|
|
|
|
103
|
|
|
} |
104
|
|
|
|
105
|
|
|
/** |
106
|
|
|
* {@inheritdoc} |
107
|
|
|
*/ |
108
|
|
View Code Duplication |
public function createUserPaginator(array $criteria = null, array $orderBy = null) |
|
|
|
|
109
|
|
|
{ |
110
|
|
|
if (empty($criteria['user'])) { |
111
|
|
|
throw new NotFoundHttpException('Not found user.'); |
112
|
|
|
} |
113
|
|
|
|
114
|
|
|
return parent::createPaginator($criteria, $orderBy); |
|
|
|
|
115
|
|
|
} |
116
|
|
|
|
117
|
|
|
/** |
118
|
|
|
* @param QueryBuilder $queryBuilder |
119
|
|
|
* @param array $sorting |
120
|
|
|
*/ |
121
|
|
|
protected function applySorting(QueryBuilder $queryBuilder, array $sorting = null) |
122
|
|
|
{ |
123
|
|
|
if (null === $sorting) { |
124
|
|
|
return; |
125
|
|
|
} |
126
|
|
|
|
127
|
|
|
foreach ($sorting as $property => $order) { |
128
|
|
|
if (!empty($order) && !$this->addAssociateOrder($queryBuilder, $property, $order)) { |
129
|
|
|
$queryBuilder->addOrderBy($this->getPropertyName($property), $order); |
130
|
|
|
} |
131
|
|
|
} |
132
|
|
|
} |
133
|
|
|
|
134
|
|
|
/** |
135
|
|
|
* @param QueryBuilder $queryBuilder |
136
|
|
|
* @param $propertyPath |
137
|
|
|
* @param $usingHidden |
138
|
|
|
* |
139
|
|
|
* @return bool|string |
140
|
|
|
*/ |
141
|
|
|
private function addAssociation(QueryBuilder $queryBuilder, $propertyPath, $usingHidden = true) |
142
|
|
|
{ |
143
|
|
|
// simple join |
144
|
|
|
if (false !== strpos($propertyPath, '.')) { |
145
|
|
|
// single level |
146
|
|
|
list($key, $field) = explode('.', $propertyPath); |
147
|
|
|
|
148
|
|
|
if ($key !== $this->getAlias()) { |
149
|
|
|
$associations = $this->getClassMetadata()->getAssociationMappings(); |
150
|
|
|
|
151
|
|
|
if ($associations[$key]['type'] === ClassMetadataInfo::MANY_TO_MANY) { |
152
|
|
|
throw new NotAcceptableHttpException('Cannot order associtated Many-To-Many object type.'); |
153
|
|
|
} |
154
|
|
|
|
155
|
|
|
$join = $this->getPropertyName($key); |
156
|
|
|
$alias = '_'.$key; |
157
|
|
|
$hidden = '__'.$key; |
158
|
|
|
|
159
|
|
|
$queryBuilder |
160
|
|
|
->join($join, $alias) |
161
|
|
|
; |
162
|
|
|
|
163
|
|
|
if ($usingHidden) { |
164
|
|
|
$queryBuilder |
165
|
|
|
->addSelect(sprintf('%s.%s AS HIDDEN %s', $alias, $field, $hidden)) |
166
|
|
|
; |
167
|
|
|
} |
168
|
|
|
|
169
|
|
|
return array($alias, $field , $hidden); |
170
|
|
|
} |
171
|
|
|
} |
172
|
|
|
|
173
|
|
|
return false; |
174
|
|
|
} |
175
|
|
|
|
176
|
|
|
/** |
177
|
|
|
* @param QueryBuilder $queryBuilder |
178
|
|
|
* @param string $name |
179
|
|
|
* @param string $order |
180
|
|
|
* |
181
|
|
|
* @return bool|string |
182
|
|
|
*/ |
183
|
|
|
private function addAssociateOrder(QueryBuilder $queryBuilder, $name, $order) |
184
|
|
|
{ |
185
|
|
|
if ($hidden = $this->addAssociation($queryBuilder, $name)) { |
186
|
|
|
$queryBuilder->orderBy($name, $order); |
187
|
|
|
return $hidden; |
188
|
|
|
} |
189
|
|
|
|
190
|
|
|
return false; |
191
|
|
|
} |
192
|
|
|
|
193
|
|
|
public function bulkUpdate(array $paths, array $criteria = array()) |
194
|
|
|
{ |
195
|
|
|
$queryBuilder = $this->_em->createQueryBuilder() |
196
|
|
|
->update($this->_entityName, $this->getAlias()) |
197
|
|
|
; |
198
|
|
|
|
199
|
|
|
$parameters = array(); |
200
|
|
|
|
201
|
|
|
foreach ($paths as $path => $value) { |
202
|
|
|
$queryBuilder->set($this->getPropertyName($path), ':'.$path); |
203
|
|
|
$parameters[$path] = $value; |
204
|
|
|
} |
205
|
|
|
|
206
|
|
|
foreach ($criteria as $key => $value) { |
207
|
|
|
$parameters[$key] = $value; |
208
|
|
|
} |
209
|
|
|
|
210
|
|
|
$this->applyCriteria($queryBuilder, $criteria); |
211
|
|
|
|
212
|
|
|
return $this->_em |
213
|
|
|
->createQuery($queryBuilder->getDQL()) |
214
|
|
|
->execute($parameters) |
215
|
|
|
; |
216
|
|
|
} |
217
|
|
|
} |
218
|
|
|
|
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.