Completed
Push — master ( 6ec6af...7fd515 )
by Jaap
14s
created

ORMRepository::find()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
crap 1
1
<?php
2
/**
3
 * Polder Knowledge / entityservice (https://polderknowledge.com)
4
 *
5
 * @link https://github.com/polderknowledge/entityservice for the canonical source repository
6
 * @copyright Copyright (c) 2016 Polder Knowledge (https://polderknowledge.com)
7
 * @license https://github.com/polderknowledge/entityservice/blob/master/LICENSE.md MIT
8
 */
9
10
namespace PolderKnowledge\EntityService\Repository\Doctrine;
11
12
use Doctrine\Common\Collections\Criteria;
13
use Doctrine\Common\Persistence\ObjectRepository;
14
use Doctrine\ORM\EntityManagerInterface;
15
use Doctrine\ORM\QueryBuilder;
16
use PolderKnowledge\EntityService\Repository\EntityRepositoryInterface;
17
use PolderKnowledge\EntityService\Repository\Feature\DeletableInterface;
18
use PolderKnowledge\EntityService\Repository\Feature\FlushableInterface;
19
use PolderKnowledge\EntityService\Repository\Feature\ReadableInterface;
20
use PolderKnowledge\EntityService\Repository\Feature\TransactionAwareInterface;
21
use PolderKnowledge\EntityService\Repository\Feature\WritableInterface;
22
use UnexpectedValueException;
23
24
/**
25
 * Class ORMRepository is a default implementation for a repository using doctrine orm.
26
 */
27
class ORMRepository implements
28
    EntityRepositoryInterface,
29
    DeletableInterface,
30
    FlushableInterface,
31
    ReadableInterface,
32
    TransactionAwareInterface,
33
    WritableInterface
34
{
35
    /**
36
     * The Doctrine ORM entity manager that is used to retrieve and store data.
37
     *
38
     * @var EntityManagerInterface
39
     */
40
    protected $entityManager;
41
42
    /**
43
     * The FQCN of the entity to work with.
44
     *
45
     * @var string
46
     */
47
    protected $entityName;
48
49
    /**
50
     * The Doctrine ORM repository that is used to retrieve and store data.
51
     *
52
     * @var ObjectRepository
53
     */
54
    protected $repository;
55
56
    /**
57
     * Initializes the self::$entityManager and self::$entityName
58
     *
59
     * @param EntityManagerInterface $entityManager The Doctrine ORM entity manager used to retrieve and store data.
60
     * @param string $entityName The FQCN of the entity to work with.
61
     */
62 48
    public function __construct(EntityManagerInterface $entityManager, $entityName)
63
    {
64 48
        $this->entityManager = $entityManager;
65 48
        $this->entityName = $entityName;
66 48
    }
67
68
    /**
69
     * Counts entities by a set of criteria.
70
     *
71
     * Optionally sorting and limiting details can be passed. An implementation may throw an UnexpectedValueException
72
     * if certain values of the sorting or limiting details are not supported.
73
     *
74
     * @param array|Criteria $criteria The criteria to find entities by.
75
     * @return int Returns the amount of entities that are found.
76
     * @throws \Doctrine\ORM\Query\QueryException
77
     * @throws \Doctrine\ORM\NoResultException
78
     * @throws \Doctrine\ORM\NonUniqueResultException
79
     * @throws UnexpectedValueException
80
     */
81 6
    public function countBy($criteria)
82
    {
83
        /* @var $queryBuilder \Doctrine\ORM\QueryBuilder */
84 6
        $queryBuilder = $this->getRepository()->createQueryBuilder('e');
85 6
        $queryBuilder->select('count(e)');
86
87 6
        if ($criteria instanceof Criteria) {
88 3
            $clonedCriteria = clone $criteria;
89 3
            $clonedCriteria->setFirstResult(null);
90 3
            $clonedCriteria->setMaxResults(null);
91
92 3
            $queryBuilder->addCriteria($clonedCriteria);
93 3
        } elseif (!empty($criteria)) {
94 3
            foreach ($criteria as $field => $value) {
95 3
                $queryBuilder->andWhere($queryBuilder->expr()->eq('e.' . $field, ':' . $field));
96 3
                $queryBuilder->setParameter(':' . $field, $value);
97
            }
98
        }
99
100 6
        return $queryBuilder->getQuery()->getSingleScalarResult();
101
    }
102
103
    /**
104
     * Deletes the given object
105
     *
106
     * @param object $entity The entity to delete.
107
     */
108 3
    public function delete($entity)
109
    {
110 3
        $this->entityManager->remove($entity);
111 3
    }
112
113
    /**
114
     * Removes objects by a set of criteria.
115
     *
116
     * @param array|Criteria $criteria
117
     * @return void
118
     * @throws \Doctrine\ORM\Query\QueryException
119
     */
120 3
    public function deleteBy($criteria)
121
    {
122 3
        $queryBuilder = $this->getQueryBuilder($criteria);
0 ignored issues
show
Bug introduced by
It seems like $criteria defined by parameter $criteria on line 120 can also be of type array; however, PolderKnowledge\EntitySe...tory::getQueryBuilder() does only seem to accept object<Doctrine\Common\Collections\Criteria>, 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...
123 3
        $queryBuilder->delete('e');
124 3
        $queryBuilder->getQuery()->execute();
125 3
    }
126
127
    /**
128
     * Tries to find an entity in the repository by the given identifier.
129
     *
130
     * @param mixed $id The id of the entity which can be any type of object.
131
     * @return object|null Returns the entity that matches the identifier or null when no instance is found.
132
     */
133 3
    public function find($id)
134
    {
135 3
        return $this->entityManager->find($this->entityName, $id);
136
    }
137
138
    /**
139
     * Tries to find all entities in the repository.
140
     *
141
     * @return object[] Returns an array with entities that are found.
142
     */
143 3
    public function findAll()
144
    {
145 3
        return $this->getRepository()->findAll();
146
    }
147
148
    /**
149
     * Tries to find entities by a set of criteria.
150
     *
151
     * Optionally sorting and limiting details can be passed. An implementation may throw an UnexpectedValueException
152
     * if certain values of the sorting or limiting details are not supported.
153
     *
154
     * @param array|Criteria $criteria The criteria to find entities by.
155
     * @return array Returns an array with found entities. Returns an empty array when no entities are found.
156
     * @throws \Doctrine\ORM\Query\QueryException
157
     * @throws UnexpectedValueException Thrown when provided parameters are not supported.
158
     */
159 6
    public function findBy($criteria)
160
    {
161 6 View Code Duplication
        if (!$criteria instanceof Criteria) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
162 3
            $criteriaParams = $criteria;
163
164 3
            $criteria = Criteria::create();
165 3
            foreach ($criteriaParams as $name => $value) {
166 3
                $criteria->andWhere(Criteria::expr()->eq($name, $value));
167
            }
168
        }
169
170 6
        $queryBuilder = $this->getQueryBuilder($criteria);
171
172 6
        return $queryBuilder->getQuery()->getResult();
173
    }
