Completed
Push — master ( 27c5e0...9ca3e9 )
by Philip
01:39
created

DoctrineCrudService::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
c 0
b 0
f 0
rs 9.4285
cc 1
eloc 3
nc 1
nop 2
1
<?php
2
3
namespace Dontdrinkandroot\Service;
4
5
use Doctrine\ORM\EntityManager;
6
use Doctrine\ORM\EntityRepository;
7
use Doctrine\ORM\Mapping;
8
use Doctrine\ORM\Mapping\ClassMetadata;
9
use Doctrine\ORM\Tools\Pagination\Paginator;
10
use Dontdrinkandroot\Repository\TransactionManager;
11
use Psr\Log\LoggerInterface;
12
use Psr\Log\NullLogger;
13
use Symfony\Component\PropertyAccess\PropertyAccess;
14
15
class DoctrineCrudService extends EntityRepository implements CrudServiceInterface
16
{
17
    /**
18
     * @var  LoggerInterface
19
     */
20
    private $logger;
21
22
    /**
23
     * @var TransactionManager
24
     */
25
    private $transactionManager;
26
27
    public function __construct(EntityManager $em, Mapping\ClassMetadata $class)
28
    {
29
        parent::__construct($em, $class);
30
        $this->transactionManager = new TransactionManager($em);
31
    }
32
33
    /**
34
     * {@inheritdoc}
35
     */
36
    public function findAllPaginated(int $page = 1, int $perPage = 50): Paginator
37
    {
38
        $queryBuilder = $this->createQueryBuilder('entity');
39
        $queryBuilder->setFirstResult(($page - 1) * $perPage);
40
        $queryBuilder->setMaxResults($perPage);
41
42
        return new Paginator($queryBuilder);
43
    }
44
45
    /**
46
     * {@inheritdoc}
47
     */
48
    public function create($entity)
49
    {
50
        $this->getEntityManager()->persist($entity);
51
        $this->getEntityManager()->flush($entity);
52
53
        return $entity;
54
    }
55
56
    /**
57
     * {@inheritdoc}
58
     */
59
    public function update($entity)
60
    {
61
        $this->getEntityManager()->flush($entity);
62
63
        return $entity;
64
    }
65
66
    /**
67
     * {@inheritdoc}
68
     */
69
    public function remove($entity)
70
    {
71
        $this->getEntityManager()->remove($entity);
72
        $this->getEntityManager()->flush($entity);
73
    }
74
75
    /**
76
     * {@inheritdoc}
77
     */
78
    public function findAssociationPaginated($entity, string $fieldName, int $page = 1, $perPage = 50)
79
    {
80
        $classMetadata = $this->getEntityManager()->getClassMetadata(get_class($entity));
81
        $targetClass = $classMetadata->getAssociationTargetClass($fieldName);
82
83
        $inverseFieldName = $this->getInverseFieldName($fieldName, $classMetadata);
84
85
        $queryBuilder = $this->getEntityManager()->createQueryBuilder();
86
        $queryBuilder->select('association');
87
        $queryBuilder->from($targetClass, 'association');
88
        $queryBuilder->join('association.' . $inverseFieldName, 'entity');
89
        $queryBuilder->where('entity = :entity');
90
        $queryBuilder->setParameter('entity', $entity);
91
92
        $queryBuilder->setFirstResult(($page - 1) * $perPage);
93
        $queryBuilder->setMaxResults($perPage);
94
95
        return new Paginator($queryBuilder);
96
    }
97
98
    /**
99
     * @param object     $entity
100
     * @param string     $fieldName
101
     * @param string|int $id
102
     */
103
    public function addToCollection($entity, string $fieldName, $id)
104
    {
105
        $classMetadata = $this->getEntityManager()->getClassMetadata(get_class($entity));
106
        $targetClass = $classMetadata->getAssociationTargetClass($fieldName);
107
108
        $inverseFieldName = $this->getInverseFieldName($fieldName, $classMetadata);
109
110
        $reference = $this->getEntityManager()->getReference($targetClass, $id);
111
        $propertyAccessor = PropertyAccess::createPropertyAccessor();
112
        $propertyAccessor->setValue($reference, $inverseFieldName, $entity);
113
114
        $this->getEntityManager()->flush($reference);
115
    }
116
117
    /**
118
     * @param object     $entity
119
     * @param string     $fieldName
120
     * @param string|int $id
121
     */
122
    public function removeFromCollection($entity, string $fieldName, $id)
123
    {
124
        $classMetadata = $this->getEntityManager()->getClassMetadata(get_class($entity));
125
        $targetClass = $classMetadata->getAssociationTargetClass($fieldName);
126
127
        $inverseFieldName = $this->getInverseFieldName($fieldName, $classMetadata);
128
129
        $reference = $this->getEntityManager()->getReference($targetClass, $id);
130
        $propertyAccessor = PropertyAccess::createPropertyAccessor();
131
        $propertyAccessor->setValue($reference, $inverseFieldName, null);
132
133
        $this->getEntityManager()->flush($reference);
134
    }
135
136
    /**
137
     * @param string        $fieldName
138
     * @param ClassMetadata $classMetadata
139
     *
140
     * @return string
141
     */
142
    public function getInverseFieldName(string $fieldName, ClassMetadata $classMetadata)
143
    {
144
        $association = $classMetadata->getAssociationMapping($fieldName);
145
        if ($classMetadata->isAssociationInverseSide($fieldName)) {
146
            return $association['mappedBy'];
147
        } else {
148
            return $association['inversedBy'];
149
        }
150
    }
151
152
    /**
153
     * @param LoggerInterface $logger
154
     */
155
    public function setLogger(LoggerInterface $logger): void
156
    {
157
        $this->logger = $logger;
158
    }
159
160
    /**
161
     * @return LoggerInterface
162
     */
163
    public function getLogger(): LoggerInterface
164
    {
165
        if (null === $this->logger) {
166
            $this->logger = new NullLogger();
167
        }
168
169
        return $this->logger;
170
    }
171
}
172