LocalProductQuery::preparePriceRanges()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 1
dl 0
loc 19
rs 9.6333
c 0
b 0
f 0
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\ProductQuery;
9
10
use Doctrine\ORM\QueryBuilder;
11
use Shopware\Bundle\StoreFrontBundle\Service\ContextServiceInterface;
12
use Shopware\Bundle\StoreFrontBundle\Service\Core\ContextService;
13
use Shopware\Bundle\StoreFrontBundle\Struct\ListProduct;
14
use Shopware\Connect\Struct\Product;
15
use Shopware\Connect\Struct\Property;
16
use ShopwarePlugins\Connect\Components\Exceptions\NoLocalProductException;
17
use ShopwarePlugins\Connect\Components\Marketplace\MarketplaceGateway;
18
use ShopwarePlugins\Connect\Components\MediaService;
19
use ShopwarePlugins\Connect\Components\Translations\ProductTranslatorInterface;
20
use Shopware\Components\Model\ModelManager;
21
use ShopwarePlugins\Connect\Components\Utils\UnitMapper;
22
use Shopware\Connect\Struct\PriceRange;
23
use Enlight_Event_EventManager;
24
25
/**
26
 * Will return a local product (e.g. for export) as Shopware\Connect\Struct\Product
27
 * Configured fields for price- and description export will be taken into account
28
 *
29
 * Class LocalProductQuery
30
 * @package ShopwarePlugins\Connect\Components\ProductQuery
31
 */
