Shopware_Controllers_Backend_Import   D
last analyzed

Complexity

Total Complexity 59

Size/Duplication

Total Lines 577
Duplicated Lines 3.47 %

Coupling/Cohesion

Components 3
Dependencies 8

Importance

Changes 0
Metric Value
dl 20
loc 577
rs 4.08
c 0
b 0
f 0
wmc 59
lcom 3
cbo 8

25 Methods

Rating   Name   Duplication   Size   Complexity  
A getHelper() 0 4 1
A getConnectFactory() 0 8 2
B getImportedProductCategoriesTreeAction() 0 58 7
A loadArticlesByRemoteCategoryAction() 0 46 2
A loadBothArticleTypesAction() 0 22 2
B assignArticlesToCategoryAction() 0 53 5
A unassignRemoteArticlesFromLocalCategoryAction() 0 20 2
B assignRemoteToLocalCategoryAction() 0 55 8
A getArticleCountForRemoteCategoryAction() 0 23 2
A assignArticlesToRemoteCategoryAction() 0 26 2
A unassignRemoteToLocalCategoryAction() 0 30 3
A activateArticlesAction() 20 20 2
A deactivateCategoryAction() 0 33 4
A getSuppliersAction() 0 19 2
A recreateRemoteCategoriesAction() 0 8 1
A getCategoryExtractor() 0 15 2
A getPdoGateway() 0 4 1
A getProductToRemoteCategoryRepository() 0 10 2
A getImportService() 0 4 1
A getAutoCategoryReverter() 0 4 1
A getCategoryRepository() 0 8 2
A getLogger() 0 8 2
A connectCategoriesNeedRecoveryAction() 0 9 1
A connectCategoriesNeedAdditionalShopIdAction() 0 9 1
A productCountForCategoryRecoveryAction() 0 9 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Shopware_Controllers_Backend_Import often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Shopware_Controllers_Backend_Import, and based on these observations, apply Extract Interface, too.

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
use ShopwarePlugins\Connect\Components\ConnectFactory;
8
9
/**
10
 * Class Shopware_Controllers_Backend_Import
11
 */
