Completed
Push — master ( 7f186d...ef28ef )
by Philip
03:23
created

OrmEntityRepository::persist()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 14
Code Lines 7

Duplication

Lines 14
Ratio 100 %

Importance

Changes 0
Metric Value
dl 14
loc 14
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 7
nc 1
nop 2
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)
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...
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)
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...
45
    {
46
        return $this->transactionManager->transactional(
47
            function () use ($entity, $flush) {
48
                $entity = $this->getEntityManager()->merge($entity);
0 ignored issues
show
Bug introduced by
Consider using a different name than the imported variable $entity, or did you forget to import by reference?

It seems like you are assigning to a variable which was imported through a use statement which was not imported by reference.

For clarity, we suggest to use a different name or import by reference depending on whether you would like to have the change visibile in outer-scope.

Change not visible in outer-scope

$x = 1;
$callable = function() use ($x) {
    $x = 2; // Not visible in outer scope. If you would like this, how
            // about using a different variable name than $x?
};

$callable();
var_dump($x); // integer(1)

Change visible in outer-scope

$x = 1;
$callable = function() use (&$x) {
    $x = 2;
};

$callable();
var_dump($x); // integer(2)
Loading history...
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)
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...
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)
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...
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