1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Dontdrinkandroot\Repository; |
4
|
|
|
|
5
|
|
|
use Doctrine\ORM\EntityRepository; |
6
|
|
|
use Doctrine\ORM\Mapping\ClassMetadata; |
7
|
|
|
use Doctrine\ORM\QueryBuilder; |
8
|
|
|
use Dontdrinkandroot\Entity\EntityInterface; |
9
|
|
|
use Dontdrinkandroot\Pagination\PaginatedResult; |
10
|
|
|
use Dontdrinkandroot\Pagination\Pagination; |
11
|
|
|
|
12
|
|
|
class OrmEntityRepository extends EntityRepository implements EntityRepositoryInterface |
13
|
|
|
{ |
14
|
|
|
|
15
|
|
|
protected $transactionManager; |
16
|
|
|
|
17
|
|
|
public function __construct($entityManager, ClassMetadata $classMetadata) |
18
|
|
|
{ |
19
|
|
|
parent::__construct($entityManager, $classMetadata); |
20
|
|
|
$this->transactionManager = new TransactionManager($entityManager); |
21
|
|
|
} |
22
|
|
|
|
23
|
|
|
/** |
24
|
|
|
* {@inheritdoc} |
25
|
|
|
*/ |
26
|
|
View Code Duplication |
public function persist($entity, $flush = true) |
|
|
|
|
27
|
|
|
{ |
28
|
|
|
return $this->transactionManager->transactional( |
29
|
|
|
function () use ($entity, $flush) { |
30
|
|
|
$this->getEntityManager()->persist($entity); |
31
|
|
|
|
32
|
|
|
if ($flush) { |
33
|
|
|
$this->getEntityManager()->flush($entity); |
34
|
|
|
} |
35
|
|
|
|
36
|
|
|
return $entity; |
37
|
|
|
} |
38
|
|
|
); |
39
|
|
|
} |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* {@inheritdoc} |
43
|
|
|
*/ |
44
|
|
View Code Duplication |
public function merge($entity, $flush = false) |
|
|
|
|
45
|
|
|
{ |
46
|
|
|
return $this->transactionManager->transactional( |
47
|
|
|
function () use ($entity, $flush) { |
48
|
|
|
$entity = $this->getEntityManager()->merge($entity); |
|
|
|
|
49
|
|
|
|
50
|
|
|
if ($flush) { |
51
|
|
|
$this->getEntityManager()->flush($entity); |
52
|
|
|
} |
53
|
|
|
|
54
|
|
|
return $entity; |
55
|
|
|
} |
56
|
|
|
); |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
/** |
60
|
|
|
* {@inheritdoc} |
61
|
|
|
*/ |
62
|
|
|
public function flush($entity = null) |
63
|
|
|
{ |
64
|
|
|
$this->getEntityManager()->flush($entity); |
65
|
|
|
} |
66
|
|
|
|
67
|
|
|
/** |
68
|
|
|
* {@inheritdoc} |
69
|
|
|
*/ |
70
|
|
|
public function detach($entity) |
71
|
|
|
{ |
72
|
|
|
$this->getEntityManager()->detach($entity); |
73
|
|
|
} |
74
|
|
|
|
75
|
|
|
/** |
76
|
|
|
* {@inheritdoc} |
77
|
|
|
*/ |
78
|
|
View Code Duplication |
public function remove($entity, $flush = false) |
|
|
|
|
79
|
|
|
{ |
80
|
|
|
return $this->transactionManager->transactional( |
81
|
|
|
function () use ($entity, $flush) { |
82
|
|
|
$this->getEntityManager()->remove($entity); |
83
|
|
|
|
84
|
|
|
if ($flush) { |
85
|
|
|
$this->getEntityManager()->flush($entity); |
86
|
|
|
} |
87
|
|
|
} |
88
|
|
|
); |
89
|
|
|
} |
90
|
|
|
|
91
|
|
|
/** |
92
|
|
|
* {@inheritdoc} |
93
|
|
|
*/ |
94
|
|
View Code Duplication |
public function removeById($id, $flush = false) |
|
|
|
|
95
|
|
|
{ |
96
|
|
|
return $this->transactionManager->transactional( |
97
|
|
|
function () use ($id, $flush) { |
98
|
|
|
/** @var EntityInterface $entity */ |
99
|
|
|
$entity = $this->find($id); |
100
|
|
|
$this->remove($entity, $flush); |
101
|
|
|
} |
102
|
|
|
); |
103
|
|
|
} |
104
|
|
|
|
105
|
|
|
/** |
106
|
|
|
* {@inheritdoc} |
107
|
|
|
*/ |
108
|
|
|
public function removeAll($flush = false, $iterate = true) |
109
|
|
|
{ |
110
|
|
|
return $this->transactionManager->transactional( |
111
|
|
|
function () use ($flush, $iterate) { |
112
|
|
|
if ($iterate) { |
113
|
|
|
$this->removeAllByIterating(); |
114
|
|
|
} else { |
115
|
|
|
$this->removeAllByQuery(); |
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
if ($flush) { |
119
|
|
|
$this->getEntityManager()->flush(); |
120
|
|
|
} |
121
|
|
|
} |
122
|
|
|
); |
123
|
|
|
} |
124
|
|
|
|
125
|
|
|
/** |
126
|
|
|
* @return TransactionManager |
127
|
|
|
*/ |
128
|
|
|
public function getTransactionManager() |
129
|
|
|
{ |
130
|
|
|
return $this->transactionManager; |
131
|
|
|
} |
132
|
|
|
|
133
|
|
|
protected function removeAllByIterating($batchSize = 100) |
134
|
|
|
{ |
135
|
|
|
return $this->transactionManager->transactional( |
136
|
|
|
function () use ($batchSize) { |
137
|
|
|
$entities = $this->findAll(); |
138
|
|
|
$count = 0; |
139
|
|
|
foreach ($entities as $entity) { |
140
|
|
|
$this->remove($entity, false); |
141
|
|
|
$count++; |
142
|
|
|
if ($count >= $batchSize) { |
143
|
|
|
$this->getEntityManager()->flush(); |
144
|
|
|
$count = 0; |
145
|
|
|
} |
146
|
|
|
} |
147
|
|
|
} |
148
|
|
|
); |
149
|
|
|
} |
150
|
|
|
|
151
|
|
|
protected function removeAllByQuery() |
152
|
|
|
{ |
153
|
|
|
return $this->transactionManager->transactional( |
154
|
|
|
function () { |
155
|
|
|
$queryBuilder = $this->createQueryBuilder('entity'); |
156
|
|
|
$queryBuilder->delete(); |
157
|
|
|
$query = $queryBuilder->getQuery(); |
158
|
|
|
$query->execute(); |
159
|
|
|
} |
160
|
|
|
); |
161
|
|
|
} |
162
|
|
|
|
163
|
|
|
/** |
164
|
|
|
* {@inheritdoc} |
165
|
|
|
*/ |
166
|
|
|
public function findPaginatedBy($page = 1, $perPage = 10, array $criteria = [], array $orderBy = null) |
167
|
|
|
{ |
168
|
|
|
return $this->transactionManager->transactional( |
169
|
|
|
function () use ($page, $perPage, $criteria, $orderBy) { |
170
|
|
|
$persister = $this->getEntityManager()->getUnitOfWork()->getEntityPersister($this->_entityName); |
171
|
|
|
$total = $this->count($criteria); |
172
|
|
|
$results = $persister->loadAll($criteria, $orderBy, $perPage, ($page - 1) * $perPage); |
173
|
|
|
|
174
|
|
|
$pagination = new Pagination($page, $perPage, $total); |
175
|
|
|
$paginatedResult = new PaginatedResult($pagination, $results); |
176
|
|
|
|
177
|
|
|
return $paginatedResult; |
178
|
|
|
} |
179
|
|
|
); |
180
|
|
|
} |
181
|
|
|
|
182
|
|
|
/** |
183
|
|
|
* @param array $criteria |
184
|
|
|
* |
185
|
|
|
* @return int |
186
|
|
|
*/ |
187
|
|
|
private function count(array $criteria = []) |
188
|
|
|
{ |
189
|
|
|
|
190
|
|
|
$persister = $this->getEntityManager()->getUnitOfWork()->getEntityPersister($this->_entityName); |
191
|
|
|
|
192
|
|
|
if (method_exists($persister, 'count')) { |
193
|
|
|
return $persister->count($criteria); |
194
|
|
|
} |
195
|
|
|
|
196
|
|
|
$queryBuilder = $this->createBlankQueryBuilder(); |
197
|
|
|
$queryBuilder |
198
|
|
|
->select('COUNT(entity)') |
199
|
|
|
->from($this->getEntityName(), 'entity'); |
200
|
|
|
|
201
|
|
|
if (count($criteria) > 0) { |
202
|
|
|
$expr = $queryBuilder->expr(); |
203
|
|
|
foreach ($criteria as $field => $value) { |
204
|
|
|
$queryBuilder->andWhere($expr->eq('entity' . $field, $value)); |
205
|
|
|
} |
206
|
|
|
} |
207
|
|
|
|
208
|
|
|
return (int)$queryBuilder->getQuery()->getSingleScalarResult(); |
209
|
|
|
} |
210
|
|
|
|
211
|
|
|
/** |
212
|
|
|
* {@inheritdoc} |
213
|
|
|
*/ |
214
|
|
|
public function countAll() |
215
|
|
|
{ |
216
|
|
|
return $this->transactionManager->transactional( |
217
|
|
|
function () { |
218
|
|
|
$queryBuilder = $this->getEntityManager()->createQueryBuilder(); |
219
|
|
|
$queryBuilder |
220
|
|
|
->select('count(entity)') |
221
|
|
|
->from($this->getClassName(), 'entity'); |
222
|
|
|
|
223
|
|
|
$result = $queryBuilder->getQuery()->getSingleScalarResult(); |
224
|
|
|
|
225
|
|
|
return $result; |
226
|
|
|
} |
227
|
|
|
); |
228
|
|
|
} |
229
|
|
|
|
230
|
|
|
/** |
231
|
|
|
* @return QueryBuilder |
232
|
|
|
*/ |
233
|
|
|
protected function createBlankQueryBuilder() |
234
|
|
|
{ |
235
|
|
|
return $this->getEntityManager()->createQueryBuilder(); |
236
|
|
|
} |
237
|
|
|
} |
238
|
|
|
|
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.