Completed
Push — master ( 7455ea...9225c9 )
by Philip
04:22
created

OrmEntityRepository   A

Complexity

Total Complexity 27

Size/Duplication

Total Lines 233
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Test Coverage

Coverage 87.38%

Importance

Changes 0
Metric Value
wmc 27
lcom 1
cbo 7
dl 0
loc 233
ccs 90
cts 103
cp 0.8738
rs 10
c 0
b 0
f 0

14 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 25 4
A persist() 0 14 2
A merge() 0 14 2
A flush() 0 4 1
A detach() 0 4 1
A remove() 0 12 2
A removeById() 0 10 1
A removeAll() 0 16 3
A getTransactionManager() 0 4 1
A removeAllByIterating() 0 17 3
A removeAllByQuery() 0 11 1
A findPaginatedBy() 0 25 4
A countAll() 0 15 1
A createBlankQueryBuilder() 0 4 1
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);
0 ignored issues
show
Bug introduced by
It seems like $classNameOrMetadata defined by parameter $classNameOrMetadata on line 29 can also be of type object<Doctrine\ORM\Mapping\ClassMetadata>; however, Doctrine\Common\Persiste...y::getManagerForClass() does only seem to accept string, maybe add an additional type check?

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.

Loading history...
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);
0 ignored issues
show
Documentation introduced by
$manager is of type object<Doctrine\Common\P...nce\ObjectManager>|null, but the function expects a object<Doctrine\ORM\EntityManagerInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
45
46 20
        if (null === $transactionManager) {
47 20
            $this->transactionManager = new TransactionManager($manager);
0 ignored issues
show
Documentation introduced by
$manager is of type object<Doctrine\Common\P...nce\ObjectManager>|null, but the function expects a object<Doctrine\ORM\EntityManagerInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
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);
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...
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