Completed
Pull Request — master (#333)
by Simon
04:01
created

Helper::isMainVariant()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 16
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 16
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 7
nc 2
nop 1
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 Doctrine\DBAL\DBALException;
11
use Shopware\Connect\Struct\Product;
12
use Shopware\Models\Article\Article as ProductModel;
13
use Shopware\Components\Model\ModelManager;
14
use Doctrine\ORM\Query;
15
use Shopware\CustomModels\Connect\Attribute as ConnectAttribute;
16
use Shopware\CustomModels\Connect\Attribute;
17
use Shopware\Models\Article\Detail as ProductDetail;
18
use Shopware\Models\Article\Unit;
19
use Shopware\Models\Customer\Group;
20
use ShopwarePlugins\Connect\Components\Utils\UnitMapper;
21
use ShopwarePlugins\Connect\Struct\ShopProductId;
22
23
/**
24
 * @category  Shopware
25
 * @package   Shopware\Plugins\SwagConnect
26
 */
27
class Helper
28
{
29
    /**
30
     * @var ModelManager
31
     */
32
    private $manager;
33
34
    /**
35
     * @var CategoryQuery
36
     */
37
    private $connectCategoryQuery;
38
39
    /**
40
     * @var ProductQuery
41
     */
42
    private $connectProductQuery;
43
44
    /**
45
     * @param ModelManager $manager
46
     * @param CategoryQuery
47
     * @param ProductQuery
48
     */
49
    public function __construct(
50
        ModelManager $manager,
51
        CategoryQuery $connectCategoryQuery,
52
        ProductQuery $connectProductQuery
53
    ) {
54
        $this->manager = $manager;
55
        $this->connectCategoryQuery = $connectCategoryQuery;
56
        $this->connectProductQuery = $connectProductQuery;
57
    }
58
59
    /**
60
     * @return Group
61
     */
62
    public function getDefaultCustomerGroup()
63
    {
64
        $repository = $this->manager->getRepository('Shopware\Models\Customer\Group');
65
66
        return $repository->findOneBy(['key' => 'EK']);
67
    }
68
69
    /**
70
     * Returns an article model for a given (sdk) product.
71
     *
72
     * @param Product $product
73
     * @param int $mode
74
     * @return null|ProductModel
75
     */
76 View Code Duplication
    public function getArticleModelByProduct(Product $product, $mode = Query::HYDRATE_OBJECT)
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...
77
    {
78
        $builder = $this->manager->createQueryBuilder();
79
        $builder->select(['ba', 'a']);
80
        $builder->from('Shopware\CustomModels\Connect\Attribute', 'ba');
81
        $builder->join('ba.article', 'a');
82
83
        $builder->where('ba.shopId = :shopId AND ba.sourceId = :sourceId');
84
        $query = $builder->getQuery();
85
86
        $query->setParameter('shopId', $product->shopId);
87
        $query->setParameter('sourceId', $product->sourceId);
88
        $result = $query->getResult(
89
            $mode
90
        );
91
92
        if (isset($result[0])) {
93
            $attribute = $result[0];
94
95
            return $attribute->getArticle();
96
        }
97
98
        return null;
99
    }
100
101
    /**
102
     * @param Product $product
103
     * @param int $mode
104
     * @return null|ProductDetail
105
     */
106 View Code Duplication
    public function getArticleDetailModelByProduct(Product $product, $mode = Query::HYDRATE_OBJECT)
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...
107
    {
108
        $builder = $this->manager->createQueryBuilder();
109
        $builder->select(['ba', 'd']);
110
        $builder->from('Shopware\CustomModels\Connect\Attribute', 'ba');
111
        $builder->join('ba.articleDetail', 'd');
112
        $builder->leftJoin('d.attribute', 'at');
113
        $builder->where('ba.shopId = :shopId AND ba.sourceId = :sourceId');
114
115
        $query = $builder->getQuery();
116
        $query->setParameter('shopId', $product->shopId);
117
        $query->setParameter('sourceId', $product->sourceId);
118
119
        $result = $query->getResult(
120
            $mode
121
        );
122
123
        if (isset($result[0])) {
124
            /** @var \Shopware\CustomModels\Connect\Attribute $attribute */
125
            $attribute = $result[0];
126
127
            return $attribute->getArticleDetail();
128
        }
129
130
        return null;
131
    }
132
133
    public function getConnectArticleModel($sourceId, $shopId)
134
    {
135
        $builder = $this->manager->createQueryBuilder();
136
        $builder->select(['ba', 'a']);
137
        $builder->from('Shopware\CustomModels\Connect\Attribute', 'ba');
138
        $builder->join('ba.article', 'a');
139
        $builder->join('a.mainDetail', 'd');
140
        $builder->leftJoin('d.attribute', 'at');
141
142
        $builder->where('ba.shopId = :shopId AND ba.sourceId = :sourceId');
143
        $query = $builder->getQuery();
144
145
        $query->setParameter('shopId', $shopId);
146
        $query->setParameter('sourceId', $sourceId);
147
        $result = $query->getResult(
148
            $query::HYDRATE_OBJECT
149
        );
150
151
        if (isset($result[0])) {
152
            $attribute = $result[0];
153
154
            return $attribute->getArticle();
155
        }
156
157
        return null;
158
    }
159
160
    /**
161
     * @param array $orderNumbers
162
     * @return array
163
     */
164 View Code Duplication
    public function getArticleIdsByNumber(array $orderNumbers)
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...
165
    {
166
        $builder = $this->manager->getConnection()->createQueryBuilder();
167
168
        $rows = $builder->select('d.articleID as articleId')
169
            ->from('s_articles_details', 'd')
170
            ->where('d.ordernumber IN (:orderNumbers)')
171
            ->setParameter('orderNumbers', $orderNumbers, \Doctrine\DBAL\Connection::PARAM_STR_ARRAY)
172
            ->execute()
173
            ->fetchAll();
174
175
        return array_map(function ($row) {
176
            return $row['articleId'];
177
        }, $rows);
178
    }
179
180
    /**
181
     * Returns article detail model by
182
     * given sourceId and shopId
183
     *
184
     * @param string $sourceId
185
     * @param int $shopId
186
     * @return null|ProductDetail
187
     */
188
    public function getConnectArticleDetailModel($sourceId, $shopId)
189
    {
190
        $product = new Product(['sourceId' => $sourceId, 'shopId' => $shopId]);
191
192
        return $this->getArticleDetailModelByProduct($product);
193
    }
194
195
    /**
196
     * Helper to update the connect_items table
197
     */
198
    public function updateConnectProducts()
199
    {
200
        // Insert new articles
201
        $sql = "
202
        INSERT INTO `s_plugin_connect_items` (article_id, article_detail_id, source_id)
203
        SELECT a.id, ad.id, IF(ad.kind = 1, a.id, CONCAT(a.id, '-', ad.id)) as sourceID
204
205
        FROM s_articles a
206
207
        LEFT JOIN `s_articles_details` ad
208
        ON a.id = ad.articleId
209
210
        LEFT JOIN `s_plugin_connect_items` bi
211
        ON bi.article_detail_id = ad.id
212
213
214
        WHERE a.id IS NOT NULL
215
        AND ad.id IS NOT NULL
216
        AND bi.id IS NULL
217
        ";
218
219
        $this->manager->getConnection()->exec($sql);
220
221
        // Delete removed articles from s_plugin_connect_items
222
        $sql = '
223
        DELETE bi FROM `s_plugin_connect_items`  bi
224
225
        LEFT JOIN `s_articles_details` ad
226
        ON ad.id = bi.article_detail_id
227
228
        WHERE ad.id IS NULL
229
        ';
230
231
        $this->manager->getConnection()->exec($sql);
232
    }
233
234
    /**
235
     * Returns a remote connectProduct e.g. for checkout maniputlations
236
     *
237
     * @param array $ids
238
     * @param int $shopId
239
     * @return array
240
     */
241
    public function getRemoteProducts(array $ids, $shopId)
242
    {
243
        return $this->connectProductQuery->getRemote($ids, $shopId);
244
    }
245
246
    /**
247
     * Returns a local connectProduct for export
248
     *
249
     * @param array $sourceIds
250
     * @return Product[]
251
     */
252
    public function getLocalProduct(array $sourceIds)
253
    {
254
        return $this->connectProductQuery->getLocal($sourceIds);
255
    }
256
257
    /**
258
     * Does the current basket contain connect products?
259
     *
260
     * @param $session
261
     * @return bool
262
     */
263
    public function hasBasketConnectProducts($session, $userId = null)
264
    {
265
        $connection = $this->manager->getConnection();
266
        $sql = 'SELECT ob.articleID
267
268
            FROM s_order_basket ob
269
270
            INNER JOIN s_plugin_connect_items bi
271
            ON bi.article_id = ob.articleID
272
            AND bi.shop_id IS NOT NULL
273
274
            WHERE ob.sessionID=?
275
            ';
276
        $whereClause = [$session];
277
278
        if ($userId > 0) {
279
            $sql .= ' OR userID=?';
280
            $whereClause[] = $userId;
281
        }
282
283
        $sql .= ' LIMIT 1';
284
285
        $result = $connection->fetchArray($sql, $whereClause);
286
287
        return !empty($result);
288
    }
289
290
    /**
291
     * Will return the connectAttribute for a given model. The model can be an Article\Article or Article\Detail
292
     *
293
     * @param $model ProductModel|ProductDetail
294
     * @return ConnectAttribute
295
     */
296
    public function getConnectAttributeByModel($model)
297
    {
298
        if (!$model->getId()) {
299
            return false;
300
        }
301
        $repository = $this->manager->getRepository('Shopware\CustomModels\Connect\Attribute');
302
303
        if ($model instanceof ProductModel) {
0 ignored issues
show
Bug introduced by
The class Shopware\Models\Article\Article does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
304
            if (!$model->getMainDetail()) {
305
                return false;
306
            }
307
308
            return $repository->findOneBy(['articleDetailId' => $model->getMainDetail()->getId()]);
309
        } elseif ($model instanceof ProductDetail) {
0 ignored issues
show
Bug introduced by
The class Shopware\Models\Article\Detail does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
310
            return $repository->findOneBy(['articleDetailId' => $model->getId()]);
311
        }
312
313
        return false;
314
    }
315
316
    /**
317
     * Returns connectAttributes for all article details by given article object
318
     *
319
     * @param ProductModel $article
320
     * @return \Shopware\CustomModels\Connect\Attribute[]
321
     */
322
    public function getConnectAttributesByArticle(ProductModel $article)
323
    {
324
        $builder = $this->manager->createQueryBuilder();
325
        $builder->select(['connectAttribute', 'detail']);
326
        $builder->from('Shopware\CustomModels\Connect\Attribute', 'connectAttribute');
327
        $builder->innerJoin('connectAttribute.articleDetail', 'detail');
328
329
        $builder->where('connectAttribute.articleId = :articleId');
330
        $query = $builder->getQuery();
331
332
        $query->setParameter('articleId', $article->getId());
333
334
        return $query->getResult();
335
    }
336
337
    /**
338
     * Returns true when product is exported to Connect
339
     *
340
     * @param Attribute $connectAttribute
341
     * @return bool
342
     */
343
    public function isProductExported(Attribute $connectAttribute)
344
    {
345
        $status = $connectAttribute->getExportStatus();
346
        if ($connectAttribute->isExported()) {
347
            return true;
348
        }
349
350
        if ($status == Attribute::STATUS_INSERT) {
351
            return true;
352
        }
353
354
        if ($status == Attribute::STATUS_UPDATE) {
355
            return true;
356
        }
357
358
        if ($status == Attribute::STATUS_SYNCED) {
359
            return true;
360
        }
361
362
        return false;
363
    }
364
365
    /**
366
     * Verifies that at least one variant from
367
     * same article is exported.
368
     *
369
     * @param Attribute $connectAttribute
370
     * @return bool
371
     */
372
    public function hasExportedVariants(Attribute $connectAttribute)
373
    {
374
        $builder = $this->manager->getConnection()->createQueryBuilder();
375
        $builder->select('COUNT(spci.id)')
376
            ->from('s_plugin_connect_items', 'spci')
377
            ->where('spci.article_id = :articleId AND spci.export_status IN (:exportStatus) AND spci.shop_id IS NULL')
378
            ->setParameter('articleId', $connectAttribute->getArticleId(), \PDO::PARAM_INT)
379
            ->setParameter(
380
                ':exportStatus',
381
                [Attribute::STATUS_INSERT, Attribute::STATUS_UPDATE, Attribute::STATUS_SYNCED],
382
                \Doctrine\DBAL\Connection::PARAM_STR_ARRAY
383
            );
384
385
        return $builder->execute()->fetchColumn() > 0;
386
    }
387
388
    /**
389
     * Helper method to create a connect attribute on the fly
390
     *
391
     * @param $model
392
     * @throws \RuntimeException
393
     * @return ConnectAttribute
394
     */
395
    public function getOrCreateConnectAttributeByModel($model)
396
    {
397
        $attribute = $this->getConnectAttributeByModel($model);
398
399
        if (!$attribute) {
400
            $attribute = new ConnectAttribute();
401
            $attribute->setPurchasePriceHash('');
402
            $attribute->setOfferValidUntil('');
403
            $attribute->setStream('');
404
405
            if ($model instanceof ProductModel) {
0 ignored issues
show
Bug introduced by
The class Shopware\Models\Article\Article does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
406
                $attribute->setArticle($model);
407
                $attribute->setArticleDetail($model->getMainDetail());
408
                $attribute->setSourceId(
409
                    $this->generateSourceId($model->getMainDetail())
410
                );
411
            } elseif ($model instanceof ProductDetail) {
0 ignored issues
show
Bug introduced by
The class Shopware\Models\Article\Detail does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
412
                $attribute->setArticle($model->getArticle());
413
                $attribute->setArticleDetail($model);
414
                $attribute->setSourceId(
415
                    $this->generateSourceId($model)
416
                );
417
            } else {
418
                throw new \RuntimeException('Passed model needs to be an article or an article detail');
419
            }
420
            $this->manager->persist($attribute);
421
            $this->manager->flush($attribute);
422
        }
423
424
        return $attribute;
425
    }
426
427
    /**
428
     * Returns connect attributes for article
429
     * and all variants.
430
     * If connect attribute does not exist
431
     * it will be created.
432
     *
433
     * @param ProductModel $article
434
     * @return array
435
     */
436
    public function getOrCreateConnectAttributes(ProductModel $article)
437
    {
438
        $attributes = [];
439
        /** @var \Shopware\Models\Article\Detail $detail */
440
        foreach ($article->getDetails() as $detail) {
441
            $attributes[] = $this->getOrCreateConnectAttributeByModel($detail);
442
        }
443
444
        return $attributes;
445
    }
446
447
    /**
448
     * Generate sourceId
449
     *
450
     * @param ProductDetail $detail
451
     * @return string
452
     */
453
    public function generateSourceId(ProductDetail $detail)
454
    {
455
        if ($detail->getKind() == 1) {
456
            $sourceId = (string) $detail->getArticle()->getId();
457
        } else {
458
            $sourceId = sprintf(
459
                '%s-%s',
460
                $detail->getArticle()->getId(),
461
                $detail->getId()
462
            );
463
        }
464
465
        return $sourceId;
466
    }
467
468
    /**
469
     * @param $id
470
     * @return array
471
     */
472
    public function getConnectCategoryForProduct($id)
473
    {
474
        return $this->connectCategoryQuery->getConnectCategoryForProduct($id);
475
    }
476
477
    public function getMostRelevantConnectCategory($categories)
478
    {
479
        usort(
480
            $categories,
481
            [
482
                $this->connectCategoryQuery->getRelevanceSorter(),
483
                'sortConnectCategoriesByRelevance'
484
            ]
485
        );
486
487
        return array_pop($categories);
488
    }
489
490
    /**
491
     * Defines the update flags
492
     *
493
     * @return array
494
     */
495
    public function getUpdateFlags()
496
    {
497
        return [2 => 'shortDescription', 4 => 'longDescription', 8 => 'name', 16 => 'image', 32 => 'price', 64 => 'imageInitialImport', 128 => 'additionalDescription'];
498
    }
499
500
    /**
501
     * Returns shopware unit entity
502
     *
503
     * @param $unitKey
504
     * @return \Shopware\Models\Article\Unit
505
     */
506
    public function getUnit($unitKey)
507
    {
508
        $repository = $this->manager->getRepository('Shopware\Models\Article\Unit');
509
510
        return $repository->findOneBy(['unit' => $unitKey]);
511
    }
512
513
    /**
514
     * Clear article cache
515
     */
516
    public function clearArticleCache($articleId)
517
    {
518
        Shopware()->Events()->notify(
519
            'Shopware_Plugins_HttpCache_InvalidateCacheId',
520
            ['cacheId' => 'a' . $articleId]
521
        );
522
    }
523
524
    /**
525
     * Replace unit and ref quantity
526
     * @param $products
527
     * @return mixed
528
     */
529
    public function prepareConnectUnit($products)
530
    {
531
        foreach ($products as &$p) {
532
            if ($p->attributes['unit']) {
533
                $configComponent = new Config($this->manager);
534
                /** @var \ShopwarePlugins\Connect\Components\Utils\UnitMapper $unitMapper */
535
                $unitMapper = new UnitMapper(
536
                    $configComponent,
537
                    $this->manager
538
                );
539
540
                $p->attributes['unit'] = $unitMapper->getConnectUnit($p->attributes['unit']);
541
            }
542
543
            if ($p->attributes['ref_quantity']) {
544
                $intRefQuantity = (int) $p->attributes['ref_quantity'];
545
                if ($p->attributes['ref_quantity'] - $intRefQuantity <= 0.0001) {
546
                    $p->attributes['ref_quantity'] = $intRefQuantity;
547
                }
548
            }
549
        }
550
551
        return $products;
552
    }
553
554
    /**
555
     * Removes connect reservation from session
556
     */
557
    public function clearConnectReservation()
558
    {
559
        Shopware()->Session()->connectReservation = null;
560
    }
561
562
    /**
563
     * Collect sourceIds by given article ids
564
     *
565
     * @param array $articleIds
566
     * @return array
567
     */
568
    public function getArticleSourceIds(array $articleIds)
569
    {
570
        if (empty($articleIds)) {
571
            return [];
572
        }
573
574
        return array_merge(
575
            $this->getSourceIds($articleIds, 1),
576
            $this->getSourceIds($articleIds, 2)
577
        );
578
    }
579
580
    private function getSourceIds(array $articleIds, $kind)
581
    {
582
        $customProductsTableExists = false;
583
        try {
584
            $builder = $this->manager->getConnection()->createQueryBuilder();
585
            $builder->select('id');
586
            $builder->from('s_plugin_custom_products_template');
587
            $builder->setMaxResults(1);
588
            $builder->execute()->fetch();
589
590
            $customProductsTableExists = true;
591
        } catch (DBALException $e) {
0 ignored issues
show
Bug introduced by
The class Doctrine\DBAL\DBALException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
592
            // ignore it
593
            // custom products is not installed
594
        }
595
596
        // main variants should be collected first, because they
597
        // should be exported first. Connect uses first variant product with an unknown groupId as main one.
598
        $builder = $this->manager->getConnection()->createQueryBuilder();
599
        $builder->select('spci.source_id')
600
            ->from('s_plugin_connect_items', 'spci')
601
            ->rightJoin('spci', 's_articles_details', 'sad', 'spci.article_detail_id = sad.id')
602
            ->where('sad.articleID IN (:articleIds) AND sad.kind = :kind AND spci.shop_id IS NULL')
603
            ->setParameter(':articleIds', $articleIds, \Doctrine\DBAL\Connection::PARAM_INT_ARRAY)
604
            ->setParameter('kind', $kind, \PDO::PARAM_INT);
605
606
        if ($customProductsTableExists) {
607
            $builder->leftJoin('spci', 's_plugin_custom_products_template_product_relation', 'spcptpr', 'spci.article_id = spcptpr.article_id')
608
                ->andWhere('spcptpr.template_id IS NULL');
609
        }
610
611
        return $builder->execute()->fetchAll(\PDO::FETCH_COLUMN);
612
    }
613
614
    /**
615
     * Get ShopProductId struct by given article detail id
616
     * It contains product sourceId and shopId.
617
     * If $articleDetailId is local product, $shopProductId->shopId will be null.
618
     *
619
     * @param int $articleDetailId
620
     * @return ShopProductId
621
     */
622
    public function getShopProductId($articleDetailId)
623
    {
624
        $articleDetailId = (int) $articleDetailId;
625
        $builder = $this->manager->getConnection()->createQueryBuilder();
626
        $builder->select('items.source_id as sourceId, items.shop_id as shopId')
627
            ->from('s_plugin_connect_items', 'items')
628
            ->where('items.article_detail_id = :articleDetailIds')
629
            ->setParameter(':articleDetailIds', $articleDetailId);
630
631
        $result = $builder->execute()->fetch(\PDO::FETCH_ASSOC);
632
633
        return new ShopProductId($result);
634
    }
635
636
    /**
637
     * Check if given articleDetailId is remote product
638
     *
639
     * @param int $articleDetailId
640
     * @return bool
641
     */
642
    public function isRemoteArticleDetail($articleDetailId)
643
    {
644
        $articleDetailId = (int) $articleDetailId;
645
        $articleDetailRepository = $this->manager->getRepository('Shopware\Models\Article\Detail');
646
        /** @var \Shopware\Models\Article\Detail $detail */
647
        $detail = $articleDetailRepository->find($articleDetailId);
648
        if (!$detail) {
649
            return false;
650
        }
651
652
        $connectAttribute = $this->getConnectAttributeByModel($detail);
653
        if (!$connectAttribute) {
654
            return false;
655
        }
656
657
        return ($connectAttribute->getShopId() != null);
658
    }
659
660
    /**
661
     * Check if given articleDetailId is remote product
662
     *
663
     * @param int $articleDetailId
664
     * @return bool
665
     */
666
    public function isRemoteArticleDetailDBAL($articleDetailId)
667
    {
668
        $articleDetailId = (int) $articleDetailId;
669
        $builder = $this->manager->getConnection()->createQueryBuilder();
670
        $builder->select('items.shop_id')
671
            ->from('s_plugin_connect_items', 'items')
672
            ->where('items.article_detail_id = :articleDetailId')
673
            ->setParameter(':articleDetailId', $articleDetailId);
674
675
        return (bool) $builder->execute()->fetchColumn();
676
    }
677
678
    /**
679
     * Extract article ID and detail ID
680
     * from source ID
681
     *
682
     * @param $sourceId
683
     * @return array
684
     */
685
    public function explodeArticleId($sourceId)
686
    {
687
        $articleId = explode('-', $sourceId);
688
689
        if (isset($articleId[1]) && isset($articleId[1])) {
690
            return $articleId;
691
        }
692
693
        return [
694
            $articleId[0]
695
        ];
696
    }
697
698
    /**
699
     * Creates Shopware product model
700
     *
701
     * @param Product $product
702
     * @return ProductModel
703
     */
704
    public function createProductModel(Product $product)
705
    {
706
        //todo@sb: Add test
707
        $model = new ProductModel();
708
        $model->setActive(false);
709
        $model->setName($product->title);
710
        $this->manager->persist($model);
711
712
        return $model;
713
    }
714
715
    /**
716
     * Returns main article detail by given groupId
717
     *
718
     * @param $product
719
     * @param int $mode
720
     * @return null|ProductModel
721
     */
722 View Code Duplication
    public function getArticleByRemoteProduct(Product $product, $mode = Query::HYDRATE_OBJECT)
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...
723
    {
724
        $builder = $this->manager->createQueryBuilder();
725
        $builder->select(['ba', 'd']);
726
        $builder->from('Shopware\CustomModels\Connect\Attribute', 'ba');
727
        $builder->join('ba.articleDetail', 'd');
728
        $builder->leftJoin('d.attribute', 'at');
729
730
        $builder->where('ba.groupId = :groupId AND ba.isMainVariant = 1 AND ba.shopId = :shopId');
731
        $query = $builder->getQuery();
732
733
        $query->setParameter('groupId', $product->groupId);
734
        $query->setParameter('shopId', $product->shopId);
735
        $result = $query->getResult(
736
            $mode
737
        );
738
739
        if (isset($result[0])) {
740
            /** @var \Shopware\CustomModels\Connect\Attribute $attribute */
741
            $attribute = $result[0];
742
743
            return $attribute->getArticle();
744
        }
745
746
        return null;
747
    }
748
749
    /**
750
     * @param $articleId
751
     * @return array
752
     */
753
    public function getSourceIdsFromArticleId($articleId)
754
    {
755
        $rows = $this->manager->getConnection()->fetchAll(
756
            'SELECT source_id FROM s_plugin_connect_items WHERE article_id = ?',
757
            [$articleId]
758
        );
759
760
        return array_map(function ($row) {
761
            return $row['source_id'];
762
        }, $rows);
763
    }
764
765
    /**
766
     * @param Unit $localUnit
767
     * @param string $remoteUnit
768
     */
769
    public function updateUnitInRelatedProducts(Unit $localUnit, $remoteUnit)
770
    {
771
        $statement = $this->manager->getConnection()->prepare('UPDATE s_articles_details sad
772
            LEFT JOIN s_articles_attributes saa ON sad.id = saa.articledetailsID
773
            SET sad.unitID = :unitId
774
            WHERE saa.connect_remote_unit = :remoteUnit');
775
776
        $statement->bindValue(':unitId', $localUnit->getId(), \PDO::PARAM_INT);
777
        $statement->bindValue(':remoteUnit', $remoteUnit, \PDO::PARAM_STR);
778
779
        $statement->execute();
780
    }
781
782
    /**
783
     * Checks whether given sourceId is main variant.
784
     * Works only with local products.
785
     * SourceIds pattern is articleId-variantId (58-142)
786
     *
787
     * For remote product check is_main_variant flag in
788
     * s_plugin_connect_items
789
     *
790
     * @param string $sourceId
791
     * @return bool
792
     */
793
    public function isMainVariant($sourceId)
794
    {
795
        $isMainVariant = $this->manager->getConnection()->fetchColumn(
796
            'SELECT d.kind
797
              FROM s_plugin_connect_items spci
798
              LEFT JOIN s_articles_details d ON spci.article_detail_id = d.id
799
              WHERE source_id = ?',
800
            [$sourceId]
801
        );
802
803
        if ($isMainVariant != 1) {
804
            return false;
805
        }
806
807
        return true;
808
    }
809
810
    /**
811
     * @return array
812
     */
813 View Code Duplication
    public function getAllNonConnectArticleIds()
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...
814
    {
815
        $builder = $this->manager->getConnection()->createQueryBuilder();
816
        $builder->select('DISTINCT spci.article_id');
817
        $builder->from('s_plugin_connect_items', 'spci');
818
        $builder->where('spci.shop_id IS NULL');
819
820
        $result = $builder->execute()->fetchAll();
821
822
        return array_map(function ($row) {
823
            return $row['article_id'];
824
        }, $result);
825
    }
826
}
827