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

Helper::getArticleModelByProduct()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 24
Code Lines 15

Duplication

Lines 23
Ratio 95.83 %

Importance

Changes 0
Metric Value
dl 23
loc 24
rs 8.9713
c 0
b 0
f 0
cc 2
eloc 15
nc 2
nop 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 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\Article\Image;
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
    private $connectCategoryQuery;
35
36
    /** @var \ShopwarePlugins\Connect\Components\ProductQuery */
37
    private $connectProductQuery;
38
39
    /**
40
     * @param ModelManager $manager
41
     * @param CategoryQuery
42
     * @param ProductQuery
43
     */
44
    public function __construct(
45
        ModelManager $manager,
46
        CategoryQuery $connectCategoryQuery,
47
        ProductQuery $connectProductQuery
48
    ) {
49
        $this->manager = $manager;
50
        $this->connectCategoryQuery = $connectCategoryQuery;
51
        $this->connectProductQuery = $connectProductQuery;
52
    }
53
54
    /**
55
     * @return \Shopware\Models\Customer\Group
56
     */
57
    public function getDefaultCustomerGroup()
58
    {
59
        $repository = $this->manager->getRepository('Shopware\Models\Customer\Group');
60
        $customerGroup = $repository->findOneBy(['key' => 'EK']);
61
62
        return $customerGroup;
63
    }
64
65
    /**
66
     * Returns an article model for a given (sdk) product.
67
     *
68
     * @param Product $product
69
     * @param int $mode
70
     * @return null|ProductModel
71
     */
72 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...
73
    {
74
        $builder = $this->manager->createQueryBuilder();
75
        $builder->select(['ba', 'a']);
76
        $builder->from('Shopware\CustomModels\Connect\Attribute', 'ba');
77
        $builder->join('ba.article', 'a');
78
79
        $builder->where('ba.shopId = :shopId AND ba.sourceId = :sourceId');
80
        $query = $builder->getQuery();
81
82
        $query->setParameter('shopId', $product->shopId);
83
        $query->setParameter('sourceId', $product->sourceId);
84
        $result = $query->getResult(
85
            $mode
86
        );
87
88
        if (isset($result[0])) {
89
            $attribute = $result[0];
90
91
            return $attribute->getArticle();
92
        }
93
94
        return null;
95
    }
96
97
    /**
98
     * @param Product $product
99
     * @param int $mode
100
     * @return null|ProductDetail
101
     */
102 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...
103
    {
104
        $builder = $this->manager->createQueryBuilder();
105
        $builder->select(['ba', 'd']);
106
        $builder->from('Shopware\CustomModels\Connect\Attribute', 'ba');
107
        $builder->join('ba.articleDetail', 'd');
108
        $builder->leftJoin('d.attribute', 'at');
109
        $builder->where('ba.shopId = :shopId AND ba.sourceId = :sourceId');
110
111
        $query = $builder->getQuery();
112
        $query->setParameter('shopId', $product->shopId);
113
        $query->setParameter('sourceId', $product->sourceId);
114
115
        $result = $query->getResult(
116
            $mode
117
        );
118
119
        if (isset($result[0])) {
120
            /** @var \Shopware\CustomModels\Connect\Attribute $attribute */
121
            $attribute = $result[0];
122
123
            return $attribute->getArticleDetail();
124
        }
125
126
        return null;
127
    }
128
129
    public function getConnectArticleModel($sourceId, $shopId)
130
    {
131
        $builder = $this->manager->createQueryBuilder();
132
        $builder->select(['ba', 'a']);
133
        $builder->from('Shopware\CustomModels\Connect\Attribute', 'ba');
134
        $builder->join('ba.article', 'a');
135
        $builder->join('a.mainDetail', 'd');
136
        $builder->leftJoin('d.attribute', 'at');
137
138
        $builder->where('ba.shopId = :shopId AND ba.sourceId = :sourceId');
139
        $query = $builder->getQuery();
140
141
        $query->setParameter('shopId', $shopId);
142
        $query->setParameter('sourceId', $sourceId);
143
        $result = $query->getResult(
144
            $query::HYDRATE_OBJECT
145
        );
146
147
        if (isset($result[0])) {
148
            $attribute = $result[0];
149
150
            return $attribute->getArticle();
151
        }
152
153
        return null;
154
    }
155
156
    /**
157
     * @param array $orderNumbers
158
     * @return array
159
     */