12
class Shopware_Controllers_Backend_Import extends Shopware_Controllers_Backend_ExtJs
13
{
14
    private $categoryExtractor;
15
16
    /**
17
     * @var \Shopware\CustomModels\Connect\ProductToRemoteCategory
18
     */
19
    private $productToRemoteCategoryRepository;
20
21
    private $remoteCategoryRepository;
22
23
    private $categoryRepository;
24
25
    private $logger;
26
27
    private $factory;
28
29
    /**
30
     * @return \ShopwarePlugins\Connect\Components\Helper
31
     */
32
    public function getHelper()
33
    {
34
        return $this->getConnectFactory()->getHelper();
35
    }
36
37
    /**
38
     * @return ConnectFactory
39
     */
40
    public function getConnectFactory()
41
    {
42
        if ($this->factory === null) {
43
            $this->factory = new ConnectFactory();
44
        }
45
46
        return $this->factory;
47
    }
48
49
    public function getImportedProductCategoriesTreeAction()
50
    {
51
        $parent = $this->request->getParam('categoryId', 'root');
52
        $hideMapped = (bool) $this->request->getParam('hideMappedProducts', false);
53
54
        $query = $this->request->getParam('remoteCategoriesQuery', '');
55
        $node = $this->request->getParam('id');
56
57
        if (trim($query) !== '') {
58
            try {
59
                $categories = $this->getCategoryExtractor()->getNodesByQuery($hideMapped, $query, $parent, $node);
60
                $this->View()->assign([
61
                    'success' => true,
62
                    'data' => $categories,
63
                ]);
64
            } catch (\InvalidArgumentException $e) {
65
                $this->View()->assign([
66
                    'success' => false,
67
                    'message' => $e->getMessage(),
68
                ]);
69
            }
70
71
            return;
72
        }
73
74
        switch ($parent) {
75
            case 'root':
76
                $categories = $this->getCategoryExtractor()->getMainNodes($hideMapped);
77
                break;
78
            case is_numeric($parent):
79
                $categories = $this->getCategoryExtractor()->getStreamsByShopId($parent);
80
                break;
81
            case strpos($parent, '_stream_') > 0:
82
                list($shopId, $stream) = explode('_stream_', $parent);
83
                $categories = $this->getCategoryExtractor()->getRemoteCategoriesTreeByStream($stream, $shopId, $hideMapped);
84
                break;
85
            default:
86
                // given id must have following structure:
87
                // shopId5~stream~AwesomeProducts~/english/boots/nike
88
                // shopId is required parameter to fetch all child categories of this parent
89
                try {
90
                    list($shopId, $stream) = $this->getCategoryExtractor()->extractNode($node);
91
                } catch (\InvalidArgumentException $e) {
92
                    $this->View()->assign([
93
                        'success' => false,
94
                        'message' => $e->getMessage(),
95
                    ]);
96
97
                    return;
98
                }
99
                $categories = $this->getCategoryExtractor()->getRemoteCategoriesTree($parent, false, $hideMapped, $shopId, $stream);
100
        }
101
102
        $this->View()->assign([
103
            'success' => true,
104
            'data' => $categories,
105
        ]);
106
    }
107
108
    public function loadArticlesByRemoteCategoryAction()
109
    {
110
        $category = $this->request->getParam('category', null);
111
        $shopId = $this->request->getParam('shopId', 0);
112
        $limit = (int) $this->request->getParam('limit', 10);
113
        $offset = (int) $this->request->getParam('start', 0);
114
        $hideMapped = (bool) $this->request->getParam('hideMappedProducts', false);
115
        $searchQuery = $this->request->getParam('remoteArticlesQuery', '');
116
117
        $stream = $this->request->getParam('stream', null);
118
119
        if (strpos($category, '_stream_') > 0) {
120
            $snippets = $this->get('snippets')->getNamespace('backend/connect/view/main');
121
122
            $this->View()->assign([
123
                'success' => false,
124
                'message' => $snippets->get(
125
                    'import/message/dont_select_streams',
126
                    'Please select a Category to display its products',
127
                    true
128
                ),
129
            ]);
130
131
            return;
132
        }
133
134
        $query = $this->getProductToRemoteCategoryRepository()->findArticlesByRemoteCategory(
135
            $category,
136
            $shopId,
137
            $stream,
138
            $limit,
139
            $offset,
140
            $hideMapped,
141
            $searchQuery
142
        );
143
144
        $query->setHydrationMode($query::HYDRATE_OBJECT);
145
146
        $paginator = new \Doctrine\ORM\Tools\Pagination\Paginator($query);
147
        $totalCount = $paginator->count();
148
        $this->View()->assign([
149
            'success' => true,
150
            'data' => $query->getArrayResult(),
151
            'total' => $totalCount,
152
        ]);
153
    }
154
155
    public function loadBothArticleTypesAction()
156
    {
157
        $categoryId = (int) $this->request->getParam('categoryId', 0);
158
        $limit = (int) $this->request->getParam('limit', 10);
159
        $offset = (int) $this->request->getParam('start', 0);
160
        $showOnlyConnectArticles = $this->request->getParam('showOnlyConnectArticles', null);
161
        $query = $this->request->getParam('localArticlesQuery', '');
162
163
        $result = $this->getImportService()->findBothArticlesType(
164
            $categoryId,
165
            $query,
166
            $showOnlyConnectArticles ? true : false,
167
            $limit,
168
            $offset
169
        );
170
171
        $this->View()->assign([
172
            'success' => true,
173
            'data' => $result['data'],
174
            'total' => $result['total'],
175
        ]);
176
    }
177
178
    public function assignArticlesToCategoryAction()
179
    {
180
        $categoryId = (int) $this->request->getParam('categoryId', 0);
181
        $articleIds = $this->request->getParam('articleIds', []);
182
183
        $snippets = Shopware()->Snippets()->getNamespace('backend/connect/view/main');
184
185
        if ($categoryId == 0 || empty($articleIds)) {
186
            $this->View()->assign([
187
                'success' => false,
188
                'message' => $snippets->get(
189
                    'import/message/category_has_children',
190
                    'Invalid category or articles',
191
                    true
192
                ),
193
            ]);
194
195
            return;
196
        }
197
198
        if ($this->getImportService()->hasCategoryChildren($categoryId)) {
199
            $this->View()->assign([
200
                'success' => false,
201
                'message' => $snippets->get(
202
                    'import/message/category_has_children',
203
                    'Category has subcategories, please make sure you have selected single one',
204
                    true
205
                ),
206
            ]);
207
208
            return;
209
        }
210
211
        try {
212
            $this->getImportService()->assignCategoryToArticles($categoryId, $articleIds);
213
        } catch (\RuntimeException $e) {
214
            $this->getLogger()->write(true, $e->getMessage(), $e);
215
            $this->View()->assign([
216
                'success' => false,
217
                'message' => $snippets->get(
218
                    'import/message/failed_product_to_category_assignment',
219
                    'Category could not be assigned to products!',
220
                    true
221
                ),
222
            ]);
223
224
            return;
225
        }
226
227
        $this->View()->assign([
228
            'success' => true
229
        ]);
230
    }
231
232
    /**
233
     * Unassign all categories from articles
234
     */
235
    public function unassignRemoteArticlesFromLocalCategoryAction()
236
    {
237
        $articleIds = $this->request->getParam('articleIds', []);
238
        $categoryId = (int) $this->request->getParam('categoryId');
239
        try {
240
            $this->getImportService()->unAssignArticleCategories($articleIds, $categoryId);
241
        } catch (\Exception $e) {
242
            $this->getLogger()->write(true, $e->getMessage(), $e);
243
            $this->View()->assign([
244
                'success' => false,
245
                'error' => 'Categories could not be unassigned from products!',
246
            ]);
247
248
            return;
249
        }
250
251
        $this->View()->assign([
252
            'success' => true
253
        ]);
254
    }
255
256
    public function assignRemoteToLocalCategoryAction()
257
    {
258
        $localCategoryId = (int) $this->request->getParam('localCategoryId', 0);
259
        $remoteCategoryKey = $this->request->getParam('remoteCategoryKey', null);
260
        $remoteCategoryLabel = $this->request->getParam('remoteCategoryLabel', null);
261
        $node = $this->request->getParam('node', null);
262
263
        if ($localCategoryId == 0 || !$remoteCategoryKey || !$remoteCategoryLabel) {
264
            $this->View()->assign([
265
                'success' => false,
266
                'error' => 'Invalid local or remote category',
267
            ]);
268
269
            return;
270
        }
271
272
        try {
273
            list($shopId, $stream) = $this->getCategoryExtractor()->extractNode($node);
274
        } catch (\InvalidArgumentException $e) {
275
            $this->View()->assign([
276
                'success' => false,
277
                'message' => $e->getMessage(),
278
            ]);
279
280
            return;
281
        }
282
283
        if (!$shopId || !$stream) {
284
            $this->View()->assign([
285
                'success' => false,
286
                'message' => 'Node must contain shopId and stream',
287
            ]);
288
289
            return;
290
        }
291
292
        try {
293
            $categories = $this->getImportService()->importRemoteCategoryCreateLocalCategories($localCategoryId, $remoteCategoryKey, $remoteCategoryLabel, $shopId, $stream);
294
        } catch (\RuntimeException $e) {
295
            $this->getLogger()->write(true, $e->getMessage(), $e);
296
            $this->View()->assign([
297
                'success' => false,
298
                'error' => 'Remote category could not be mapped to local category!',
299
            ]);
300
301
            return;
302
        }
303
304
        $this->View()->assign([
305
            'success' => true,
306
            'categories' => $categories,
307
            'shopId' => $shopId,
308
            'stream' => $stream
309
        ]);
310
    }
311
312
    public function getArticleCountForRemoteCategoryAction()
313
    {
314
        $remoteCategoryKey = $this->request->getParam('remoteCategoryKey', '');
315
        $shopId = (int) $this->request->getParam('shopId', 0);
316
        $stream = $this->request->getParam('stream', '');
317
318
        try {
319
            $articleCount = $this->getImportService()->importRemoteCategoryGetArticleCountForCategory($shopId, $remoteCategoryKey, $stream);
320
        } catch (\RuntimeException $e) {
321
            $this->getLogger()->write(true, $e->getMessage(), $e);
322
            $this->View()->assign([
323
                'success' => false,
324
                'error' => 'Articles could not be counted!',
325
            ]);
326
327
            return;
328
        }
329
330
        $this->View()->assign([
331
            'success' => true,
332
            'count' => (int) $articleCount
333
        ]);
334
    }
335
336
    public function assignArticlesToRemoteCategoryAction()
337
    {
338
        $remoteCategoryKey = $this->request->getParam('remoteCategoryKey', '');
339
        $localCategoryId = (int) $this->request->getParam('localCategoryId', 0);
340
        $localParentId = (int) $this->request->getParam('localParentId', 0);
341
        $offset = (int) $this->request->getParam('offset', 0);
342
        $limit = (int) $this->request->getParam('limit', 0);
343
        $shopId = (int) $this->request->getParam('shopId', 0);
344
        $stream = $this->request->getParam('stream', '');
345
346
        try {
347
            $this->getImportService()->importRemoteCategoryAssignArticles($shopId, $remoteCategoryKey, $stream, $localCategoryId, $localParentId, $offset, $limit);
348
        } catch (\RuntimeException $e) {
349
            $this->getLogger()->write(true, $e->getMessage(), $e);
350
            $this->View()->assign([
351
                'success' => false,
352
                'error' => 'Articles could not be assigned to local Categorys!',
353
            ]);
354
355
            return;
356
        }
357
358
        $this->View()->assign([
359
            'success' => true,
360
        ]);
361
    }
362
363
    /**
364
     * Unassign all remote articles from local category
365
     */
366
    public function unassignRemoteToLocalCategoryAction()
367
    {
368
        $localCategoryId = (int) $this->request->getParam('localCategoryId', 0);
369
370
        if ($localCategoryId == 0) {
371
            $this->View()->assign([
372
                'success' => false,
373
                'error' => 'Invalid local or remote category',
374
            ]);
375
376
            return;
377
        }
378
379
        try {
380
            $articleIds = $this->getImportService()->findRemoteArticleIdsByCategoryId($localCategoryId);
381
            $this->getImportService()->unAssignArticleCategories($articleIds);
382
        } catch (\Exception $e) {
383
            $this->getLogger()->write(true, $e->getMessage(), $e);
384
            $this->View()->assign([
385
                'success' => false,
386
                'error' => 'Products from remote category could not be unassigned!',
387
            ]);
388
389
            return;
390
        }
391
392
        $this->View()->assign([
393
            'success' => true
394
        ]);
395
    }
396
397 View Code Duplication
    public function activateArticlesAction()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
398
    {
399
        $articleIds = $this->request->getParam('ids', 0);
400
401
        try {
402
            $this->getImportService()->activateArticles($articleIds);
403
        } catch (\Exception $e) {
404
            $this->getLogger()->write(true, $e->getMessage(), $e);
405
            $this->View()->assign([
406
                'success' => false,
407
                'error' => 'There is a problem with products activation!',
408
            ]);
409
410
            return;
411
        }
412
413
        $this->View()->assign([
414
            'success' => true,
415
        ]);
416
    }
417
418
    /**
419
     * Deactivates connect categories
420
     */
421
    public function deactivateCategoryAction()
422
    {
423
        $categoryId = $this->request->getParam('categoryId', 0);
424
425
        if (!$categoryId) {
426
            return $this->View()->assign([
427
                'success' => false,
428
                'error' => 'Please select a category for deactivation',
429
            ]);
430
        }
431
432
        /** @var \Shopware\Models\Category\Category $category */
433
        $category = $this->getCategoryRepository()->findOneBy(['id' => $categoryId]);
434
435
        if (!$category) {
436
            $this->View()->assign([
437
                'success' => false,
438
                'error' => 'Please select a valid category for deactivation',
439
            ]);
440
        }
441
442
        $categoryIds = $this->getCategoryExtractor()->getCategoryIdsCollection($category);
443
444
        $changedCount = 0;
445
        if (count($categoryIds) > 0) {
446
            $changedCount = $this->getImportService()->deactivateLocalCategoriesByIds($categoryIds);
447
        }
448
449
        $this->View()->assign([
450
            'success' => true,
451
            'deactivatedCategoriesCount' => $changedCount,
452
        ]);
453
    }
454
455
    /**
456
     * @return Enlight_View|Enlight_View_Default
457
     */
458
    public function getSuppliersAction()
459
    {
460
        $suppliers = [];
461
        $pdoGateway = $this->getPdoGateway();
462
463
        foreach ($pdoGateway->getConnectedShopIds() as $shopId) {
464
            $configuration = $pdoGateway->getShopConfiguration($shopId);
465
            $suppliers = [
466
                'id' => $shopId,
467
                'name' => $configuration->displayName,
468
                'logoUrl' => $configuration->logoUrl,
469
            ];
470
        }
471
472
        return $this->View()->assign([
473
            'success' => true,
474
            'data' => $suppliers,
475
        ]);
476
    }
477
478
    public function recreateRemoteCategoriesAction()
479
    {
480
        $this->getAutoCategoryReverter()->recreateRemoteCategories();
481
482
        return $this->View()->assign([
483
            'success' => true,
484
        ]);
485
    }
486
487
    private function getCategoryExtractor()
488
    {
489
        if (!$this->categoryExtractor) {
490
            $modelManager = Shopware()->Models();
491
            $this->categoryExtractor = new \ShopwarePlugins\Connect\Components\CategoryExtractor(
492
                $modelManager->getRepository('Shopware\CustomModels\Connect\Attribute'),
493
                $this->container->get('swagconnect.auto_category_resolver'),
494
                $this->getPdoGateway(),
495
                new \ShopwarePlugins\Connect\Components\RandomStringGenerator(),
496
                Shopware()->Db()
497
            );
498
        }
499
500
        return $this->categoryExtractor;
501
    }
502
503
    /**
504
     * @return \Shopware\Connect\Gateway\PDO
505
     */
506
    private function getPdoGateway()
507
    {
508
        return new \Shopware\Connect\Gateway\PDO(Shopware()->Db()->getConnection());
509
    }
510
511
    /**
512
     * @return \Shopware\CustomModels\Connect\ProductToRemoteCategoryRepository
513
     */
514
    private function getProductToRemoteCategoryRepository()
515
    {
516
        if (!$this->productToRemoteCategoryRepository) {
517
            $this->productToRemoteCategoryRepository = Shopware()->Models()->getRepository(
518
                'Shopware\CustomModels\Connect\ProductToRemoteCategory'
519
            );
520
        }
521
522
        return $this->productToRemoteCategoryRepository;
523
    }
524
525
    /**
526
     * @return \ShopwarePlugins\Connect\Components\ImportService
527
     */
528
    private function getImportService()
529
    {
530
        return $this->container->get('swagconnect.import_service');
531
    }
532
533
    private function getAutoCategoryReverter()
534
    {
535
        return $this->container->get('swagconnect.auto_category_reverter');
536
    }
537
538
    /**
539
     * @return \Shopware\Models\Category\Repository
540
     */
541
    private function getCategoryRepository()
542
    {
543
        if (!$this->categoryRepository) {
544
            $this->categoryRepository = $this->getModelManager()->getRepository('Shopware\Models\Category\Category');
545
        }
546
547
        return $this->categoryRepository;
548
    }
549
550
    private function getLogger()
551
    {
552
        if (!$this->logger) {
553
            $this->logger = new \ShopwarePlugins\Connect\Components\Logger(Shopware()->Db());
554
        }
555
556
        return $this->logger;
557
    }
558
559
    public function connectCategoriesNeedRecoveryAction()
560
    {
561
        $this->View()->assign([
562
            'success' => true,
563
            'data' => [
564
                'recreateConnectCategories' => $this->getHelper()->checkIfConnectCategoriesHaveToBeRecreated(),
565
            ]
566
        ]);
567
    }
568
569
    public function connectCategoriesNeedAdditionalShopIdAction()
570
    {
571
        $this->View()->assign([
572
            'success' => true,
573
            'data' => [
574
                'addShopIdToConnectCategories' => $this->getHelper()->checkIfShopIdHasToBeAddedToConnectCategories(),
575
            ]
576
        ]);
577
    }
578
579
    public function productCountForCategoryRecoveryAction()
580
    {
581
        $this->View()->assign([
582
            'success' => true,
583
            'data' => [
584
                'totalCount' => $this->getHelper()->getProductCountForCategoryRecovery(),
585
            ]
586
        ]);
587
    }
588
}
589