32
class LocalProductQuery extends BaseProductQuery
33
{
34
    const IMAGE_LIMIT = 10;
35
36
    const VARIANT_IMAGE_LIMIT = 10;
37
38
    protected $baseProductUrl;
39
40
    /**
41
     * @var \ShopwarePlugins\Connect\Components\Config
42
     */
43
    protected $configComponent;
44
45
    /**
46
     * @var MarketplaceGateway
47
     */
48
    protected $marketplaceGateway;
49
50
    /**
51
     * @var \ShopwarePlugins\Connect\Components\Translations\ProductTranslatorInterface
52
     */
53
    protected $productTranslator;
54
55
    /**
56
     * @var \Shopware\Bundle\StoreFrontBundle\Service\ContextServiceInterface
57
     */
58
    protected $contextService;
59
60
    /**
61
     * @var \Shopware\Bundle\StoreFrontBundle\Service\Core\MediaService
62
     */
63
    protected $localMediaService;
64
65
    /**
66
     * @var \Shopware\Bundle\StoreFrontBundle\Struct\ProductContext
67
     */
68
    protected $productContext;
69
70
    /**
71
     * @var Enlight_Event_EventManager
72
     */
73
    private $eventManager;
74
75
    /**
76
     * LocalProductQuery constructor.
77
     * @param ModelManager $manager
78
     * @param null $baseProductUrl
79
     * @param $configComponent
80
     * @param MarketplaceGateway $marketplaceGateway
81
     * @param ProductTranslatorInterface $productTranslator
82
     * @param ContextServiceInterface $contextService
83
     * @param MediaService $storeFrontMediaService
84
     * @param null $mediaService
85
     * @param Enlight_Event_EventManager $eventManager
86
     */
87
    public function __construct(
88
        ModelManager $manager,
89
        $baseProductUrl,
90
        $configComponent,
91
        MarketplaceGateway $marketplaceGateway,
92
        ProductTranslatorInterface $productTranslator,
93
        ContextServiceInterface $contextService,
94
        MediaService $storeFrontMediaService,
95
        Enlight_Event_EventManager $eventManager,
96
        $mediaService = null
97
    ) {
98
        parent::__construct($manager, $mediaService);
99
100
        $this->baseProductUrl = $baseProductUrl;
101
        $this->configComponent = $configComponent;
102
        $this->marketplaceGateway = $marketplaceGateway;
103
        $this->productTranslator = $productTranslator;
104
        $this->contextService = $contextService;
105
        $this->eventManager = $eventManager;
106
        $this->localMediaService = $storeFrontMediaService;
0 ignored issues
show
Documentation Bug introduced by
It seems like $storeFrontMediaService of type object<ShopwarePlugins\C...omponents\MediaService> is incompatible with the declared type object<Shopware\Bundle\S...vice\Core\MediaService> of property $localMediaService.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
107
108
        // products context is needed to load product media
109
        // it's used for image translations
110
        // in our case translations are not used
111
        // so we don't care about shop language
112
        $this->productContext = $this->contextService->createShopContext(
113
            $this->configComponent->getDefaultShopId(),
114
            null,
115
            ContextService::FALLBACK_CUSTOMER_GROUP
116
        );
117
    }
118
119
    /**
120
     * @return QueryBuilder
121
     */
122
    public function getProductQuery()
123
    {
124
        $articleAttributeAlias = 'attribute';
125
        $exportPriceCustomerGroup = $this->configComponent->getConfig('priceGroupForPriceExport', 'EK');
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $exportPriceCustomerGroup is correct as $this->configComponent->...pForPriceExport', 'EK') (which targets ShopwarePlugins\Connect\...nts\Config::getConfig()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
126
        $exportPurchasePriceCustomerGroup = $this->configComponent->getConfig('priceGroupForPurchasePriceExport', 'EK');
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $exportPurchasePriceCustomerGroup is correct as $this->configComponent->...hasePriceExport', 'EK') (which targets ShopwarePlugins\Connect\...nts\Config::getConfig()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
127
        $exportPriceColumn = $this->configComponent->getConfig('priceFieldForPriceExport');
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $exportPriceColumn is correct as $this->configComponent->...ceFieldForPriceExport') (which targets ShopwarePlugins\Connect\...nts\Config::getConfig()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
128
        $exportPurchasePriceColumn = $this->configComponent->getConfig('priceFieldForPurchasePriceExport');
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $exportPurchasePriceColumn is correct as $this->configComponent->...orPurchasePriceExport') (which targets ShopwarePlugins\Connect\...nts\Config::getConfig()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
129
130
        $builder = $this->manager->createQueryBuilder();
131
132
        $builder->from('Shopware\CustomModels\Connect\Attribute', 'at');
133
        $builder->join('at.article', 'a');
134
        $builder->join('at.articleDetail', 'd');
135
        $builder->leftJoin('a.supplier', 's');
136
        $builder->join('a.tax', 't');
137
        $builder->leftJoin('d.attribute', 'attribute');
138
        $builder->leftJoin('d.unit', 'u');
139
        $builder->leftJoin('a.configuratorSet', 'configSet');
140
        $builder->where('at.shopId IS NULL');
141
        $selectColumns = [
142
            'a.id as localId',
143
            'd.id as detailId',
144
            'd.number as sku',
145
            'at.shopId as shopId',
146
            'at.sourceId as sourceId',
147
            'd.kind as detailKind',
148
            'd.ean',
149
            'a.name as title',
150
            's.name as vendorName',
151
            's.image as vendorImage',
152
            's.link as vendorLink',
153
            's.description as vendorDescription',
154
            's.metaTitle as vendorMetaTitle',
155
            't.tax / 100 as vat',
156
157
            'd.releaseDate as deliveryDate',
158
            'd.inStock as availability',
159
            'd.minPurchase as minPurchaseQuantity',
160
161
            'd.width',
162
            'd.height',
163
            'd.len as length',
164
165
            'd.weight',
166
            'u.unit',
167
            'd.purchaseUnit as purchaseUnit',
168
            'd.referenceUnit as referenceUnit',
169
            'd.packUnit as packageUnit',
170
            'd.minPurchase as basicUnit',
171
            'd.supplierNumber as manufacturerNumber',
172
            'at.category as category',
173
            'at.fixedPrice as fixedPrice',
174
            'd.shippingTime as deliveryWorkDays',
175
            'a.lastStock',
176
            'a.configuratorSetId',
177
            'configSet.type as configuratorSetType'
178
        ];
179
180
        if ($this->configComponent->getConfig(self::SHORT_DESCRIPTION_FIELD, false)) {
181
            $selectColumns[] = 'a.description as shortDescription';
182
        }
183
184
        if ($this->configComponent->getConfig(self::LONG_DESCRIPTION_FIELD, false)) {
185
            $selectColumns[] = 'a.descriptionLong as longDescription';
186
        }
187
188
        if ($this->configComponent->getConfig(self::CONNECT_DESCRIPTION_FIELD, false)) {
189
            $selectColumns[] = 'attribute.connectProductDescription as additionalDescription';
190
        }
191
192
        if ($exportPriceColumn) {
193
            $selectColumns[] = "exportPrice.{$exportPriceColumn} as price";
194
        }
195
        if ($exportPurchasePriceColumn && $exportPurchasePriceColumn == 'detailPurchasePrice') {
196
            $selectColumns[] = 'd.purchasePrice as purchasePrice';
197
        } elseif ($exportPurchasePriceColumn) {
198
            $selectColumns[] = "exportPurchasePrice.{$exportPurchasePriceColumn} as purchasePrice";
199
        }
200
201
        $builder->select($selectColumns);
202
203
        $builder = $this->addMarketplaceAttributeSelect($builder, $articleAttributeAlias);
204
        $builder = $this->addPriceJoins($builder, $exportPriceColumn, $exportPurchasePriceColumn);
205
206
        $builder->setParameter('priceCustomerGroup', $exportPriceCustomerGroup);
207
        if ($exportPurchasePriceColumn != 'detailPurchasePrice') {
208
            $builder->setParameter('purchasePriceCustomerGroup', $exportPurchasePriceCustomerGroup);
209
        }
210
211
        return $builder;
212
    }
213
214
    /**
215
     * @param array $rows
216
     * @return array
217
     */
218
    public function getConnectProducts($rows)
219
    {
220
        $products = [];
221
        foreach ($rows as $row) {
222
            $products[] = $this->getConnectProduct($row);
223
        }
224
225
        return $products;
226
    }
227
228
    /**
229
     * @param $row
230
     * @throws NoLocalProductException
231
     * @return Product
232
     */
233
    public function getConnectProduct($row)
234
    {
235
        $row = $this->prepareCommonAttributes($row);
236
        $row['translations'] = $this->productTranslator->translate($row['localId'], $row['sourceId']);
237
238
        if (!empty($row['shopId'])) {
239
            throw new NoLocalProductException("Product {$row['title']} is not a local product");
240
        }
241
242
        $row['url'] = $this->getUrlForProduct($row['sourceId']);
243
        $row['priceRanges'] = $this->preparePriceRanges($row['detailId']);
244
245
        $row['properties'] = $this->prepareProperties($row['localId']);
246
247
        $product = new ListProduct($row['localId'], $row['detailId'], $row['sku']);
248
249
        $sku = $row['sku'];
250
        $row['images'] = [];
251
        $mediaFiles = $this->localMediaService->getProductMediaList([$product], $this->productContext);
252
        if (array_key_exists($sku, $mediaFiles) && $mediaFiles[$sku]) {
253
            $mediaFiles[$sku] = array_slice($mediaFiles[$sku], 0, self::IMAGE_LIMIT);
254
            foreach ($mediaFiles[$sku] as $media) {
255
                //main image has to be first image
256
                if ($this->isMediaMainImage($row['localId'], $media->getId()) && isset($row['images'][0])) {
257
                    $temp = $row['images'][0];
258
                    $row['images'][0] = $media->getFile();
259
                    $row['images'][] = $temp;
260
                } else {
261
                    $row['images'][] = $media->getFile();
262
                }
263
            }
264
        }
265
266
        $variantMediaFiles = $this->localMediaService->getVariantMediaList([$product], $this->productContext);
267
        if (array_key_exists($sku, $variantMediaFiles) && $variantMediaFiles[$sku]) {
268
            $variantMediaFiles[$sku] = array_slice($variantMediaFiles[$sku], 0, self::VARIANT_IMAGE_LIMIT);
269
            foreach ($variantMediaFiles[$sku] as $media) {
270
                $row['variantImages'][] = $media->getFile();
271
                $row['images'][] = $media->getFile();
272
            }
273
        }
274
275
        $row = $this->prepareVendor($row);
276
277
        if ($row['deliveryWorkDays']) {
278
            $row['deliveryWorkDays'] = (int) $row['deliveryWorkDays'];
279
        } else {
280
            $row['deliveryWorkDays'] = null;
281
        }
282
283
        if ($row['configuratorSetId'] > 0) {
284
            $row['groupId'] = $row['localId'];
285
            $row = $this->applyConfiguratorOptions($row);
286
        }
287
288
        $row['supplierStreams'] = $this->getSupplierStreams($row['localId']);
289
290
        foreach (['localId', 'detailId', 'detailKind', 'configuratorSetId'] as $fieldName) {
291
            unset($row[$fieldName]);
292
        }
293
294
        if (
295
            (array_key_exists(Product::ATTRIBUTE_UNIT, $row['attributes']) && $row['attributes'][Product::ATTRIBUTE_UNIT]) &&
296
            (array_key_exists(Product::ATTRIBUTE_QUANTITY, $row['attributes']) && $row['attributes'][Product::ATTRIBUTE_QUANTITY]) &&
297
            (array_key_exists(Product::ATTRIBUTE_REFERENCE_QUANTITY, $row['attributes']) && $row['attributes'][Product::ATTRIBUTE_REFERENCE_QUANTITY])) {
298
            //Map local unit to connect unit
299
            if ($row['attributes'][Product::ATTRIBUTE_UNIT]) {
300
                $unitMapper = new UnitMapper($this->configComponent, $this->manager);
301
                $row['attributes'][Product::ATTRIBUTE_UNIT] = $unitMapper->getConnectUnit($row['attributes'][Product::ATTRIBUTE_UNIT]);
302
            }
303
304
            $intRefQuantity = (int) $row['attributes'][Product::ATTRIBUTE_REFERENCE_QUANTITY];
305
            if ($row['attributes'][Product::ATTRIBUTE_REFERENCE_QUANTITY] - $intRefQuantity <= 0.0001) {
306
                $row['attributes'][Product::ATTRIBUTE_REFERENCE_QUANTITY] = $intRefQuantity;
307
            }
308
        } else {
309
            unset($row['attributes'][Product::ATTRIBUTE_UNIT]);
310
            $row['attributes'][Product::ATTRIBUTE_QUANTITY] = null;
311
            $row['attributes'][Product::ATTRIBUTE_REFERENCE_QUANTITY] = null;
312
        }
313
314 View Code Duplication
        if (!(array_key_exists(Product::ATTRIBUTE_PACKAGEUNIT, $row['attributes']) && $row['attributes'][Product::ATTRIBUTE_PACKAGEUNIT])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
315
            unset($row['attributes'][Product::ATTRIBUTE_PACKAGEUNIT]);
316
        }
317
318 View Code Duplication
        if (!(array_key_exists(Product::ATTRIBUTE_MANUFACTURERNUMBER, $row['attributes']) && $row['attributes'][Product::ATTRIBUTE_MANUFACTURERNUMBER])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
319
            unset($row['attributes'][Product::ATTRIBUTE_MANUFACTURERNUMBER]);
320
        }
321
322 View Code Duplication
        if (!(array_key_exists(Product::ATTRIBUTE_BASICUNIT, $row['attributes']) && $row['attributes'][Product::ATTRIBUTE_BASICUNIT])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
323
            unset($row['attributes'][Product::ATTRIBUTE_BASICUNIT]);
324
        }
325
        $product = new Product($row);
326
327
        $this->eventManager->notify(
328
            'Connect_Supplier_Get_Single_Product_Before',
329
            [
330
                'subject' => $this,
331
                'product' => $product
332
            ]
333
        );
334
335
        return $product;
336
    }
337
338
    /**
339
     * @param $articleId
340
     * @return array
341
     * @throws \Doctrine\DBAL\DBALException
342
     */
343
    private function getSupplierStreams($articleId)
344
    {
345
        $result = $this->manager->getConnection()->executeQuery('
346
            SELECT `stream_id`, `name`
347
            FROM s_plugin_connect_streams_relation csr
348
            INNER JOIN s_product_streams ps ON csr.stream_id = ps.id
349
            WHERE csr.article_id = ? AND csr.deleted = 0
350
        ', [$articleId])->fetchAll();
351
352
        $streams = [];
353
        foreach ($result as $row) {
354
            $streams[$row['stream_id']] = $row['name'];
355
        }
356
357
        return $streams;
358
    }
359
360
    /**
361
     * Will add the correct joins depending on the configuration of the price columns
362
     *
363
     * @param $builder QueryBuilder
364
     * @param $exportPriceColumn
365
     * @param $exportPurchasePriceColumn
366
     * @return QueryBuilder
367
     */
368
    public function addPriceJoins(QueryBuilder $builder, $exportPriceColumn, $exportPurchasePriceColumn)
369
    {
370
        // When the price attribute is used, we need two joins to get it
371
        if ($exportPriceColumn == 'connectPrice') {
372
            $builder->leftJoin(
373
                'd.prices',
374
                'price_join_for_export_price',
375
                'with',
376
                'price_join_for_export_price.from = 1 AND price_join_for_export_price.customerGroupKey = :priceCustomerGroup'
377
            );
378
            $builder->leftJoin('price_join_for_export_price.attribute', 'exportPrice');
379
        } else {
380
            $builder->leftJoin(
381
                'd.prices',
382
                'exportPrice',
383
                'with',
384
                'exportPrice.from = 1 AND exportPrice.customerGroupKey = :priceCustomerGroup'
385
            );
386
        }
387
388
        // When the price attribute is used, we need two joins to get it
389
        if ($exportPurchasePriceColumn == 'connectPrice') {
390
            $builder->leftJoin(
391
                'd.prices',
392
                'price_join_for_export_purchase_price',
393
                'with',
394
                'price_join_for_export_purchase_price.from = 1 AND price_join_for_export_purchase_price.customerGroupKey = :purchasePriceCustomerGroup'
395
            );
396
            $builder->leftJoin('price_join_for_export_purchase_price.attribute', 'exportPurchasePrice');
397
        } elseif ($exportPurchasePriceColumn != 'detailPurchasePrice') {
398
            $builder->leftJoin(
399
                'd.prices',
400
                'exportPurchasePrice',
401
                'with',
402
                'exportPurchasePrice.from = 1 AND exportPurchasePrice.customerGroupKey = :purchasePriceCustomerGroup'
403
            );
404
        }
405
406
        return $builder;
407
    }
408
409 View Code Duplication
    public function getUrlForProduct($productId, $shopId = null)
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...
410
    {
411
        $shopId = (int) $shopId;
412
        $url = $this->baseProductUrl . $productId;
413
        if ($shopId > 0) {
414
            $url = $url . '/shId/' . $shopId;
415
        }
416
417
        return $url;
418
    }
419
420
    /**
421
     * Select attributes  which are already mapped to marketplace
422
     *
423
     * @param QueryBuilder $builder
424
     * @param $alias
425
     * @return QueryBuilder
426
     */
427
    private function addMarketplaceAttributeSelect(QueryBuilder $builder, $alias)
428
    {
429
        foreach ($this->marketplaceGateway->getMappings() as $mapping) {
430
            if (strlen($mapping['shopwareAttributeKey']) > 0 && strlen($mapping['attributeKey']) > 0) {
431
                $builder->addSelect("{$alias}.{$mapping['shopwareAttributeKey']}");
432
            }
433
        }
434
435
        return $builder;
436
    }
437
438
    /**
439
     * Returns shopware to martketplace attributes mapping as array
440
     *
441
     * @return array
442
     */
443
    public function getAttributeMapping()
444
    {
445
        $mappings = $this->marketplaceGateway->getMappings();
446
447
        return array_merge(
448
            array_filter(
449
                array_combine(
450
                    array_map(
451
                        function ($mapping) {
452
                            return $mapping['shopwareAttributeKey'];
453
                        },
454
                        $mappings
455
                    ),
456
                    array_map(
457
                        function ($mapping) {
458
                            return $mapping['attributeKey'];
459
                        },
460
                        $mappings
461
                    )
462
                ),
463
                function ($mapping) {
464
                    return strlen($mapping['shopwareAttributeKey']) > 0 && strlen($mapping['attributeKey']) > 0;
465
                }
466
            ),
467
            $this->attributeMapping
468
        );
469
    }
470
471
    /**
472
     * Check whether the product contains variants
473
     *
474
     * @param int $articleId
475
     * @return bool
476
     */
477
    public function hasVariants($articleId)
478
    {
479
        $result = $this->manager->getConnection()->fetchColumn(
480
            'SELECT a.configurator_set_id FROM s_articles a WHERE a.id = ?',
481
            [(int) $articleId]
482
        );
483
484
        return $result > 0;
485
    }
486
487
    /**
488
     * @param $detailId
489
     * @return PriceRange[]
490
     */
491
    protected function preparePriceRanges($detailId)
492
    {
493
        $prices = $this->getPriceRanges($detailId);
494
495
        $priceRanges = [];
496
        foreach ($prices as $price) {
497
            $clonePrice = $price;
498
499
            if ($price['to'] == 'beliebig') {
500
                $clonePrice['to'] = PriceRange::ANY;
501
            } else {
502
                $clonePrice['to'] = (int) $price['to'];
503
            }
504
505
            $priceRanges[] = new PriceRange($clonePrice);
506
        }
507
508
        return $priceRanges;
509
    }
510
511
    /**
512
     * @param int $detailId
513
     * @return array
514
     */
515
    private function getPriceRanges($detailId)
516
    {
517
        $exportPriceCustomerGroup = $this->configComponent->getConfig('priceGroupForPriceExport', 'EK');
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $exportPriceCustomerGroup is correct as $this->configComponent->...pForPriceExport', 'EK') (which targets ShopwarePlugins\Connect\...nts\Config::getConfig()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
518
        $exportPriceColumn = $this->configComponent->getConfig('priceFieldForPriceExport');
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $exportPriceColumn is correct as $this->configComponent->...ceFieldForPriceExport') (which targets ShopwarePlugins\Connect\...nts\Config::getConfig()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
519
520
        $columns = ['p.from', 'p.to', 'p.customerGroupKey'];
521
522
        if ($exportPriceColumn) {
523
            $columns[] = "p.{$exportPriceColumn} as price";
524
        }
525
526
        $builder = $this->manager->createQueryBuilder();
527
        $builder->select($columns)
528
            ->from('Shopware\Models\Article\Price', 'p')
529
            ->where('p.articleDetailsId = :detailId')
530
            ->andWhere('p.customerGroupKey = :groupKey')
531
            ->setParameter('detailId', $detailId)
532
            ->setParameter('groupKey', $exportPriceCustomerGroup);
533
534
        return $builder->getQuery()->getArrayResult();
535
    }
536
537
    /**
538
     * @param $articleId
539
     * @return Property[]
540
     */
541
    protected function prepareProperties($articleId)
542
    {
543
        $properties = $this->getProperties($articleId);
544
        $attrGroup = $this->attributeGroup($articleId);
545
546
        // if product property group exist then the
547
        // property values are still old by that
548
        // this will not generate wrong Connect changes
549
        $property = reset($properties);
550
        if ($attrGroup) {
551
            $groupName = $attrGroup->getName();
552
            $groupPosition = $attrGroup->getPosition();
553
        } else {
554
            $groupName = $property['groupName'];
555
            $groupPosition = $property['groupPosition'];
556
        }
557
558
        $propertyArray = [];
559
        foreach ($properties as $property) {
560
            $cloneProperty = $property;
561
            $cloneProperty['groupName'] = $groupName;
562
            $cloneProperty['groupPosition'] = $groupPosition;
563
            $propertyArray[] = new Property($cloneProperty);
564
        }
565
566
        return $propertyArray;
567
    }
568
569
    /**
570
     * @param $row
571
     * @return array
572
     */
573
    private function prepareVendor($row)
574
    {
575
        $row['vendor'] = [
576
            'name' => $row['vendorName'],
577
            'url' => $row['vendorLink'],
578
            'logo_url' => null,
579
            'description' => $row['vendorDescription'],
580
            'page_title' => $row['vendorMetaTitle'],
581
        ];
582
583
        if ($row['vendorImage']) {
584
            $info = pathinfo($row['vendorImage']);
585
            $row['vendor']['logo_url'] = $this->getImagePath($info['basename']);
586
        }
587
588
        unset($row['vendorName']);
589
        unset($row['vendorLink']);
590
        unset($row['vendorImage']);
591
        unset($row['vendorDescription']);
592
        unset($row['vendorMetaTitle']);
593
594
        return $row;
595
    }
596
597
    /**
598
     * Applies configurator options and groups
599
     * to article array
600
     *
601
     * @param array $row
602
     * @return array
603
     */
604
    private function applyConfiguratorOptions($row)
605
    {
606
        $builder = $this->manager->createQueryBuilder();
607
        $builder->from('Shopware\Models\Article\Detail', 'd');
608
        $builder->join('d.configuratorOptions', 'cor');
609
        $builder->join('cor.group', 'cg');
610
        $builder->select([
611
            'cor.name as optionName',
612
            'cor.id as optionId',
613
            'cg.name as groupName',
614
            'cg.id as groupId',
615
        ]);
616
        $builder->where('d.id = :detailId');
617
        $builder->setParameter(':detailId', $row['detailId']);
618
619
        $query = $builder->getQuery();
620
621
        $configuratorData = [];
622
        $configs = $query->getArrayResult();
623
624
        foreach ($configs as $config) {
625
            $row['translations'] = $this->productTranslator->translateConfiguratorGroup($config['groupId'], $config['groupName'], $row['translations']);
626
            $row['translations'] = $this->productTranslator->translateConfiguratorOption($config['optionId'], $config['optionName'], $row['translations']);
627
628
            $groupName = $config['groupName'];
629
            $configuratorData[$groupName] = $config['optionName'];
630
        }
631
632
        $row['variant'] = $configuratorData;
633
634
        foreach ($row['translations'] as $key => $translation) {
635
            try {
636
                // todo@sb: test me
637
                $this->productTranslator->validate($translation, count($configs));
638
            } catch (\Exception $e) {
639
                unset($row['translations'][$key]);
640
            }
641
        }
642
643
        return $row;
644
    }
645
646
    /**
647
     * @param int $articleId
648
     * @param int $mediaId
649
     * @return bool
650
     */
651
    private function isMediaMainImage($articleId, $mediaId)
652
    {
653
        $isMain = $this->manager->getConnection()->fetchColumn(
654
            'SELECT main FROM s_articles_img WHERE articleID = ? and media_id = ?',
655
            [$articleId, $mediaId]
656
        );
657
658
        return $isMain == 1;
659
    }
660
}
661