160 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...
161
    {
162
        $builder = $this->manager->getConnection()->createQueryBuilder();
163
164
        $rows = $builder->select('d.articleID as articleId')
165
            ->from('s_articles_details', 'd')
166
            ->where('d.ordernumber IN (:orderNumbers)')
167
            ->setParameter('orderNumbers', $orderNumbers, \Doctrine\DBAL\Connection::PARAM_STR_ARRAY)
168
            ->execute()
169
            ->fetchAll();
170
171
        return array_map(function ($row) {
172
            return $row['articleId'];
173
        }, $rows);
174
    }
175
176
    /**
177
     * Returns article detail model by
178
     * given sourceId and shopId
179
     *
180
     * @param string $sourceId
181
     * @param int $shopId
182
     * @return null|ProductDetail
183
     */
184
    public function getConnectArticleDetailModel($sourceId, $shopId)
185
    {
186
        $product = new Product(['sourceId' => $sourceId, 'shopId' => $shopId]);
187
188
        return $this->getArticleDetailModelByProduct($product);
189
    }
190
191
    /**
192
     * Helper to update the connect_items table
193
     */
194
    public function updateConnectProducts()
195
    {
196
        // Insert new articles
197
        $sql = "
198
        INSERT INTO `s_plugin_connect_items` (article_id, article_detail_id, source_id)
199
        SELECT a.id, ad.id, IF(ad.kind = 1, a.id, CONCAT(a.id, '-', ad.id)) as sourceID
200
201
        FROM s_articles a
202
203
        LEFT JOIN `s_articles_details` ad
204
        ON a.id = ad.articleId
205
206
        LEFT JOIN `s_plugin_connect_items` bi
207
        ON bi.article_detail_id = ad.id
208
209
210
        WHERE a.id IS NOT NULL
211
        AND ad.id IS NOT NULL
212
        AND bi.id IS NULL
213
        ";
214
215
        $this->manager->getConnection()->exec($sql);
216
217
        // Delete removed articles from s_plugin_connect_items
218
        $sql = '
219
        DELETE bi FROM `s_plugin_connect_items`  bi
220
221
        LEFT JOIN `s_articles_details` ad
222
        ON ad.id = bi.article_detail_id
223
224
        WHERE ad.id IS NULL
225
        ';
226
227
        $this->manager->getConnection()->exec($sql);
228
    }
229
230
    /**
231
     * Returns a remote connectProduct e.g. for checkout maniputlations
232
     *
233
     * @param array $ids
234
     * @param int $shopId
235
     * @return array
236
     */
237
    public function getRemoteProducts(array $ids, $shopId)
238
    {
239
        return $this->connectProductQuery->getRemote($ids, $shopId);
240
    }
241
242
    /**
243
     * Returns a local connectProduct for export
244
     *
245
     * @param array $sourceIds
246
     * @return Product[]
247
     */
248
    public function getLocalProduct(array $sourceIds)
249
    {
250
        return $this->connectProductQuery->getLocal($sourceIds);
251
    }
252
253
    /**
254
     * Does the current basket contain connect products?
255
     *
256
     * @param $session
257
     * @return bool
258
     */
259
    public function hasBasketConnectProducts($session, $userId = null)
260
    {
261
        $connection = $this->manager->getConnection();
262
        $sql = 'SELECT ob.articleID
263
264
            FROM s_order_basket ob
265
266
            INNER JOIN s_plugin_connect_items bi
267
            ON bi.article_id = ob.articleID
268
            AND bi.shop_id IS NOT NULL
269
270
            WHERE ob.sessionID=?
271
            ';
272
        $whereClause = [$session];
273
274
        if ($userId > 0) {
275
            $sql .= ' OR userID=?';
276
            $whereClause[] = $userId;
277
        }
278
279
        $sql .= ' LIMIT 1';
280
281
        $result = $connection->fetchArray($sql, $whereClause);
282
283
        return !empty($result);
284
    }
285
286
    /**
287
     * Will return the connectAttribute for a given model. The model can be an Article\Article or Article\Detail
288
     *
289
     * @param $model ProductModel|ProductDetail
290
     * @return ConnectAttribute
291
     */
292
    public function getConnectAttributeByModel($model)
293
    {
294
        if (!$model->getId()) {
295
            return false;
296
        }
297
        $repository = $this->manager->getRepository('Shopware\CustomModels\Connect\Attribute');
298
299
        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...
300
            if (!$model->getMainDetail()) {
301
                return false;
302
            }
303
304
            return $repository->findOneBy(['articleDetailId' => $model->getMainDetail()->getId()]);
305
        } 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...
