Completed
Push — master ( b55ca8...f3fba8 )
by Kamil
20:16 queued 07:20
created

postUpdate()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 26
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 26
rs 8.5806
c 0
b 0
f 0
cc 4
eloc 14
nc 4
nop 1
1
<?php
2
3
/*
4
 * This file is part of the Sylius package.
5
 *
6
 * (c) Paweł Jędrzejewski
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Sylius\Bundle\ProductBundle\EventListener;
15
16
use Doctrine\Common\Persistence\ObjectManager;
17
use Doctrine\ORM\Event\LifecycleEventArgs;
18
use Sylius\Component\Attribute\AttributeType\SelectAttributeType;
19
use Sylius\Component\Product\Model\ProductAttributeInterface;
20
use Sylius\Component\Product\Model\ProductAttributeValue;
21
use Sylius\Component\Product\Model\ProductAttributeValueInterface;
22
use Sylius\Component\Product\Repository\ProductAttributeValueRepositoryInterface;
23
24
final class SelectProductAttributeChoiceRemoveListener
25
{
26
    /**
27
     * @var string
28
     */
29
    private $productAttributeValueClass;
30
31
    /**
32
     * @param string $productAttributeValueClass
33
     */
34
    public function __construct(string $productAttributeValueClass)
35
    {
36
        $this->productAttributeValueClass = $productAttributeValueClass;
37
    }
38
39
    /**
40
     * @param LifecycleEventArgs $event
41
     */
42
    public function postUpdate(LifecycleEventArgs $event): void
43
    {
44
        /** @var ProductAttributeInterface $productAttribute */
45
        $productAttribute = $event->getEntity();
46
47
        if (!($productAttribute instanceof ProductAttributeInterface)) {
48
            return;
49
        }
50
51
        if ($productAttribute->getType() !== SelectAttributeType::TYPE) {
52
            return;
53
        }
54
55
        $entityManager = $event->getEntityManager();
56
57
        $unitOfWork = $entityManager->getUnitOfWork();
58
        $changeSet = $unitOfWork->getEntityChangeSet($productAttribute);
59
60
        $oldChoices = $changeSet['configuration'][0]['choices'] ?? [];
61
        $newChoices = $changeSet['configuration'][1]['choices'] ?? [];
62
63
        $removedChoices = array_diff_key($oldChoices, $newChoices);
64
        if (!empty($removedChoices)) {
65
            $this->removeValues($entityManager, array_keys($removedChoices));
66
        }
67
    }
68
69
    /**
70
     * @param ObjectManager $entityManager
71
     * @param array|string[] $choiceKeys
72
     */
73
    public function removeValues(ObjectManager $entityManager, array $choiceKeys): void
74
    {
75
        /** @var ProductAttributeValueRepositoryInterface $productAttributeValueRepository */
76
        $productAttributeValueRepository = $entityManager->getRepository($this->productAttributeValueClass);
77
        foreach ($choiceKeys as $choiceKey) {
78
            $productAttributeValues = $productAttributeValueRepository->findByJsonChoiceKey($choiceKey);
79
80
            /** @var ProductAttributeValueInterface $productAttributeValue */
81
            foreach ($productAttributeValues as $productAttributeValue) {
82
                $newValue = array_diff($productAttributeValue->getValue(), [$choiceKey]);
83
                if (!empty($newValue)) {
84
                    $productAttributeValue->setValue($newValue);
85
86
                    continue;
87
                }
88
89
                $entityManager->remove($productAttributeValue);
90
            }
91
        }
92
93
        $entityManager->flush();
94
    }
95
}
96