Passed
Push — PAC-894 ( 0a9221...9b2951 )
by
unknown
03:10
created

cleanUpGrouped()   A

Complexity

Conditions 6
Paths 8

Size

Total Lines 42
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 19
c 2
b 0
f 0
dl 0
loc 42
rs 9.0111
cc 6
nc 8
nop 0
1
<?php
2
/**
3
 * Copyright (c) 2024 TechDivision GmbH <[email protected]> - TechDivision GmbH
4
 * All rights reserved
5
 *
6
 * This product includes proprietary software developed at TechDivision GmbH, Germany
7
 * For more information see https://www.techdivision.com
8
 *
9
 * To obtain a valid license for using this software, please contact us at
10
 * [email protected]
11
 */
12
declare(strict_types=1);
13
14
namespace TechDivision\Import\Product\Grouped\Observers;
15
16
use Exception;
17
use TechDivision\Import\Observers\StateDetectorInterface;
18
use TechDivision\Import\Product\Grouped\Services\ProductGroupedProcessorInterface;
19
use TechDivision\Import\Product\Grouped\Utils\ColumnKeys;
20
use TechDivision\Import\Product\Grouped\Utils\ProductTypes;
21
use TechDivision\Import\Product\Observers\AbstractProductImportObserver;
22
use TechDivision\Import\Product\Utils\ConfigurationKeys;
23
use TechDivision\Import\Product\Utils\MemberNames;
24
25
/**
26
 * @copyright Copyright (c) 2024 TechDivision GmbH <[email protected]> - TechDivision GmbH
27
 * @link http://www.techdivision.com
28
 * @author MET <[email protected]>
29
 */
30
class CleanUpGroupedProductRelationObserver extends AbstractProductImportObserver
31
{
32
    /**
33
     * @var ProductGroupedProcessorInterface
34
     */
35
    protected ProductGroupedProcessorInterface $productGroupedProcessor;
36
37
    /**
38
     * Initialize the observer with the passed grouped product data processor instance.
39
     *
40
     * @param ProductGroupedProcessorInterface $productGroupedProcessor The grouped product processor instance
41
     * @param StateDetectorInterface|null $stateDetector The state detector instance to use
42
     */
43
    public function __construct(
44
        ProductGroupedProcessorInterface $productGroupedProcessor,
45
        StateDetectorInterface $stateDetector = null
46
    ) {
47
        // pass the state detector to the parent constructor
48
        parent::__construct($stateDetector);
49
50
        // initialize the grouped product processor instance
51
        $this->productGroupedProcessor = $productGroupedProcessor;
52
    }
53
54
    /**
55
     * Return's the grouped product processor instance.
56
     *
57
     * @return ProductGroupedProcessorInterface The grouped product processor instance
58
     */
59
    protected function getProductGroupedProcessor(): ProductGroupedProcessorInterface
60
    {
61
        return $this->productGroupedProcessor;
62
    }
63
64
    /**
65
     * Process the observer's business logic.
66
     *
67
     * @return void
68
     * @throws Exception
69
     */
70
    protected function process()
71
    {
72
        // query whether or not we've found a grouped product
73
        if ($this->getValue(ColumnKeys::PRODUCT_TYPE) !== ProductTypes::GROUPED) {
74
            return;
75
        }
76
77
        $subject = $this->getSubject();
78
        $subjectConfiguration = $subject->getConfiguration();
79
80
        if ($subjectConfiguration->hasParam(ConfigurationKeys::CLEAN_UP_LINKS)
81
            && $subjectConfiguration->getParam(ConfigurationKeys::CLEAN_UP_LINKS)) {
82
            $this->cleanUpGrouped();
83
84
            $subject->getSystemLogger()->info(
85
                $subject->appendExceptionSuffix(
86
                    sprintf(
87
                        'Successfully clean up grouped product with SKU "%s"',
88
                        $this->getValue(ColumnKeys::SKU)
89
                    )
90
                )
91
            );
92
        }
93
    }
94
95
    /**
96
     * Search for child products in the artefacts and check for differences in the database.
97
     * Remove entries in DB that do not exist in artefact.
98
     *
99
     * @return void
100
     * @throws Exception Is thrown if all the child products cannot be deleted
101
     */
102
    protected function cleanUpGrouped()
103
    {
104
        // load the available artefacts from the subject
105
        $subject = $this->getSubject();
106
        $artefacts = $subject->getArtefacts();
107
108
        // return, if we do NOT have any grouped product artefacts
109
        if (!isset($artefacts[ProductGroupedObserver::ARTEFACT_TYPE])) {
110
            return;
111
        }
112
113
        // load the entity ID of the parent product
114
        $parentIdForArtefacts = $this->getLastEntityId();
115
116
        // return, if we do NOT have any artefacts for the actual entity ID
117
        if (!isset($artefacts[ProductGroupedObserver::ARTEFACT_TYPE][$parentIdForArtefacts])) {
118
            return;
119
        }
120
121
        // initialize the array with the SKUs of the child IDs and the attribute codes
122
        $actualGrouped = [];
123
124
        // load the grouped product artefacts for the actual entity ID
125
        $allGrouped = $artefacts[ProductGroupedObserver::ARTEFACT_TYPE][$parentIdForArtefacts];
126
127
        // iterate over the artefacts with the grouped product data
128
        foreach ($allGrouped as $groupedData) {
129
            // add the child SKU to the array
130
            $actualGrouped[] = $groupedData[ColumnKeys::GROUPED_CHILD_SKU];
131
        }
132
133
        // load the row/entity ID of the parent product
134
        $parentId = $this->getLastPrimaryKey();
135
136
        try {
137
            $this->cleanUpGroupedRelation($parentId, $actualGrouped);
138
        } catch (Exception $e) {
139
            // log a warning if debug mode has been enabled
140
            if ($subject->isDebugMode()) {
141
                $subject->getSystemLogger()->critical($subject->appendExceptionSuffix($e->getMessage()));
142
            } else {
143
                throw $e;
144
            }
145
        }
146
    }
147
148
    /**
149
     * Delete not exists import relations from database.
150
     *
151
     * @param int $parentProductId The ID of the parent product
152
     * @param array $childData The array of child products
153
     *
154
     * @return void
155
     * @throws Exception
156
     */
157
    protected function cleanUpGroupedRelation(int $parentProductId, array $childData)
158
    {
159
        // we don't want to delete everything
160
        if (empty($childData)) {
161
            return;
162
        }
163
164
        // load the SKU of the parent product
165
        $parentSku = $this->getValue(ColumnKeys::SKU);
166
167
        // remove the old child products from the database
168
        $this->getProductGroupedProcessor()->deleteProductRelation(
169
            [
170
                MemberNames::PARENT_ID => $parentProductId,
171
                MemberNames::SKU => $childData,
172
            ]
173
        );
174
175
        // log a debug message that the image has been removed
176
        $subject = $this->getSubject();
177
        $subject->getSystemLogger()->info(
178
            $subject->appendExceptionSuffix(
179
                sprintf(
180
                    'Successfully clean up relations for product with SKU "%s"',
181
                    $parentSku
182
                )
183
            )
184
        );
185
    }
186
187
    /**
188
     * Return's the PK to create the product => child relation.
189
     *
190
     * @return int The PK to create the relation with
191
     */
192
    protected function getLastPrimaryKey(): int
193
    {
194
        return (int)$this->getLastEntityId();
195
    }
196
}
197