306
            return $repository->findOneBy(['articleDetailId' => $model->getId()]);
307
        }
308
309
        return false;
310
    }
311
312
    /**
313
     * Returns connectAttributes for all article details by given article object
314
     *
315
     * @param ProductModel $article
316
     * @return \Shopware\CustomModels\Connect\Attribute[]
317
     */
318
    public function getConnectAttributesByArticle(ProductModel $article)
319
    {
320
        $builder = $this->manager->createQueryBuilder();
321
        $builder->select(['connectAttribute', 'detail']);
322
        $builder->from('Shopware\CustomModels\Connect\Attribute', 'connectAttribute');
323
        $builder->innerJoin('connectAttribute.articleDetail', 'detail');
324
325
        $builder->where('connectAttribute.articleId = :articleId');
326
        $query = $builder->getQuery();
327
328
        $query->setParameter('articleId', $article->getId());
329
330
        return $query->getResult();
331
    }
332
333
    /**
334
     * Returns true when product is exported to Connect
335
     *
336
     * @param Attribute $connectAttribute
337
     * @return bool
338
     */
339
    public function isProductExported(Attribute $connectAttribute)
340
    {
341
        $status = $connectAttribute->getExportStatus();
342
        if ($connectAttribute->isExported()) {
343
            return true;
344
        }
345
346
        if ($status == Attribute::STATUS_INSERT) {
347
            return true;
348
        }
349
350
        if ($status == Attribute::STATUS_UPDATE) {
351
            return true;
352
        }
353
354
        if ($status == Attribute::STATUS_SYNCED) {
355
            return true;
356
        }
357
358
        return false;
359
    }
360
361
    /**
362
     * Verifies that at least one variant from
363
     * same article is exported.
364
     *
365
     * @param Attribute $connectAttribute
366
     * @return bool
367
     */
368
    public function hasExportedVariants(Attribute $connectAttribute)
369
    {
370
        $builder = $this->manager->getConnection()->createQueryBuilder();
371
        $builder->select('COUNT(spci.id)')
372
            ->from('s_plugin_connect_items', 'spci')
373
            ->where('spci.article_id = :articleId AND spci.export_status IN (:exportStatus) AND spci.shop_id IS NULL')
374
            ->setParameter('articleId', $connectAttribute->getArticleId(), \PDO::PARAM_INT)
375
            ->setParameter(
376
                ':exportStatus',
377
                [Attribute::STATUS_INSERT, Attribute::STATUS_UPDATE, Attribute::STATUS_SYNCED],
378
                \Doctrine\DBAL\Connection::PARAM_STR_ARRAY
379
            );
380
381
        return $builder->execute()->fetchColumn() > 0;
382
    }
383
384
    /**
385
     * Helper method to create a connect attribute on the fly
386
     *
387
     * @param $model
388
     * @throws \RuntimeException
389
     * @return ConnectAttribute
390
     */
391
    public function getOrCreateConnectAttributeByModel($model)
392
    {
393
        $attribute = $this->getConnectAttributeByModel($model);
394
395
        if (!$attribute) {
396
            $attribute = new ConnectAttribute();
397
            $attribute->setPurchasePriceHash('');
398
            $attribute->setOfferValidUntil('');
399
            $attribute->setStream('');
400
401
            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...
402
                $attribute->setArticle($model);
403
                $attribute->setArticleDetail($model->getMainDetail());
404
                $attribute->setSourceId(
405
                    $this->generateSourceId($model->getMainDetail())
406
                );
407
            } 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...
408
                $attribute->setArticle($model->getArticle());
409
                $attribute->setArticleDetail($model);
410
                $attribute->setSourceId(
411
                    $this->generateSourceId($model)
412
                );
413
            } else {
414
                throw new \RuntimeException('Passed model needs to be an article or an article detail');
415
            }
416
            $this->manager->persist($attribute);
417
            $this->manager->flush($attribute);
418
        }
419
420
        return $attribute;
421
    }
422
423
    /**
424
     * Returns connect attributes for article
425
     * and all variants.
426
     * If connect attribute does not exist
427
     * it will be created.
428
     *
429
     * @param ProductModel $article
430
     * @return array
431
     */
432
    public function getOrCreateConnectAttributes(ProductModel $article)
