Completed
Pull Request — master (#422)
by Jonas
05:22
created

LocalProductQuery::addPriceJoins()   B

Complexity

Conditions 4
Paths 6

Size

Total Lines 40
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 40
rs 8.5806
c 0
b 0
f 0
cc 4
eloc 28
nc 6
nop 3
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
        foreach (['localId', 'detailId', 'detailKind', 'configuratorSetId'] as $fieldName) {
289
            unset($row[$fieldName]);
290
        }
291
292
        if (
293
            (array_key_exists(Product::ATTRIBUTE_UNIT, $row['attributes']) && $row['attributes'][Product::ATTRIBUTE_UNIT]) &&
294
            (array_key_exists(Product::ATTRIBUTE_QUANTITY, $row['attributes']) && $row['attributes'][Product::ATTRIBUTE_QUANTITY]) &&
295
            (array_key_exists(Product::ATTRIBUTE_REFERENCE_QUANTITY, $row['attributes']) && $row['attributes'][Product::ATTRIBUTE_REFERENCE_QUANTITY])) {
296
            //Map local unit to connect unit
297
            if ($row['attributes'][Product::ATTRIBUTE_UNIT]) {
298
                $unitMapper = new UnitMapper($this->configComponent, $this->manager);
299
                $row['attributes'][Product::ATTRIBUTE_UNIT] = $unitMapper->getConnectUnit($row['attributes'][Product::ATTRIBUTE_UNIT]);
300
            }
301
302
            $intRefQuantity = (int) $row['attributes'][Product::ATTRIBUTE_REFERENCE_QUANTITY];
303
            if ($row['attributes'][Product::ATTRIBUTE_REFERENCE_QUANTITY] - $intRefQuantity <= 0.0001) {
304
                $row['attributes'][Product::ATTRIBUTE_REFERENCE_QUANTITY] = $intRefQuantity;
305
            }
306
        } else {
307
            unset($row['attributes'][Product::ATTRIBUTE_UNIT]);
308
            $row['attributes'][Product::ATTRIBUTE_QUANTITY] = null;
309
            $row['attributes'][Product::ATTRIBUTE_REFERENCE_QUANTITY] = null;
310
        }
311
312 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...
313
            unset($row['attributes'][Product::ATTRIBUTE_PACKAGEUNIT]);
314
        }
315
316 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...
317
            unset($row['attributes'][Product::ATTRIBUTE_MANUFACTURERNUMBER]);
318
        }
319
320 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...
321
            unset($row['attributes'][Product::ATTRIBUTE_BASICUNIT]);
322
        }
323
        $product = new Product($row);
324
325
        $this->eventManager->notify(
326
            'Connect_Supplier_Get_Single_Product_Before',
327
            [
328
                'subject' => $this,
329
                'product' => $product
330
            ]
331
        );
332
333
        return $product;
334
    }
335
336
    /**
337
     * Will add the correct joins depending on the configuration of the price columns
338
     *
339
     * @param $builder QueryBuilder
340
     * @param $exportPriceColumn
341
     * @param $exportPurchasePriceColumn
342
     * @return QueryBuilder
343
     */
344
    public function addPriceJoins(QueryBuilder $builder, $exportPriceColumn, $exportPurchasePriceColumn)
345
    {
346
        // When the price attribute is used, we need two joins to get it
347
        if ($exportPriceColumn == 'connectPrice') {
348
            $builder->leftJoin(
349
                'd.prices',
350
                'price_join_for_export_price',
351
                'with',
352
                'price_join_for_export_price.from = 1 AND price_join_for_export_price.customerGroupKey = :priceCustomerGroup'
353
            );
354
            $builder->leftJoin('price_join_for_export_price.attribute', 'exportPrice');
355
        } else {
356
            $builder->leftJoin(
357
                'd.prices',
358
                'exportPrice',
359
                'with',
360
                'exportPrice.from = 1 AND exportPrice.customerGroupKey = :priceCustomerGroup'
361
            );
362
        }
363
364
        // When the price attribute is used, we need two joins to get it
365
        if ($exportPurchasePriceColumn == 'connectPrice') {
366
            $builder->leftJoin(
367
                'd.prices',
368
                'price_join_for_export_purchase_price',
369
                'with',
370
                'price_join_for_export_purchase_price.from = 1 AND price_join_for_export_purchase_price.customerGroupKey = :purchasePriceCustomerGroup'
371
            );
372
            $builder->leftJoin('price_join_for_export_purchase_price.attribute', 'exportPurchasePrice');
373
        } elseif ($exportPurchasePriceColumn != 'detailPurchasePrice') {
374
            $builder->leftJoin(
375
                'd.prices',
376
                'exportPurchasePrice',
377
                'with',
378
                'exportPurchasePrice.from = 1 AND exportPurchasePrice.customerGroupKey = :purchasePriceCustomerGroup'
379
            );
380
        }
381
382
        return $builder;
383
    }
