Completed
Push — master ( 7ba03f...fe443c )
by Joachim
56:05 queued 41:02
created

AbstractRepository::getReference()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 0
cts 0
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Loevgaard\DandomainFoundation\Repository;
4
5
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
6
use Loevgaard\DandomainDateTime\DateTimeImmutable;
7
use Loevgaard\DandomainFoundation\Repository\Generated\AbstractRepositoryTrait;
8
use Symfony\Component\OptionsResolver\OptionsResolver;
9
10
abstract class AbstractRepository extends ServiceEntityRepository implements RepositoryInterface
11
{
12
    use AbstractRepositoryTrait;
13
14
    /**
15
     * @param $entity
16
     * @throws \Doctrine\ORM\OptimisticLockException
17
     */
18
    public function save($entity)
19
    {
20
        $this->getEntityManager()->persist($entity);
21
        $this->getEntityManager()->flush();
22
    }
23
24
    /**
25
     * @param array $options
26
     * @return \Generator
27
     * @throws \Doctrine\ORM\OptimisticLockException
28
     */
29
    public function iterate(array $options = []): \Generator
30
    {
31
        $resolver = new OptionsResolver();
32
        $this->configureIterateOptions($resolver);
33
        $options = $resolver->resolve($options);
34
35
        $em = $this->getEntityManager();
36
37
        $qb = $this->createQueryBuilder('c');
38
39
        $result = $qb->getQuery()->iterate();
40
        $i = 1;
41
        foreach ($result as $item) {
42
            $obj = $item[0];
43
            yield $obj;
44
45
            if ($options['update']) {
46
                if (0 == $i % $options['bulkSize']) {
47
                    $em->flush();
48
                    $em->clear();
49
                }
50
            } else {
51
                $em->detach($obj);
52
            }
53
54
            ++$i;
55
        }
56
57
        if ($options['update']) {
58
            $em->flush();
59
        }
60
    }
61
62
    /**
63
     * Will remove entities based on the ids you input
64
     *
65
     * @param int[] $in
66
     * @param int[] $notIn
67
     */
68
    public function removeByIds(array $in = [], array $notIn = [])
69
    {
70
        if (!count($in) && !count($notIn)) {
71
            return;
72
        }
73
74
        $qb = $this->createQueryBuilder('e');
75
76
        if ($this->getClassMetadata()->hasField('deletedAt')) {
77
            $qb->update()
78
                ->set('e.deletedAt', ':date')
79
                ->setParameter('date', new DateTimeImmutable())
80
            ;
81
        } else {
82
            $qb->delete();
83
        }
84
85
        if (count($in)) {
86
            $qb->andWhere($qb->expr()->in('e.id', ':inIds'));
87
            $qb->setParameter('inIds', $in);
88
        }
89
90
        if (count($notIn)) {
91
            $qb->andWhere($qb->expr()->notIn('e.id', ':notInIds'));
92
            $qb->setParameter('notInIds', $notIn);
93
        }
94
95
        $qb->getQuery()->execute();
96
    }
97
98
    public function clearAll()
99
    {
100
        $this->getEntityManager()->clear();
101
    }
102
103
    /**
104
     * @param $id
105
     * @return bool|\Doctrine\Common\Proxy\Proxy|null|object
106
     * @throws \Doctrine\ORM\ORMException
107
     */
108
    public function getReference($id)
109
    {
110
        return $this->getEntityManager()->getReference($this->getClassName(), $id);
111
    }
112
113
    /**
114
     * On 90% of the entities there is an external id so we put this helper method here
115
     * so that all these repository doesn't have to implement the same method, instead they
116
     * can call this method and just create the type hint and validation of input
117
     *
118
     * @param $externalId
119
     * @return null|object
120
     */
121
    protected function _findOneByExternalId($externalId)
122
    {
123
        $obj = $this->findOneBy([
124
            'externalId' => $externalId,
125
        ]);
126
127
        return $obj;
128
    }
129
130
    protected function configureIterateOptions(OptionsResolver $resolver)
131
    {
132
        $resolver->setDefaults([
133
            'update' => true,
134
            'bulkSize' => 50,
135
        ]);
136
    }
137
}
138