433
    {
434
        $attributes = [];
435
        /** @var \Shopware\Models\Article\Detail $detail */
436
        foreach ($article->getDetails() as $detail) {
437
            $attributes[] = $this->getOrCreateConnectAttributeByModel($detail);
438
        }
439
440
        return $attributes;
441
    }
442
443
    /**
444
     * Generate sourceId
445
     *
446
     * @param ProductDetail $detail
447
     * @return string
448
     */
449
    public function generateSourceId(ProductDetail $detail)
450
    {
451
        if ($detail->getKind() == 1) {
452
            $sourceId = (string) $detail->getArticle()->getId();
453
        } else {
454
            $sourceId = sprintf(
455
                '%s-%s',
456
                $detail->getArticle()->getId(),
457
                $detail->getId()
458
            );
459
        }
460
461
        return $sourceId;
462
    }
463
464
    /**
465
     * @param $id
466
     * @return array
467
     */
468
    public function getConnectCategoryForProduct($id)
469
    {
470
        return $this->getCategoryQuery()->getConnectCategoryForProduct($id);
471
    }
472
473
    /**
474
     * @param Product $product
475
     * @return \Shopware\Models\Category\Category[]
476
     */
477
    public function getCategoriesByProduct(Product $product)
478
    {
479
        return $this->getCategoryQuery()->getCategoriesByProduct($product);
480
    }
481
482
    protected function getCategoryQuery()
483
    {
484
        return $this->connectCategoryQuery;
485
    }
486
487
    public function getMostRelevantConnectCategory($categories)
488
    {
489
        usort(
490
            $categories,
491
            [
492
                $this->getCategoryQuery()->getRelevanceSorter(),
493
                'sortConnectCategoriesByRelevance'
494
            ]
495
        );
496
497
        return array_pop($categories);
498
    }
499
500
    /**
501
     * Defines the update flags
502
     *
503
     * @return array
504
     */
505
    public function getUpdateFlags()
506
    {
507
        return [2 => 'shortDescription', 4 => 'longDescription', 8 => 'name', 16 => 'image', 32 => 'price', 64 => 'imageInitialImport', 128 => 'additionalDescription'];
508
    }
509
510
    /**
511
     * Returns shopware unit entity
512
     *
513
     * @param $unitKey
514
     * @return \Shopware\Models\Article\Unit
515
     */
516
    public function getUnit($unitKey)
517
    {
518
        $repository = $this->manager->getRepository('Shopware\Models\Article\Unit');
519
520
        return $repository->findOneBy(['unit' => $unitKey]);
521
    }
522
523
    /**
524
     * Clear article cache
525
     */
526
    public function clearArticleCache($articleId)
527
    {
528
        Shopware()->Events()->notify(
529
            'Shopware_Plugins_HttpCache_InvalidateCacheId',
530
            ['cacheId' => 'a' . $articleId]
531
        );
532
    }
533
534
    /**
535
     * Replace unit and ref quantity
536
     * @param $products
537
     * @return mixed
538
     */
539
    public function prepareConnectUnit($products)
540
    {
541
        foreach ($products as &$p) {
542
            if ($p->attributes['unit']) {
543
                $configComponent = new Config($this->manager);
544
                /** @var \ShopwarePlugins\Connect\Components\Utils\UnitMapper $unitMapper */
545
                $unitMapper = new UnitMapper(
546
                    $configComponent,
547
                    $this->manager
548
                );
549
550
                $p->attributes['unit'] = $unitMapper->getConnectUnit($p->attributes['unit']);
551
            }
552
553
            if ($p->attributes['ref_quantity']) {
554
                $intRefQuantity = (int) $p->attributes['ref_quantity'];
555
                if ($p->attributes['ref_quantity'] - $intRefQuantity <= 0.0001) {
556
                    $p->attributes['ref_quantity'] = $intRefQuantity;
557
                }
558
            }
559
        }
560
561
        return $products;
562
    }
563
564
    /**
565
     * Removes connect reservation from session
566
     */
567
    public function clearConnectReservation()
568
    {
569
        Shopware()->Session()->connectReservation = null;
570
    }
571
572
    /**
573
     * Collect sourceIds by given article ids
574
     *
575
     * @param array $articleIds
576
     * @return array
577
     */
578
    public function getArticleSourceIds(array $articleIds)
