Completed
Push — master ( 9dd58c...d31ca7 )
by Walter
02:40
created

ORMRepository::delete()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 3
cts 3
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 UnexpectedValueException
77
     */
78 6
    public function countBy($criteria)
79
    {
80
        /* @var $queryBuilder \Doctrine\ORM\QueryBuilder */
81 6
        $queryBuilder = $this->getRepository()->createQueryBuilder('e');
82 6
        $queryBuilder->select('count(e)');
83
84 6
        if ($criteria instanceof Criteria) {
85 3
            $clonedCriteria = clone $criteria;
86 3
            $clonedCriteria->setFirstResult(null);
87 3
            $clonedCriteria->setMaxResults(null);
88
89 3
            $queryBuilder->addCriteria($clonedCriteria);
90 6
        } elseif (!empty($criteria)) {
91 3
            foreach ($criteria as $field => $value) {
92 3
                $queryBuilder->andWhere($queryBuilder->expr()->eq('e.' . $field, ':' . $field));
93 3
                $queryBuilder->setParameter(':' . $field, $value);
94 3
            }
95 3
        }
96
97 6
        return $queryBuilder->getQuery()->getSingleScalarResult();
98
    }
99
100
    /**
101
     * Deletes the given object
102
     *
103
     * @param object $entity The entity to delete.
104
     */
105 3
    public function delete($entity)
106
    {
107 3
        $this->entityManager->remove($entity);
108 3
    }
109
110
    /**
111
     * Removes objects by a set of criteria.
112
     *
113
     * @param array|Criteria $criteria
114
     * @return int Returns the number of records that are deleted.
115
     */
116 3
    public function deleteBy($criteria)
117
    {
118 3
        $queryBuilder = $this->getQueryBuilder($criteria);
0 ignored issues
show
Bug introduced by
It seems like $criteria defined by parameter $criteria on line 116 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...
119 3
        $queryBuilder->delete('e');
120 3
        $queryBuilder->getQuery()->execute();
121 3
    }
122
123
    /**
124
     * Tries to find an entity in the repository by the given identifier.
125
     *
126
     * @param mixed $id The id of the entity which can be any type of object.
127
     * @return object|null Returns the entity that matches the identifier or null when no instance is found.
128
     */
129 3
    public function find($id)
130
    {
131 3
        return $this->entityManager->find($this->entityName, $id);
132
    }
133
134
    /**
135
     * Tries to find all entities in the repository.
136
     *
137
     * @return object[] Returns an array with entities that are found.
138
     */
139 3
    public function findAll()
140
    {
141 3
        return $this->getRepository()->findAll();
142
    }
143
144
    /**
145
     * Tries to find entities by a set of criteria.
146
     *
147
     * Optionally sorting and limiting details can be passed. An implementation may throw an UnexpectedValueException
148
     * if certain values of the sorting or limiting details are not supported.
149
     *
150
     * @param array|Criteria $criteria The criteria to find entities by.
151
     * @return array Returns an array with found entities. Returns an empty array when no entities are found.
152
     * @throws UnexpectedValueException Thrown when provided parameters are not supported.
153
     */
154 6
    public function findBy($criteria)
155
    {
156 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...
157 3
            $criteriaParams = $criteria;
158
159 3
            $criteria = Criteria::create();
160 3
            foreach ($criteriaParams as $name => $value) {
161 3
                $criteria->andWhere(Criteria::expr()->eq($name, $value));
162 3
            }
163 3
        }
164
165 6
        $queryBuilder = $this->getQueryBuilder($criteria);
166
167 6
        return $queryBuilder->getQuery()->getResult();
168
    }
169
170
    /**
171
     * Tries to find a single entity by a set of criteria.
172
     *
173
     * @param array|Criteria $criteria The criteria. The criteria to find the entity by.
174
     * @return object|null Returns the entity that is found or null when no entity is found.
175
     */
176 6
    public function findOneBy($criteria)
177
    {
178 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...
179 3
            $criteriaParams = $criteria;
180
181 3
            $criteria = Criteria::create();
182 3
            foreach ($criteriaParams as $name => $value) {
183 3
                $criteria->andWhere($criteria->expr()->eq($name, $value));
184 3
            }
185 3
        }
186
187 6
        $criteria->setFirstResult(0);
188 6
        $criteria->setMaxResults(1);
189
190 6
        $queryBuilder = $this->getQueryBuilder($criteria);
191
192 6
        return $queryBuilder->getQuery()->getOneOrNullResult();
193
    }
194
195
    /**
196
     * Creates a new query builder using the $criteria.
197
     *
198
     * @param Criteria $criteria
199
     * @return \Doctrine\ORM\QueryBuilder
200
     */
201 15
    protected function getQueryBuilder(Criteria $criteria)
202
    {
203
        /** @var QueryBuilder $queryBuilder */
204 15
        $queryBuilder = $this->getRepository()->createQueryBuilder('e');
205 15
        $queryBuilder->addCriteria($criteria);
206
207 15
        return $queryBuilder;
208
    }
209
210
    /**
211
     * Gets the Doctrine EntityManager.
212
     *
213
     * @return EntityManagerInterface
214
     */
215 3
    public function getEntityManager()
216
    {
217 3
        return $this->entityManager;
218
    }
219
220
    /**
221
     * Returns the doctrine repository.
222
     *
223
     * @return ObjectRepository
224
     */
225 24
    public function getRepository()
226
    {
227 24
        if ($this->repository === null) {
228 24
            $this->repository = $this->entityManager->getRepository($this->entityName);
229 24
        }
230
231 24
        return $this->repository;
232
    }
233
234
    /**
235
     * Will flush the given entity. If non given all queued entities will be flushed.
236
     *
237
     * @param object $entity The entity to flush.
238
     * @return void
239
     */
240 3
    public function flush($entity = null)
241
    {
242 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...
243 3
    }
244
245
    /**
246
     * Persist the given entity.
247
     *
248
     * @param object $entity The entity to persist.
249
     */
250 3
    public function persist($entity)
251
    {
252 3
        $this->entityManager->persist($entity);
253 3
    }
254
255
    /**
256
     * Starts a new transaction.
257
     *
258
     * @return void
259
     */
260 3
    public function beginTransaction()
261
    {
262 3
        $this->entityManager->beginTransaction();
263 3
    }
264
265
    /**
266
     * Commits a started transaction.
267
     *
268
     * @return void
269
     */
270 3
    public function commitTransaction()
271
    {
272 3
        $this->entityManager->commit();
273 3
    }
274
275
    /**
276
     * Rolls back a started transaction.
277
     *
278
     * @return void
279
     */
280 3
    public function rollbackTransaction()
281
    {
282 3
        $this->entityManager->rollback();
283 3
    }
284
}
285