384
385 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...
386
    {
387
        $shopId = (int) $shopId;
388
        $url = $this->baseProductUrl . $productId;
389
        if ($shopId > 0) {
390
            $url = $url . '/shId/' . $shopId;
391
        }
392
393
        return $url;
394
    }
395
396
    /**
397
     * Select attributes  which are already mapped to marketplace
398
     *
399
     * @param QueryBuilder $builder
400
     * @param $alias
401
     * @return QueryBuilder
402
     */
403
    private function addMarketplaceAttributeSelect(QueryBuilder $builder, $alias)
404
    {
405
        foreach ($this->marketplaceGateway->getMappings() as $mapping) {
406
            if (strlen($mapping['shopwareAttributeKey']) > 0 && strlen($mapping['attributeKey']) > 0) {
407
                $builder->addSelect("{$alias}.{$mapping['shopwareAttributeKey']}");
408
            }
409
        }
410
411
        return $builder;
412
    }
413
414
    /**
415
     * Returns shopware to martketplace attributes mapping as array
416
     *
417
     * @return array
418
     */
419
    public function getAttributeMapping()
420
    {
421
        $mappings = $this->marketplaceGateway->getMappings();
422
423
        return array_merge(
424
            array_filter(
425
                array_combine(
426
                    array_map(
427
                        function ($mapping) {
428
                            return $mapping['shopwareAttributeKey'];
429
                        },
430
                        $mappings
431
                    ),
432
                    array_map(
433
                        function ($mapping) {
434
                            return $mapping['attributeKey'];
435
                        },
436
                        $mappings
437
                    )
438
                ),
439
                function ($mapping) {
440
                    return strlen($mapping['shopwareAttributeKey']) > 0 && strlen($mapping['attributeKey']) > 0;
441
                }
442
            ),
443
            $this->attributeMapping
444
        );
445
    }
446
447
    /**
448
     * Check whether the product contains variants
449
     *
450
     * @param int $articleId
451
     * @return bool
452
     */
453
    public function hasVariants($articleId)
454
    {
455
        $result = $this->manager->getConnection()->fetchColumn(
456
            'SELECT a.configurator_set_id FROM s_articles a WHERE a.id = ?',
457
            [(int) $articleId]
458
        );
459
460
        return $result > 0;
461
    }
462
463
    /**
464
     * @param $detailId
465
     * @return PriceRange[]
466
     */
467
    protected function preparePriceRanges($detailId)
468
    {
469
        $prices = $this->getPriceRanges($detailId);
470
471
        $priceRanges = [];
472
        foreach ($prices as $price) {
473
            $clonePrice = $price;
474
475
            if ($price['to'] == 'beliebig') {
476
                $clonePrice['to'] = PriceRange::ANY;
477
            } else {
478
                $clonePrice['to'] = (int) $price['to'];
479
            }
480
481
            $priceRanges[] = new PriceRange($clonePrice);
482
        }
483
484
        return $priceRanges;
485
    }
486
487
    /**
488
     * @param int $detailId
489
     * @return array
490
     */
491
    private function getPriceRanges($detailId)
492
    {
493
        $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...
494
        $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...
495
496
        $columns = ['p.from', 'p.to', 'p.customerGroupKey'];
497
498
        if ($exportPriceColumn) {
499
            $columns[] = "p.{$exportPriceColumn} as price";
500
        }
501
502
        $builder = $this->manager->createQueryBuilder();
503
        $builder->select($columns)
504
            ->from('Shopware\Models\Article\Price', 'p')
505
            ->where('p.articleDetailsId = :detailId')
506
            ->andWhere('p.customerGroupKey = :groupKey')
507
            ->setParameter('detailId', $detailId)
508
            ->setParameter('groupKey', $exportPriceCustomerGroup);
509
510
        return $builder->getQuery()->getArrayResult();
511
    }