579
    {
580
        if (empty($articleIds)) {
581
            return [];
582
        }
583
584
        return array_merge(
585
            $this->getSourceIds($articleIds, 1),
586
            $this->getSourceIds($articleIds, 2)
587
        );
588
    }
589
590
    private function getSourceIds(array $articleIds, $kind)
591
    {
592
        $customProductsTableExists = false;
593
        try {
594
            $builder = $this->manager->getConnection()->createQueryBuilder();
595
            $builder->select('id');
596
            $builder->from('s_plugin_custom_products_template');
597
            $builder->setMaxResults(1);
598
            $builder->execute()->fetch();
599
600
            $customProductsTableExists = true;
601
        } 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...
602
            // ignore it
603
            // custom products is not installed
604
        }
605
606
        // main variants should be collected first, because they
607
        // should be exported first. Connect uses first variant product with an unknown groupId as main one.
608
        $builder = $this->manager->getConnection()->createQueryBuilder();
609
        $builder->select('spci.source_id')
610
            ->from('s_plugin_connect_items', 'spci')
611
            ->rightJoin('spci', 's_articles_details', 'sad', 'spci.article_detail_id = sad.id')
612
            ->where('sad.articleID IN (:articleIds) AND sad.kind = :kind AND spci.shop_id IS NULL')
613
            ->setParameter(':articleIds', $articleIds, \Doctrine\DBAL\Connection::PARAM_INT_ARRAY)
614
            ->setParameter('kind', $kind, \PDO::PARAM_INT);
615
616
        if ($customProductsTableExists) {
617
            $builder->leftJoin('spci', 's_plugin_custom_products_template_product_relation', 'spcptpr', 'spci.article_id = spcptpr.article_id')
618
                ->andWhere('spcptpr.template_id IS NULL');
619
        }
620
621
        return $builder->execute()->fetchAll(\PDO::FETCH_COLUMN);
622
    }
623
624
    /**
625
     * Get ShopProductId struct by given article detail id
626
     * It contains product sourceId and shopId.
627
     * If $articleDetailId is local product, $shopProductId->shopId will be null.
628
     *
629
     * @param int $articleDetailId
630
     * @return ShopProductId
631
     */
632
    public function getShopProductId($articleDetailId)
633
    {
634
        $articleDetailId = (int) $articleDetailId;
635
        $builder = $this->manager->getConnection()->createQueryBuilder();
636
        $builder->select('items.source_id as sourceId, items.shop_id as shopId')
637
            ->from('s_plugin_connect_items', 'items')
638
            ->where('items.article_detail_id = :articleDetailIds')
639
            ->setParameter(':articleDetailIds', $articleDetailId);
640
641
        $result = $builder->execute()->fetch(\PDO::FETCH_ASSOC);
642
643
        return new ShopProductId($result);
644
    }
645
646
    /**
647
     * Check if given articleDetailId is remote product
648
     *
649
     * @param int $articleDetailId
650
     * @return bool
651
     */
652
    public function isRemoteArticleDetail($articleDetailId)
653
    {
654
        $articleDetailId = (int) $articleDetailId;
655
        $articleDetailRepository = $this->manager->getRepository('Shopware\Models\Article\Detail');
656
        /** @var \Shopware\Models\Article\Detail $detail */
657
        $detail = $articleDetailRepository->find($articleDetailId);
658
        if (!$detail) {
659
            return false;
660
        }
661
662
        $connectAttribute = $this->getConnectAttributeByModel($detail);
663
        if (!$connectAttribute) {
664
            return false;
665
        }
666
667
        return ($connectAttribute->getShopId() != null);
668
    }
669
670
    /**
671
     * Check if given articleDetailId is remote product
672
     *
673
     * @param int $articleDetailId
674
     * @return bool
675
     */
676
    public function isRemoteArticleDetailDBAL($articleDetailId)
677
    {
678
        $articleDetailId = (int) $articleDetailId;
679
        $builder = $this->manager->getConnection()->createQueryBuilder();
680
        $builder->select('items.shop_id')
681
            ->from('s_plugin_connect_items', 'items')
682
            ->where('items.article_detail_id = :articleDetailId')
683
            ->setParameter(':articleDetailId', $articleDetailId);
684
685
        return (bool) $builder->execute()->fetchColumn();
686
    }
687
688
    /**
689
     * Extract article ID and detail ID
690
     * from source ID
691
     *
692
     * @param $sourceId
693
     * @return array
694
     */