174
175
    /**
176
     * Tries to find a single entity by a set of criteria.
177
     *
178
     * @param array|Criteria $criteria The criteria. The criteria to find the entity by.
179
     * @return object|null Returns the entity that is found or null when no entity is found.
180
     * @throws \Doctrine\ORM\Query\QueryException
181
     * @throws \Doctrine\ORM\NonUniqueResultException
182
     */
183 6
    public function findOneBy($criteria)
184
    {
185 6 View Code Duplication
        if (!$criteria instanceof Criteria) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
186 3
            $criteriaParams = $criteria;
187
188 3
            $criteria = Criteria::create();
189 3
            foreach ($criteriaParams as $name => $value) {
190 3
                $criteria->andWhere(Criteria::expr()->eq($name, $value));
191
            }
192
        }
193
194 6
        $criteria->setFirstResult(0);
195 6
        $criteria->setMaxResults(1);
196
197 6
        $queryBuilder = $this->getQueryBuilder($criteria);
198
199 6
        return $queryBuilder->getQuery()->getOneOrNullResult();
200
    }
201
202
    /**
203
     * Creates a new query builder using the $criteria.
204
     *
205
     * @param Criteria $criteria
206
     * @return \Doctrine\ORM\QueryBuilder
207
     * @throws \Doctrine\ORM\Query\QueryException
208
     */
209 15
    protected function getQueryBuilder(Criteria $criteria)
210
    {
211
        /** @var QueryBuilder $queryBuilder */
212 15
        $queryBuilder = $this->getRepository()->createQueryBuilder('e');
213 15
        $queryBuilder->addCriteria($criteria);
214
215 15
        return $queryBuilder;
216
    }
217
218
    /**
219
     * Gets the Doctrine EntityManager.
220
     *
221
     * @return EntityManagerInterface
222
     */
223 3
    public function getEntityManager()
224
    {
225 3
        return $this->entityManager;
226
    }
227
228
    /**
229
     * Returns the doctrine repository.
230
     *
231
     * @return ObjectRepository
232
     */
233 24
    public function getRepository()
234
    {
235 24
        if ($this->repository === null) {
236 24
            $this->repository = $this->entityManager->getRepository($this->entityName);
237
        }
238
239 24
        return $this->repository;
240
    }
241
242
    /**
243
     * Will flush the given entity. If non given all queued entities will be flushed.
244
     *
245
     * @param object $entity The entity to flush.
246
     * @return void
247
     */
248 3
    public function flush($entity = null)
249
    {
250 3
        $this->entityManager->flush($entity);
0 ignored issues
show
Unused Code introduced by
The call to EntityManagerInterface::flush() has too many arguments starting with $entity.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
251 3
    }
252
253
    /**
254
     * Persist the given entity.
255
     *
256
     * @param object $entity The entity to persist.
257
     */
258 3
    public function persist($entity)
259
    {
260 3
        $this->entityManager->persist($entity);
261 3
    }
262
263
    /**
264
     * Starts a new transaction.
265
     *
266
     * @return void
267
     */
268 3
    public function beginTransaction()
269
    {
270 3
        $this->entityManager->beginTransaction();
271 3
    }
272
273
    /**
274
     * Commits a started transaction.
275
     *
276
     * @return void
277
     */
278 3
    public function commitTransaction()
279
    {
280 3
        $this->entityManager->commit();
281 3
    }
282
283
    /**
284
     * Rolls back a started transaction.
285
     *
286
     * @return void
287
     */
288 3
    public function rollbackTransaction()
289
    {
290 3
        $this->entityManager->rollback();
291 3
    }
292
}
293