1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Dontdrinkandroot\Repository; |
4
|
|
|
|
5
|
|
|
use Doctrine\Common\Persistence\ManagerRegistry; |
6
|
|
|
use Doctrine\ORM\EntityManagerInterface; |
7
|
|
|
use Doctrine\ORM\EntityRepository; |
8
|
|
|
use Doctrine\ORM\Mapping\ClassMetadata; |
9
|
|
|
use Doctrine\ORM\QueryBuilder; |
10
|
|
|
use Doctrine\ORM\Tools\Pagination\Paginator; |
11
|
|
|
use Dontdrinkandroot\Entity\EntityInterface; |
12
|
|
|
|
13
|
|
|
/** |
14
|
|
|
* @author Philip Washington Sorst <[email protected]> |
15
|
|
|
*/ |
16
|
|
|
class OrmEntityRepository extends EntityRepository implements EntityRepositoryInterface |
17
|
|
|
{ |
18
|
|
|
protected $transactionManager; |
19
|
|
|
|
20
|
|
|
/** |
21
|
|
|
* OrmEntityRepository constructor. |
22
|
|
|
* |
23
|
|
|
* @param ManagerRegistry|EntityManagerInterface $registryOrManager |
24
|
|
|
* @param string|ClassMetadata $classNameOrMetadata |
25
|
|
|
* @param TransactionManager|null $transactionManager |
26
|
|
|
*/ |
27
|
20 |
|
public function __construct( |
28
|
|
|
$registryOrManager, |
29
|
|
|
$classNameOrMetadata, |
30
|
|
|
?TransactionManager $transactionManager = null |
31
|
|
|
) { |
32
|
20 |
|
if ($registryOrManager instanceof ManagerRegistry) { |
33
|
|
|
$manager = $registryOrManager->getManagerForClass($classNameOrMetadata); |
|
|
|
|
34
|
|
|
} else { |
35
|
20 |
|
$manager = $registryOrManager; |
36
|
|
|
} |
37
|
|
|
|
38
|
20 |
|
if ($classNameOrMetadata instanceof ClassMetadata) { |
39
|
20 |
|
$classMetadata = $classNameOrMetadata; |
40
|
|
|
} else { |
41
|
|
|
$classMetadata = $manager->getClassMetadata($classNameOrMetadata); |
42
|
|
|
} |
43
|
|
|
|
44
|
20 |
|
parent::__construct($manager, $classMetadata); |
|
|
|
|
45
|
|
|
|
46
|
20 |
|
if (null === $transactionManager) { |
47
|
20 |
|
$this->transactionManager = new TransactionManager($manager); |
|
|
|
|
48
|
|
|
} else { |
49
|
|
|
$this->transactionManager = $transactionManager; |
50
|
|
|
} |
51
|
20 |
|
} |
52
|
|
|
|
53
|
|
|
/** |
54
|
|
|
* {@inheritdoc} |
55
|
|
|
*/ |
56
|
6 |
|
public function persist($entity, $flush = true) |
57
|
|
|
{ |
58
|
6 |
|
return $this->transactionManager->transactional( |
59
|
3 |
|
function () use ($entity, $flush) { |
60
|
6 |
|
$this->getEntityManager()->persist($entity); |
61
|
|
|
|
62
|
6 |
|
if ($flush) { |
63
|
6 |
|
$this->getEntityManager()->flush($entity); |
64
|
|
|
} |
65
|
|
|
|
66
|
6 |
|
return $entity; |
67
|
6 |
|
} |
68
|
|
|
); |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
/** |
72
|
|
|
* {@inheritdoc} |
73
|
|
|
*/ |
74
|
4 |
|
public function merge($entity, $flush = false) |
75
|
|
|
{ |
76
|
4 |
|
return $this->transactionManager->transactional( |
77
|
2 |
|
function () use ($entity, $flush) { |
78
|
4 |
|
$entity = $this->getEntityManager()->merge($entity); |
|
|
|
|
79
|
|
|
|
80
|
4 |
|
if ($flush) { |
81
|
|
|
$this->getEntityManager()->flush($entity); |
82
|
|
|
} |
83
|
|
|
|
84
|
4 |
|
return $entity; |
85
|
4 |
|
} |
86
|
|
|
); |
87
|
|
|
} |
88
|
|
|
|
89
|
|
|
/** |
90
|
|
|
* {@inheritdoc} |
91
|
|
|
*/ |
92
|
4 |
|
public function flush($entity = null) |
93
|
|
|
{ |
94
|
4 |
|
$this->getEntityManager()->flush($entity); |
95
|
4 |
|
} |
96
|
|
|
|
97
|
|
|
/** |
98
|
|
|
* {@inheritdoc} |
99
|
|
|
*/ |
100
|
|
|
public function detach($entity) |
101
|
|
|
{ |
102
|
|
|
$this->getEntityManager()->detach($entity); |
103
|
|
|
} |
104
|
|
|
|
105
|
|
|
/** |
106
|
|
|
* {@inheritdoc} |
107
|
|
|
*/ |
108
|
6 |
|
public function remove($entity, $flush = false) |
109
|
|
|
{ |
110
|
6 |
|
return $this->transactionManager->transactional( |
111
|
3 |
|
function () use ($entity, $flush) { |
112
|
6 |
|
$this->getEntityManager()->remove($entity); |
113
|
|
|
|
114
|
6 |
|
if ($flush) { |
115
|
|
|
$this->getEntityManager()->flush($entity); |
116
|
|
|
} |
117
|
6 |
|
} |
118
|
|
|
); |
119
|
|
|
} |
120
|
|
|
|
121
|
|
|
/** |
122
|
|
|
* {@inheritdoc} |
123
|
|
|
*/ |
124
|
2 |
|
public function removeById($id, $flush = false) |
125
|
|
|
{ |
126
|
2 |
|
return $this->transactionManager->transactional( |
127
|
1 |
|
function () use ($id, $flush) { |
128
|
|
|
/** @var EntityInterface $entity */ |
129
|
2 |
|
$entity = $this->find($id); |
130
|
2 |
|
$this->remove($entity, $flush); |
131
|
2 |
|
} |
132
|
|
|
); |
133
|
|
|
} |
134
|
|
|
|
135
|
|
|
/** |
136
|
|
|
* {@inheritdoc} |
137
|
|
|
*/ |
138
|
4 |
|
public function removeAll($flush = false, $iterate = true) |
139
|
|
|
{ |
140
|
4 |
|
return $this->transactionManager->transactional( |
141
|
2 |
|
function () use ($flush, $iterate) { |
142
|
4 |
|
if ($iterate) { |
143
|
2 |
|
$this->removeAllByIterating(); |
144
|
|
|
} else { |
145
|
2 |
|
$this->removeAllByQuery(); |
146
|
|
|
} |
147
|
|
|
|
148
|
4 |
|
if ($flush) { |
149
|
4 |
|
$this->getEntityManager()->flush(); |
150
|
|
|
} |
151
|
4 |
|
} |
152
|
|
|
); |
153
|
|
|
} |
154
|
|
|
|
155
|
|
|
/** |
156
|
|
|
* {@inheritdoc} |
157
|
|
|
*/ |
158
|
|
|
public function getTransactionManager() |
159
|
|
|
{ |
160
|
|
|
return $this->transactionManager; |
161
|
|
|
} |
162
|
|
|
|
163
|
2 |
|
protected function removeAllByIterating($batchSize = 100) |
164
|
|
|
{ |
165
|
2 |
|
return $this->transactionManager->transactional( |
166
|
1 |
|
function () use ($batchSize) { |
167
|
2 |
|
$entities = $this->findAll(); |
168
|
2 |
|
$count = 0; |
169
|
2 |
|
foreach ($entities as $entity) { |
170
|
2 |
|
$this->remove($entity, false); |
171
|
2 |
|
$count++; |
172
|
2 |
|
if ($count >= $batchSize) { |
173
|
|
|
$this->getEntityManager()->flush(); |
174
|
2 |
|
$count = 0; |
175
|
|
|
} |
176
|
|
|
} |
177
|
2 |
|
} |
178
|
|
|
); |
179
|
|
|
} |
180
|
|
|
|
181
|
2 |
|
protected function removeAllByQuery() |
182
|
|
|
{ |
183
|
2 |
|
return $this->transactionManager->transactional( |
184
|
1 |
|
function () { |
185
|
2 |
|
$queryBuilder = $this->createQueryBuilder('entity'); |
186
|
2 |
|
$queryBuilder->delete(); |
187
|
2 |
|
$query = $queryBuilder->getQuery(); |
188
|
2 |
|
$query->execute(); |
189
|
2 |
|
} |
190
|
|
|
); |
191
|
|
|
} |
192
|
|
|
|
193
|
|
|
/** |
194
|
|
|
* {@inheritdoc} |
195
|
|
|
*/ |
196
|
2 |
|
public function findPaginatedBy($page = 1, $perPage = 10, array $criteria = [], array $orderBy = null) |
197
|
|
|
{ |
198
|
2 |
|
return $this->transactionManager->transactional( |
199
|
1 |
|
function () use ($page, $perPage, $criteria, $orderBy) { |
200
|
|
|
|
201
|
2 |
|
$queryBuilder = $this->createQueryBuilder('entity'); |
202
|
|
|
|
203
|
2 |
|
foreach ($criteria as $field => $value) { |
204
|
2 |
|
$queryBuilder->andWhere('entity.' . $field . ' = :' . $field); |
205
|
2 |
|
$queryBuilder->setParameter($field, $value); |
206
|
|
|
} |
207
|
|
|
|
208
|
2 |
|
if (null !== $orderBy) { |
209
|
2 |
|
foreach ($orderBy as $field => $order) { |
210
|
2 |
|
$queryBuilder->addOrderBy('entity.' . $field, $order); |
211
|
|
|
} |
212
|
|
|
} |
213
|
|
|
|
214
|
2 |
|
$queryBuilder->setFirstResult(($page - 1) * $perPage); |
215
|
2 |
|
$queryBuilder->setMaxResults($perPage); |
216
|
|
|
|
217
|
2 |
|
return new Paginator($queryBuilder); |
218
|
2 |
|
} |
219
|
|
|
); |
220
|
|
|
} |
221
|
|
|
|
222
|
|
|
/** |
223
|
|
|
* {@inheritdoc} |
224
|
|
|
*/ |
225
|
2 |
|
public function countAll() |
226
|
|
|
{ |
227
|
2 |
|
return $this->transactionManager->transactional( |
228
|
1 |
|
function () { |
229
|
2 |
|
$queryBuilder = $this->getEntityManager()->createQueryBuilder(); |
230
|
|
|
$queryBuilder |
231
|
2 |
|
->select('count(entity)') |
232
|
2 |
|
->from($this->getClassName(), 'entity'); |
233
|
|
|
|
234
|
2 |
|
$result = $queryBuilder->getQuery()->getSingleScalarResult(); |
235
|
|
|
|
236
|
2 |
|
return $result; |
237
|
2 |
|
} |
238
|
|
|
); |
239
|
|
|
} |
240
|
|
|
|
241
|
|
|
/** |
242
|
|
|
* @return QueryBuilder |
243
|
|
|
*/ |
244
|
|
|
protected function createBlankQueryBuilder() |
245
|
|
|
{ |
246
|
|
|
return $this->getEntityManager()->createQueryBuilder(); |
247
|
|
|
} |
248
|
|
|
} |
249
|
|
|
|
This check looks at variables that have been passed in as parameters and are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.