695
    public function explodeArticleId($sourceId)
696
    {
697
        $articleId = explode('-', $sourceId);
698
699
        if (isset($articleId[1]) && isset($articleId[1])) {
700
            return $articleId;
701
        }
702
703
        return [
704
            $articleId[0]
705
        ];
706
    }
707
708
    /**
709
     * Creates Shopware product model
710
     *
711
     * @param Product $product
712
     * @return ProductModel
713
     */
714
    public function createProductModel(Product $product)
715
    {
716
        //todo@sb: Add test
717
        $model = new ProductModel();
718
        $model->setActive(false);
719
        $model->setName($product->title);
720
        $this->manager->persist($model);
721
722
        return $model;
723
    }
724
725
    /**
726
     * Returns main article detail by given groupId
727
     *
728
     * @param $product
729
     * @param int $mode
730
     * @return null|ProductModel
731
     */
732 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...
733
    {
734
        $builder = $this->manager->createQueryBuilder();
735
        $builder->select(['ba', 'd']);
736
        $builder->from('Shopware\CustomModels\Connect\Attribute', 'ba');
737
        $builder->join('ba.articleDetail', 'd');
738
        $builder->leftJoin('d.attribute', 'at');
739
740
        $builder->where('ba.groupId = :groupId AND ba.isMainVariant = 1 AND ba.shopId = :shopId');
741
        $query = $builder->getQuery();
742
743
        $query->setParameter('groupId', $product->groupId);
744
        $query->setParameter('shopId', $product->shopId);
745
        $result = $query->getResult(
746
            $mode
747
        );
748
749
        if (isset($result[0])) {
750
            /** @var \Shopware\CustomModels\Connect\Attribute $attribute */
751
            $attribute = $result[0];
752
753
            return $attribute->getArticle();
754
        }
755
756
        return null;
757
    }
758
759
    /**
760
     * @param $articleId
761
     * @return array
762
     */
763
    public function getSourceIdsFromArticleId($articleId)
764
    {
765
        $rows = $this->manager->getConnection()->fetchAll(
766
            'SELECT source_id FROM s_plugin_connect_items WHERE article_id = ?',
767
            [$articleId]
768
        );
769
770
        return array_map(function ($row) {
771
            return $row['source_id'];
772
        }, $rows);
773
    }
774
775
    /**
776
     * @param Unit $localUnit
777
     * @param string $remoteUnit
778
     */
779
    public function updateUnitInRelatedProducts(Unit $localUnit, $remoteUnit)
780
    {
781
        $statement = $this->manager->getConnection()->prepare('UPDATE s_articles_details sad
782
            LEFT JOIN s_articles_attributes saa ON sad.id = saa.articledetailsID
783
            SET sad.unitID = :unitId
784
            WHERE saa.connect_remote_unit = :remoteUnit');
785
786
        $statement->bindValue(':unitId', $localUnit->getId(), \PDO::PARAM_INT);
787
        $statement->bindValue(':remoteUnit', $remoteUnit, \PDO::PARAM_STR);
788
789
        $statement->execute();
790
    }
791
792
    /**
793
     * Checks whether given sourceId is main variant.
794
     * Works only with local products.
795
     * SourceIds pattern is articleId-variantId (58-142)
796
     *
797
     * For remote product check is_main_variant flag in
798
     * s_plugin_connect_items
799
     *
800
     * @param string $sourceId
801
     * @return bool
802
     */
803
    public function isMainVariant($sourceId)
804
    {
805
        $isMainVariant = $this->manager->getConnection()->fetchColumn(
806
            'SELECT d.kind
807
              FROM s_plugin_connect_items spci
808
              LEFT JOIN s_articles_details d ON spci.article_detail_id = d.id
809
              WHERE source_id = ?',
810
            [$sourceId]
811
        );
812
813
        if ($isMainVariant != 1) {
814
            return false;
815
        }
816
817
        return true;
818
    }
819
820
    /**
821
     * @return array
822
     */
823 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...
824
    {
825
        $builder = $this->manager->getConnection()->createQueryBuilder();
826
        $builder->select('DISTINCT spci.article_id');
827
        $builder->from('s_plugin_connect_items', 'spci');
828
        $builder->where('spci.shop_id IS NULL');
829
830
        $result = $builder->execute()->fetchAll();
831
832
        return array_map(function ($row) {
833
            return $row['article_id'];
834
        }, $result);
835
    }
836
}
837