Completed
Push — master ( a18731...e2e070 )
by
unknown
99:54 queued 47:45
created

MagentoDeleteProvider   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 140
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Importance

Changes 0
Metric Value
wmc 8
lcom 1
cbo 8
dl 0
loc 140
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A supports() 0 4 1
A deleteRelatedData() 0 13 1
A getChannelId() 0 4 1
B removeCarts() 0 26 1
B removeWorkflowDefinitions() 0 27 2
A removeFromEntityByChannelId() 0 12 1
1
<?php
2
3
namespace OroCRM\Bundle\MagentoBundle\Manager;
4
5
use Doctrine\ORM\EntityManager;
6
7
use Oro\Bundle\IntegrationBundle\Entity\Channel;
8
use Oro\Bundle\IntegrationBundle\Manager\DeleteProviderInterface;
9
use Oro\Bundle\WorkflowBundle\Entity\WorkflowItem;
10
use Oro\Bundle\WorkflowBundle\Helper\WorkflowQueryTrait;
11
12
class MagentoDeleteProvider implements DeleteProviderInterface
13
{
14
    use WorkflowQueryTrait;
15
16
    /** @var EntityManager */
17
    protected $em;
18
19
    /** @var Channel */
20
    protected $channel;
21
22
    /**
23
     * @param EntityManager $em
24
     */
25
    public function __construct(EntityManager $em)
0 ignored issues
show
Bug introduced by
You have injected the EntityManager via parameter $em. This is generally not recommended as it might get closed and become unusable. Instead, it is recommended to inject the ManagerRegistry and retrieve the EntityManager via getManager() each time you need it.

The EntityManager might become unusable for example if a transaction is rolled back and it gets closed. Let’s assume that somewhere in your application, or in a third-party library, there is code such as the following:

function someFunction(ManagerRegistry $registry) {
    $em = $registry->getManager();
    $em->getConnection()->beginTransaction();
    try {
        // Do something.
        $em->getConnection()->commit();
    } catch (\Exception $ex) {
        $em->getConnection()->rollback();
        $em->close();

        throw $ex;
    }
}

If that code throws an exception and the EntityManager is closed. Any other code which depends on the same instance of the EntityManager during this request will fail.

On the other hand, if you instead inject the ManagerRegistry, the getManager() method guarantees that you will always get a usable manager instance.

Loading history...
26
    {
27
        $this->em = $em;
28
    }
29
30
    /**
31
     * {@inheritdoc}
32
     */
33
    public function supports($channelType)
34
    {
35
        return 'magento' === $channelType;
36
    }
37
38
    /**
39
     * {@inheritdoc}
40
     */
41
    public function deleteRelatedData(Channel $channel)
42
    {
43
        $this->channel = $channel;
44
        $this->removeWorkflowDefinitions('OroCRMMagentoBundle:Order')
45
            ->removeFromEntityByChannelId('OroCRMMagentoBundle:Order')
46
            ->removeWorkflowDefinitions('OroCRMMagentoBundle:Cart')
47
            ->removeCarts()
48
            ->removeFromEntityByChannelId('OroCRMMagentoBundle:Customer')
49
            ->removeFromEntityByChannelId('OroCRMMagentoBundle:Store')
50
            ->removeFromEntityByChannelId('OroCRMMagentoBundle:Website')
51
            ->removeFromEntityByChannelId('OroCRMMagentoBundle:CustomerGroup')
52
            ->removeFromEntityByChannelId('OroCRMMagentoBundle:NewsletterSubscriber');
53
    }
54
55
    /**
56
     * Get channel id for current channel
57
     *
58
     * @return int
59
     */
60
    protected function getChannelId()
61
    {
62
        return $this->channel->getId();
63
    }
64
65
    /**
66
     * Remove cart records
67
     *
68
     * @return $this
69
     */
70
    protected function removeCarts()
71
    {
72
        $cartTable = $this->em->getClassMetadata('OroCRMMagentoBundle:Cart')->getTableName();
73
        $shippingAddresses = sprintf(
74
            'SELECT sa.shipping_address_id FROM %s sa WHERE sa.channel_id = %s',
75
            $cartTable,
76
            $this->channel->getId()
77
        );
78
        $billingAddresses = sprintf(
79
            'SELECT ba.billing_address_id FROM %s ba WHERE ba.channel_id = %s',
80
            $cartTable,
81
            $this->channel->getId()
82
        );
83
        $this->em->getConnection()->executeQuery(
84
            sprintf(
85
                'Delete FROM %s WHERE id IN (%s) OR id IN (%s)',
86
                $this->em->getClassMetadata('OroCRMMagentoBundle:CartAddress')->getTableName(),
87
                $shippingAddresses,
88
                $billingAddresses
89
            )
90
        );
91
92
        $this->removeFromEntityByChannelId('OroCRMMagentoBundle:Cart');
93
94
        return $this;
95
    }
96
97
    /**
98
     * Remove workflow records
99
     *
100
     * @param string $entityClassName
101
     *
102
     * @return $this
103
     */
104
    protected function removeWorkflowDefinitions($entityClassName)
105
    {
106
        $subQuery = $this->em->createQueryBuilder()->select('workflowItem.id')->from($entityClassName, 'o');
107
        $this->joinWorkflowItem($subQuery, 'workflowItem');
108
        $subQuery
109
            ->where('o.channel=:channel')
110
            ->setParameter('channel', $this->channel);
111
112
        $ids = array_filter(
113
            array_map(
114
                function (array $record) {
115
                    return $record['id'];
116
                },
117
                $subQuery->getQuery()->getResult()
118
            )
119
        );
120
        if (0 === count($ids)) {
121
            return $this;
122
        }
123
124
        $qbDel = $this->em->createQueryBuilder()->delete()->from(WorkflowItem::class, 'wi');
125
        $qbDel->where($qbDel->expr()->in('wi.id', $ids));
126
127
        $qbDel->getQuery()->execute();
128
129
        return $this;
130
    }
131
132
    /**
133
     * Remove records from given entity type related to channel
134
     *
135
     * @param string $entityClassName
136
     *
137
     * @return $this
138
     */
139
    protected function removeFromEntityByChannelId($entityClassName)
140
    {
141
        $this->em->getConnection()->executeQuery(
142
            sprintf(
143
                'DELETE FROM %s WHERE channel_id=%s',
144
                $this->em->getClassMetadata($entityClassName)->getTableName(),
145
                $this->getChannelId()
146
            )
147
        );
148
149
        return $this;
150
    }
151
}
152