Passed
Push — master ( c4324c...02742b )
by Joachim
10:39
created

updateParentChildRelationships()   C

Complexity

Conditions 8
Paths 50

Size

Total Lines 62
Code Lines 38

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 72

Importance

Changes 0
Metric Value
cc 8
eloc 38
nc 50
nop 1
dl 0
loc 62
ccs 0
cts 0
cp 0
crap 72
rs 6.943
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Loevgaard\DandomainFoundation\Repository;
4
5
use Doctrine\ORM\ORMException;
6
use Doctrine\ORM\UnexpectedResultException;
7
use Loevgaard\DandomainFoundation\Entity\Generated\ProductInterface;
8
use Loevgaard\DandomainFoundation\Entity\Product;
9
use Loevgaard\DandomainFoundation\Repository\Generated\ProductRepositoryTrait;
10
use Symfony\Bridge\Doctrine\RegistryInterface;
11
12
/**
13
 * @method null|ProductInterface find($id)
14
 * @method ProductInterface[] findBy(array $criteria, array $orderBy = null, int $limit = null, int $offset = null)
15
 * @method null|ProductInterface findOneBy(array $criteria)
16
 * @method ProductInterface[] findAll()
17
 */
18
class ProductRepository extends AbstractRepository
19
{
20
    use ProductRepositoryTrait;
21
22
    public function __construct(RegistryInterface $registry)
23
    {
24
        parent::__construct($registry, Product::class);
25
    }
26
27
    public function findOneByExternalId(int $externalId): ?ProductInterface
28
    {
29
        /** @var ProductInterface $obj */
30
        $obj = $this->_findOneByExternalId($externalId);
31
32
        return $obj;
33
    }
34
35
    /**
36
     * @param string $number
37
     *
38
     * @return ProductInterface|null
39
     */
40
    public function findOneByNumber(string $number): ?ProductInterface
41
    {
42
        /** @var ProductInterface $obj */
43
        $obj = $this->findOneBy([
44
            'number' => $number,
45
        ]);
46
47
        return $obj;
48
    }
49
50
    /**
51
     * @param array $productIds
52
     * @throws \Doctrine\ORM\OptimisticLockException
53
     */
54
    public function updateParentChildRelationships(array $productIds = [])
55
    {
56
        $variantMasterIdCache = [];
57
58
        $innerQb = $this->createQueryBuilder('p');
59
        $innerQb->where('p.isVariantMaster = 1')
60
            ->andWhere('p.number = :number');
61
62
        $qb = $this->createQueryBuilder('p');
63
        $qb
64
            ->where('p.isVariantMaster = 0')
65
            ->andWhere('p.variantMasterId is not null')
66
        ;
67
68
        if (count($productIds)) {
69
            $qb->andWhere($qb->expr()->in('p.id', ':productIds'));
70
            $qb->setParameter('productIds', $productIds);
71
        }
72
73
        $batchSize = 50;
74
        $i = 1;
75
76
        $iterableResult = $qb->getQuery()->iterate();
77
        foreach ($iterableResult as $row) {
78
            /** @var ProductInterface $product */
79
            $product = $row[0];
80
81
            if (!isset($variantMasterIdCache[$product->getVariantMasterId()])) {
82
                try {
83
                    /** @var ProductInterface $parent */
84
                    $parent = $innerQb->setParameter(
85
                        'number',
86
                        $product->getVariantMasterId()
87
                    )->getQuery()->getSingleResult();
88
                    $parent = $parent->getId();
89
                } catch (UnexpectedResultException $e) {
90
                    $parent = null;
91
                }
92
93
                $variantMasterIdCache[$product->getVariantMasterId()] = $parent;
94
            }
95
96
            $ref = $variantMasterIdCache[$product->getVariantMasterId()];
97
            if ($ref) {
98
                try {
99
                    $ref = $this->getEntityManager()->getReference(Product::class, $ref);
100
                } catch (ORMException $e) {
101
                    $ref = null;
102
                }
103
            }
104
105
            $product->setParent($ref);
106
107
            if (0 === ($i % $batchSize)) {
108
                $this->getEntityManager()->flush();
109
                $this->getEntityManager()->clear();
110
            }
111
112
            ++$i;
113
        }
114
115
        $this->getEntityManager()->flush();
116
    }
117
}
118