BaseEntityRepository::save()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 2
1
<?php
2
3
/*
4
 * This file is part of the Veslo project <https://github.com/symfony-doge/veslo>.
5
 *
6
 * (C) 2019 Pavel Petrov <[email protected]>.
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 *
11
 * @license https://opensource.org/licenses/GPL-3.0 GPL-3.0
12
 */
13
14
declare(strict_types=1);
15
16
namespace Veslo\AppBundle\Entity\Repository;
17
18
use Doctrine\Common\Collections\Criteria;
19
use Doctrine\ORM\EntityManagerInterface;
20
use Doctrine\ORM\EntityRepository;
21
use Doctrine\ORM\OptimisticLockException;
22
use Doctrine\ORM\ORMException;
23
use Doctrine\ORM\Query;
24
use Doctrine\ORM\Query\QueryException;
25
use Doctrine\ORM\QueryBuilder;
26
use Veslo\AppBundle\Exception\EntityNotFoundException;
27
28
/**
29
 * Provides additional contract-based methods for standard ORM repository API.
30
 *
31
 * - Custom methods should use {getQueryBuilder} as starting point for query building.
32
 * - Custom methods should build Criteria object and pass it to {getQuery} before result evaluation.
33
 */
34
class BaseEntityRepository extends EntityRepository
35
{
36
    /**
37
     * Returns an entity by its identifier or throws exception
38
     *
39
     * @param mixed    $id          The identifier.
40
     * @param int|null $lockMode    One of the \Doctrine\DBAL\LockMode::* constants
41
     *                              or NULL if no specific lock mode should be used
42
     *                              during the search.
43
     * @param int|null $lockVersion The lock version.
44
     *
45
     * @return object The entity instance.
46
     *
47
     * @throws EntityNotFoundException
48
     */
49
    public function require($id, $lockMode = null, $lockVersion = null)
50
    {
51
        $entity = $this->find($id, $lockMode, $lockVersion);
52
53
        $classMetadata = $this->getClassMetadata();
54
55
        if (!$entity instanceof $classMetadata->name) {
56
            throw EntityNotFoundException::withClassAndId($classMetadata->name, $id);
57
        }
58
59
        return $entity;
60
    }
61
62
    /**
63
     * Calls related EntityManager to persist an entity and, optionally, flush
64
     *
65
     * @param object $entity  The instance to make managed and persistent.
66
     * @param bool   $isFlush Whenever EntityManager should perform flush
67
     *
68
     * @return void
69
     *
70
     * @throws OptimisticLockException If a version check on an entity that
71
     *         makes use of optimistic locking fails on flush.
72
     * @throws ORMException
73
     *
74
     * @see EntityManagerInterface::persist()
75
     * @see EntityManagerInterface::flush()
76
     * @see https://stackoverflow.com/a/20517528/3121455 (merge logic can be implemented if needed)
77
     */
78
    public function save(object $entity, bool $isFlush = true): void
79
    {
80
        $entityManager = $this->getEntityManager();
81
        $entityManager->persist($entity);
82
83
        if ($isFlush) {
84
            $entityManager->flush();
85
        }
86
    }
87
88
    /**
89
     * Returns base query instance for each request to the entity repository
90
     *
91
     * Using such kind of methods directly via third-party services in common cases is not recommended,
92
     * because it exposes encapsulated implementation of database layer to the other application domains
93
     * For example, in case of pagination, a custom method should be implemented
94
     * that gets a paginator service and returns result by contract.
95
     *
96
     * Custom methods should build Criteria object and pass it to this method before result evaluation.
97
     *
98
     * @param Criteria|null $criteria Criteria for filtering data which will be selected by query
99
     *
100
     * @return Query
101
     *
102
     * @throws QueryException
103
     */
104
    protected function getQuery(?Criteria $criteria = null): Query
105
    {
106
        $queryBuilder = $this->getQueryBuilder();
107
108
        if ($criteria instanceof Criteria) {
109
            $queryBuilder->addCriteria($criteria);
110
        }
111
112
        return $queryBuilder->getQuery();
113
    }
114
115
    /**
116
     * Returns base query builder for each request to the entity repository
117
     *
118
     * Custom methods should use this method as starting point for query building.
119
     *
120
     * @return QueryBuilder
121
     */
122
    protected function getQueryBuilder(): QueryBuilder
123
    {
124
        return $this->createQueryBuilder('e');
125
    }
126
}
127