Completed
Push — master ( 0bed22...e02f18 )
by Jonas
06:16 queued 02:43
created

CategoryResolver   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 206
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
dl 0
loc 206
rs 10
c 0
b 0
f 0
wmc 20
lcom 1
cbo 4

9 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 11 1
resolve() 0 1 ?
generateTree() 0 1 ?
A storeRemoteCategories() 0 21 3
B convertTreeToKeys() 0 20 5
A addProductToRemoteCategory() 0 13 3
A removeProductsFromNotAssignedRemoteCategories() 0 18 4
A checkAndCreateLocalCategory() 0 13 2
B createLocalCategory() 0 27 2
1
<?php
2
/**
3
 * (c) shopware AG <[email protected]>
4
 * For the full copyright and license information, please view the LICENSE
5
 * file that was distributed with this source code.
6
 */
7
8
namespace ShopwarePlugins\Connect\Components;
9
10
use Shopware\CustomModels\Connect\ProductToRemoteCategory;
11
use Shopware\CustomModels\Connect\RemoteCategory;
12
use Shopware\CustomModels\Connect\RemoteCategoryRepository;
13
use Shopware\Components\Model\ModelManager;
14
use Shopware\CustomModels\Connect\ProductToRemoteCategoryRepository;
15
use Shopware\Models\Category\Repository as CategoryRepository;
16
use Shopware\Models\Category\Category;
17
18
abstract class CategoryResolver
19
{
20
    /**
21
     * @var ModelManager
22
     */
23
    protected $manager;
24
25
    /**
26
     * @var \Shopware\CustomModels\Connect\RemoteCategoryRepository
27
     */
28
    protected $remoteCategoryRepository;
29
30
    /**
31
     * @var \Shopware\CustomModels\Connect\ProductToRemoteCategoryRepository
32
     */
33
    protected $productToRemoteCategoryRepository;
34
35
    /**
36
     * @var \Shopware\Models\Category\Repository
37
     */
38
    protected $categoryRepository;
39
40
    public function __construct(
41
        ModelManager $manager,
42
        RemoteCategoryRepository $remoteCategoryRepository,
43
        ProductToRemoteCategoryRepository $productToRemoteCategoryRepository,
44
        CategoryRepository $categoryRepository
45
    ) {
46
        $this->manager = $manager;
47
        $this->remoteCategoryRepository = $remoteCategoryRepository;
48
        $this->productToRemoteCategoryRepository = $productToRemoteCategoryRepository;
49
        $this->categoryRepository = $categoryRepository;
50
    }
51
52
    /**
53
     * Returns array with category entities
54
     * if they don't exist will be created
55
     *
56
     * @param array $categories
57
     * @return \Shopware\Models\Category\Category[]
58
     */
59
    abstract public function resolve(array $categories);
60
61
    /**
62
     * Generates categories tree by given array of categories
63
     *
64
     * @param array $categories
65
     * @param string $idPrefix
66
     * @return array
67
     */
68
    abstract public function generateTree(array $categories, $idPrefix = '');
69
70
    /**
71
     * Stores raw Shopware Connect categories
72
     *
73
     * @param array $categories
74
     * @param int $articleId
75
     * @return void
76
     */
77
    public function storeRemoteCategories(array $categories, $articleId)
78
    {
79
        $remoteCategories = [];
80
        foreach ($categories as $categoryKey => $category) {
81
            $remoteCategory = $this->remoteCategoryRepository->findOneBy(['categoryKey' => $categoryKey]);
82
            if (!$remoteCategory) {
83
                $remoteCategory = new RemoteCategory();
84
                $remoteCategory->setCategoryKey($categoryKey);
85
            }
86
            $remoteCategory->setLabel($category);
87
            $this->manager->persist($remoteCategory);
88
            $remoteCategories[] = $remoteCategory;
89
        }
90
91
        $this->manager->flush();
92
93
        $this->addProductToRemoteCategory($remoteCategories, $articleId);
94
        $this->removeProductsFromNotAssignedRemoteCategories($remoteCategories, $articleId);
95
96
        $this->manager->flush();
97
    }
98
99
    /**
100
     * @param RemoteCategory[] $remoteCategories
101
     * @param $articleId
102
     */
103
    private function addProductToRemoteCategory($remoteCategories, $articleId)
104
    {
105
        $productToCategories = $this->productToRemoteCategoryRepository->getRemoteCategoryIds($articleId);
106
        /** @var $remoteCategory \Shopware\CustomModels\Connect\RemoteCategory */
107
        foreach ($remoteCategories as $remoteCategory) {
108
            if (!in_array($remoteCategory->getId(), $productToCategories)) {
109
                $productToCategory = new ProductToRemoteCategory();
110
                $productToCategory->setArticleId($articleId);
111
                $productToCategory->setConnectCategory($remoteCategory);
112
                $this->manager->persist($productToCategory);
113
            }
114
        }
115
    }
116
117
    /**
118
     * @param \Shopware\CustomModels\Connect\RemoteCategory[] $assignedCategories
119
     * @param $articleId
120
     */
121
    private function removeProductsFromNotAssignedRemoteCategories(array $assignedCategories, $articleId)
122
    {
123
        $currentProductCategoryIds = $this->productToRemoteCategoryRepository->getRemoteCategoryIds($articleId);
124
125
        $assignedCategoryIds = array_map(function (RemoteCategory $assignedCategory) {
126
            $assignedCategory->getId();
0 ignored issues
show
Unused Code introduced by
The call to the method Shopware\CustomModels\Co...RemoteCategory::getId() seems un-needed as the method has no side-effects.

PHP Analyzer performs a side-effects analysis of your code. A side-effect is basically anything that might be visible after the scope of the method is left.

Let’s take a look at an example:

class User
{
    private $email;

    public function getEmail()
    {
        return $this->email;
    }

    public function setEmail($email)
    {
        $this->email = $email;
    }
}

If we look at the getEmail() method, we can see that it has no side-effect. Whether you call this method or not, no future calls to other methods are affected by this. As such code as the following is useless:

$user = new User();
$user->getEmail(); // This line could safely be removed as it has no effect.

On the hand, if we look at the setEmail(), this method _has_ side-effects. In the following case, we could not remove the method call:

$user = new User();
$user->setEmail('email@domain'); // This line has a side-effect (it changes an
                                 // instance variable).
Loading history...
127
        }, $assignedCategories);
128
129
        /** @var int $currentProductCategoryId */
130
        foreach ($currentProductCategoryIds as $currentProductCategoryId) {
131
            if (!in_array($currentProductCategoryId, $assignedCategoryIds)) {
132
                $this->productToRemoteCategoryRepository->deleteByConnectCategoryId($currentProductCategoryId);
133
                if ($this->productToRemoteCategoryRepository->getProductCountByCategoryId($currentProductCategoryId) > 0) {
134
                    $this->remoteCategoryRepository->deleteById($currentProductCategoryId);
135
                }
136
            }
137
        }
138
    }
139
140
    /**
141
     * Loop through category tree and fetch ids
142
     *
143
     * @param array $node
144
     * @param int $parentId
145
     * @param bool $returnOnlyLeafs
146
     * @param array $categories
147
     * @return array
148
     */
149
    public function convertTreeToKeys(array $node, $parentId, $returnOnlyLeafs = true, $categories = [])
150
    {
151
        foreach ($node as $category) {
152
            $categoryId = $this->checkAndCreateLocalCategory($category['name'], $category['categoryId'], $parentId);
153
154
            if ((!$returnOnlyLeafs) || (empty($category['children']))) {
155
                $categories[] = [
156
                    'categoryKey' => $categoryId,
157
                    'parentId' => $parentId,
158
                    'remoteCategory' => $category['categoryId']
159
                ];
160
            }
161
162
            if (!empty($category['children'])) {
163
                $categories = $this->convertTreeToKeys($category['children'], $categoryId, $returnOnlyLeafs, $categories);
164
            }
165
        }
166
167
        return $categories;
168
    }
169
170
    /**
171
     * @param string $categoryName
172
     * @param string $categoryKey
173
     * @param int $parentId
174
     * @return int
175
     */
176
    private function checkAndCreateLocalCategory($categoryName, $categoryKey, $parentId)
177
    {
178
        $id = $this->manager->getConnection()->fetchColumn('SELECT `id` 
179
            FROM `s_categories`
180
            WHERE `parent` = :parentId AND `description` = :description',
181
            [':parentId' => $parentId, ':description' => $categoryName]);
182
183
        if (!$id) {
184
            return $this->createLocalCategory($categoryName, $categoryKey, $parentId);
185
        }
186
187
        return $id;
188
    }
189
190
    /**
191
     * @param string $categoryName
192
     * @param string $categoryKey
193
     * @param int $parentId
194
     * @return int
195
     */
196
    public function createLocalCategory($categoryName, $categoryKey, $parentId)
197
    {
198
        $path = $this->manager->getConnection()->fetchColumn('SELECT `path` 
199
            FROM `s_categories`
200
            WHERE `id` = ?',
201
            [$parentId]);
202
        $suffix = ($path) ? "$parentId|" : "|$parentId|";
203
        $path = $path . $suffix;
204
        $this->manager->getConnection()->executeQuery('INSERT INTO `s_categories` (`description`, `parent`, `path`, `active`) 
205
            VALUES (?, ?, ?, 1)',
206
            [$categoryName, $parentId, $path]);
207
        $localCategoryId = $this->manager->getConnection()->fetchColumn('SELECT LAST_INSERT_ID()');
208
209
        $this->manager->getConnection()->executeQuery('INSERT INTO `s_categories_attributes` (`categoryID`, `connect_imported_category`) 
210
            VALUES (?, 1)',
211
            [$localCategoryId]);
212
213
        $remoteCategoryId = $this->manager->getConnection()->fetchColumn('SELECT `id` 
214
            FROM `s_plugin_connect_categories`
215
            WHERE `category_key` = ?',
216
            [$categoryKey]);
217
        $this->manager->getConnection()->executeQuery('INSERT INTO `s_plugin_connect_categories_to_local_categories` (`remote_category_id`, `local_category_id`) 
218
            VALUES (?, ?)',
219
            [$remoteCategoryId, $localCategoryId]);
220
221
        return $localCategoryId;
222
    }
223
}
224