512
513
    /**
514
     * @param $articleId
515
     * @return Property[]
516
     */
517
    protected function prepareProperties($articleId)
518
    {
519
        $properties = $this->getProperties($articleId);
520
        $attrGroup = $this->attributeGroup($articleId);
521
522
        // if product property group exist then the
523
        // property values are still old by that
524
        // this will not generate wrong Connect changes
525
        $property = reset($properties);
526
        if ($attrGroup) {
527
            $groupName = $attrGroup->getName();
528
            $groupPosition = $attrGroup->getPosition();
529
        } else {
530
            $groupName = $property['groupName'];
531
            $groupPosition = $property['groupPosition'];
532
        }
533
534
        $propertyArray = [];
535
        foreach ($properties as $property) {
536
            $cloneProperty = $property;
537
            $cloneProperty['groupName'] = $groupName;
538
            $cloneProperty['groupPosition'] = $groupPosition;
539
            $propertyArray[] = new Property($cloneProperty);
540
        }
541
542
        return $propertyArray;
543
    }
544
545
    /**
546
     * @param $row
547
     * @return array
548
     */
549
    private function prepareVendor($row)
550
    {
551
        $row['vendor'] = [
552
            'name' => $row['vendorName'],
553
            'url' => $row['vendorLink'],
554
            'logo_url' => null,
555
            'description' => $row['vendorDescription'],
556
            'page_title' => $row['vendorMetaTitle'],
557
        ];
558
559
        if ($row['vendorImage']) {
560
            $info = pathinfo($row['vendorImage']);
561
            $row['vendor']['logo_url'] = $this->getImagePath($info['basename']);
562
        }
563
564
        unset($row['vendorName']);
565
        unset($row['vendorLink']);
566
        unset($row['vendorImage']);
567
        unset($row['vendorDescription']);
568
        unset($row['vendorMetaTitle']);
569
570
        return $row;
571
    }
572
573
    /**
574
     * Applies configurator options and groups
575
     * to article array
576
     *
577
     * @param array $row
578
     * @return array
579
     */
580
    private function applyConfiguratorOptions($row)
581
    {
582
        $builder = $this->manager->createQueryBuilder();
583
        $builder->from('Shopware\Models\Article\Detail', 'd');
584
        $builder->join('d.configuratorOptions', 'cor');
585
        $builder->join('cor.group', 'cg');
586
        $builder->select([
587
            'cor.name as optionName',
588
            'cor.id as optionId',
589
            'cg.name as groupName',
590
            'cg.id as groupId',
591
        ]);
592
        $builder->where('d.id = :detailId');
593
        $builder->setParameter(':detailId', $row['detailId']);
594
595
        $query = $builder->getQuery();
596
597
        $configuratorData = [];
598
        $configs = $query->getArrayResult();
599
600
        foreach ($configs as $config) {
601
            $row['translations'] = $this->productTranslator->translateConfiguratorGroup($config['groupId'], $config['groupName'], $row['translations']);
602
            $row['translations'] = $this->productTranslator->translateConfiguratorOption($config['optionId'], $config['optionName'], $row['translations']);
603
604
            $groupName = $config['groupName'];
605
            $configuratorData[$groupName] = $config['optionName'];
606
        }
607
608
        $row['variant'] = $configuratorData;
609
610
        foreach ($row['translations'] as $key => $translation) {
611
            try {
612
                // todo@sb: test me
613
                $this->productTranslator->validate($translation, count($configs));
614
            } catch (\Exception $e) {
615
                unset($row['translations'][$key]);
616
            }
617
        }
618
619
        return $row;
620
    }
621
622
    /**
623
     * @param int $articleId
624
     * @param int $mediaId
625
     * @return bool
626
     */
627
    private function isMediaMainImage($articleId, $mediaId)
628
    {
629
        $isMain = $this->manager->getConnection()->fetchColumn('SELECT main FROM s_articles_img WHERE articleID = ? and media_id = ?',
630
            [$articleId, $mediaId]);
631
632
        return $isMain == 1;
633
    }
634
}
635