Completed
Push — master ( 7c0075...645752 )
by Kamil
18:52
created

ProductContext   F

Complexity

Total Complexity 48

Size/Duplication

Total Lines 700
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 21

Importance

Changes 0
Metric Value
wmc 48
lcom 1
cbo 21
dl 0
loc 700
rs 3.3846
c 0
b 0
f 0

39 Methods

Rating   Name   Duplication   Size   Complexity  
A storeHasAProductPricedAt() 0 12 2
A storeHasProductWithCode() 0 12 2
A storeHasAProductPricedAtAvailableInChannels() 0 12 2
A thisProductIsNamedIn() 0 12 1
A storeHasAConfigurableProduct() 0 18 2
A theStoreHasProducts() 0 6 2
A thisChannelHasProducts() 0 9 2
B __construct() 0 33 1
A theProductHasVariantPricedAt() 0 9 1
A theProductHasVariantPricedAtIdentifiedBy() 0 8 1
A thereIsProductAvailableInGivenChannel() 0 9 1
A productBelongsToTaxCategory() 0 8 1
A itComesInTheFollowingVariations() 0 15 2
A productVariantBelongsToTaxCategory() 0 7 1
A thisProductHasAttributeWithValue() 0 8 1
A thisProductHasPercentAttributeWithValue() 0 8 1
A thisProductHasCheckboxAttributeWithValue() 0 9 1
A thisProductHasDateTimeAttributeWithDate() 0 9 1
A thisProductHasOptionWithValues() 0 21 2
A thereIsQuantityOfProducts() 0 8 1
A theProductIsOutOfStock() 0 9 1
A otherCustomerHasBoughtProductsByThisTime() 0 8 1
A thisProductIsTrackedByTheInventory() 0 8 1
A thisProductIsAvailableInSize() 0 14 1
A thisProductHasThisProductOption() 0 6 1
A thereAreItemsOfProductInVariantAvailableInTheInventory() 0 7 1
A theProductVariantIsTrackedByTheInventory() 0 6 1
A theProductChangedItsPriceTo() 0 8 1
A thisProductHasAnImageWithACode() 0 14 1
A itHasDifferentPricesForDifferentChannelsAndCurrencies() 0 7 1
A itHasPriceForChannelAndCurrency() 0 16 1
A createProductAttribute() 0 10 1
A createProductAttributeValue() 0 11 1
A getPriceFromString() 0 4 1
A createProduct() 0 17 1
A addProductOption() 0 13 1
A saveProduct() 0 5 1
A getParameter() 0 4 2
A createProductVariant() 0 17 1

How to fix   Complexity   

Complex Class

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

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

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

1
<?php
2
3
/*
4
 * This file is part of the Sylius package.
5
 *
6
 * (c) Paweł Jędrzejewski
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Sylius\Behat\Context\Setup;
13
14
use Behat\Behat\Context\Context;
15
use Behat\Gherkin\Node\TableNode;
16
use Behat\Mink\Element\NodeElement;
17
use Doctrine\Common\Persistence\ObjectManager;
18
use Sylius\Component\Attribute\Factory\AttributeFactoryInterface;
19
use Sylius\Component\Core\Formatter\StringInflector;
20
use Sylius\Component\Core\Model\ChannelInterface;
21
use Sylius\Component\Core\Model\ImageInterface;
22
use Sylius\Component\Core\Model\ProductInterface;
23
use Sylius\Component\Core\Model\ProductTranslationInterface;
24
use Sylius\Component\Core\Model\ProductVariantInterface;
25
use Sylius\Component\Core\Pricing\Calculators;
26
use Sylius\Component\Core\Repository\ProductRepositoryInterface;
27
use Sylius\Behat\Service\SharedStorageInterface;
28
use Sylius\Component\Core\Uploader\ImageUploaderInterface;
29
use Sylius\Component\Product\Factory\ProductFactoryInterface;
30
use Sylius\Component\Product\Generator\SlugGeneratorInterface;
31
use Sylius\Component\Product\Model\ProductAttributeInterface;
32
use Sylius\Component\Product\Model\ProductAttributeValueInterface;
33
use Sylius\Component\Product\Model\ProductOptionInterface;
34
use Sylius\Component\Product\Model\ProductOptionValueInterface;
35
use Sylius\Component\Resource\Factory\FactoryInterface;
36
use Sylius\Component\Taxation\Model\TaxCategoryInterface;
37
use Sylius\Component\Product\Resolver\ProductVariantResolverInterface;
38
use Symfony\Component\HttpFoundation\File\UploadedFile;
39
40
/**
41
 * @author Arkadiusz Krakowiak <[email protected]>
42
 * @author Mateusz Zalewski <[email protected]>
43
 * @author Magdalena Banasiak <[email protected]>
44
 */
45
final class ProductContext implements Context
46
{
47
    /**
48
     * @var SharedStorageInterface
49
     */
50
    private $sharedStorage;
51
52
    /**
53
     * @var ProductRepositoryInterface
54
     */
55
    private $productRepository;
56
57
    /**
58
     * @var ProductFactoryInterface
59
     */
60
    private $productFactory;
61
62
    /**
63
     * @var FactoryInterface
64
     */
65
    private $productTranslationFactory;
66
67
    /**
68
     * @var AttributeFactoryInterface
69
     */
70
    private $productAttributeFactory;
71
72
    /**
73
     * @var FactoryInterface
74
     */
75
    private $productVariantFactory;
76
77
    /**
78
     * @var FactoryInterface
79
     */
80
    private $attributeValueFactory;
81
82
    /**
83
     * @var FactoryInterface
84
     */
85
    private $productOptionFactory;
86
87
    /**
88
     * @var FactoryInterface
89
     */
90
    private $productOptionValueFactory;
91
92
    /**
93
     * @var FactoryInterface
94
     */
95
    private $productImageFactory;
96
97
    /**
98
     * @var ObjectManager
99
     */
100
    private $objectManager;
101
102
    /**
103
     * @var ProductVariantResolverInterface
104
     */
105
    private $defaultVariantResolver;
106
107
    /**
108
     * @var ImageUploaderInterface
109
     */
110
    private $imageUploader;
111
112
    /**
113
     * @var SlugGeneratorInterface
114
     */
115
    private $slugGenerator;
116
117
    /**
118
     * @var array
119
     */
120
    private $minkParameters;
121
122
    /**
123
     * @param SharedStorageInterface $sharedStorage
124
     * @param ProductRepositoryInterface $productRepository
125
     * @param ProductFactoryInterface $productFactory
126
     * @param FactoryInterface $productTranslationFactory
127
     * @param AttributeFactoryInterface $productAttributeFactory
128
     * @param FactoryInterface $attributeValueFactory
129
     * @param FactoryInterface $productVariantFactory
130
     * @param FactoryInterface $productOptionFactory
131
     * @param FactoryInterface $productOptionValueFactory
132
     * @param FactoryInterface $productImageFactory
133
     * @param ObjectManager $objectManager
134
     * @param ProductVariantResolverInterface $defaultVariantResolver
135
     * @param ImageUploaderInterface $imageUploader
136
     * @param SlugGeneratorInterface $slugGenerator
137
     * @param array $minkParameters
138
     */
139
    public function __construct(
140
        SharedStorageInterface $sharedStorage,
141
        ProductRepositoryInterface $productRepository,
142
        ProductFactoryInterface $productFactory,
143
        FactoryInterface $productTranslationFactory,
144
        AttributeFactoryInterface $productAttributeFactory,
145
        FactoryInterface $attributeValueFactory,
146
        FactoryInterface $productVariantFactory,
147
        FactoryInterface $productOptionFactory,
148
        FactoryInterface $productOptionValueFactory,
149
        FactoryInterface $productImageFactory,
150
        ObjectManager $objectManager,
151
        ProductVariantResolverInterface $defaultVariantResolver,
152
        ImageUploaderInterface $imageUploader,
153
        SlugGeneratorInterface $slugGenerator,
154
        array $minkParameters
155
    ) {
156
        $this->sharedStorage = $sharedStorage;
157
        $this->productRepository = $productRepository;
158
        $this->productFactory = $productFactory;
159
        $this->productTranslationFactory = $productTranslationFactory;
160
        $this->productAttributeFactory = $productAttributeFactory;
161
        $this->attributeValueFactory = $attributeValueFactory;
162
        $this->productVariantFactory = $productVariantFactory;
163
        $this->productOptionFactory = $productOptionFactory;
164
        $this->productOptionValueFactory = $productOptionValueFactory;
165
        $this->productImageFactory = $productImageFactory;
166
        $this->objectManager = $objectManager;
167
        $this->defaultVariantResolver = $defaultVariantResolver;
168
        $this->imageUploader = $imageUploader;
169
        $this->slugGenerator = $slugGenerator;
170
        $this->minkParameters = $minkParameters;
171
    }
172
173
    /**
174
     * @Given the store has a product :productName
175
     * @Given the store has a :productName product
176
     * @Given I added a product :productName
177
     * @Given /^the store(?:| also) has a product "([^"]+)" priced at ("[^"]+")$/
178
     */
179
    public function storeHasAProductPricedAt($productName, $price = 0)
180
    {
181
        $product = $this->createProduct($productName, $price);
182
183
        $product->setDescription('Awesome '.$productName);
184
185
        if ($this->sharedStorage->has('channel')) {
186
            $product->addChannel($this->sharedStorage->get('channel'));
187
        }
188
189
        $this->saveProduct($product);
190
    }
191
192
    /**
193
     * @Given the store( also) has a product :productName with code :code
194
     * @Given the store( also) has a product :productName with code :code, created at :date
195
     */
196
    public function storeHasProductWithCode($productName, $code, $date = null)
197
    {
198
        $product = $this->createProduct($productName, 0, $date);
199
200
        $product->setCode($code);
201
202
        if ($this->sharedStorage->has('channel')) {
203
            $product->addChannel($this->sharedStorage->get('channel'));
204
        }
205
206
        $this->saveProduct($product);
207
    }
208
209
    /**
210
     * @Given /^the store(?:| also) has a product "([^"]+)" priced at ("[^"]+") available in (channel "[^"]+") and (channel "[^"]+")$/
211
     */
212
    public function storeHasAProductPricedAtAvailableInChannels($productName, $price = 0, ...$channels)
213
    {
214
        $product = $this->createProduct($productName, $price);
215
216
        $product->setDescription('Awesome '.$productName);
217
218
        foreach ($channels as $channel) {
219
            $product->addChannel($channel);
220
        }
221
222
        $this->saveProduct($product);
223
    }
224
225
    /**
226
     * @Given /^(this product) is named "([^"]+)" (in the "([^"]+)" locale)$/
227
     * @Given /^the (product "[^"]+") is named "([^"]+)" (in the "([^"]+)" locale)$/
228
     */
229
    public function thisProductIsNamedIn(ProductInterface $product, $name, $locale)
230
    {
231
        /** @var ProductTranslationInterface $translation */
232
        $translation = $this->productTranslationFactory->createNew();
233
        $translation->setLocale($locale);
234
        $translation->setName($name);
235
        $translation->setSlug($this->slugGenerator->generate($name));
236
237
        $product->addTranslation($translation);
0 ignored issues
show
Documentation introduced by
$translation is of type object<Sylius\Component\...ctTranslationInterface>, but the function expects a object<Sylius\Component\...l\TranslationInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
238
239
        $this->objectManager->flush();
240
    }
241
242
    /**
243
     * @Given the store has a :productName configurable product
244
     */
245
    public function storeHasAConfigurableProduct($productName)
246
    {
247
        /** @var ProductInterface $product */
248
        $product = $this->productFactory->createNew();
249
250
        $product->setName($productName);
251
        $product->setCode(StringInflector::nameToUppercaseCode($productName));
252
        $product->setSlug($this->slugGenerator->generate($productName));
253
254
        $product->setDescription('Awesome '.$productName);
255
256
        if ($this->sharedStorage->has('channel')) {
257
            $channel = $this->sharedStorage->get('channel');
258
            $product->addChannel($channel);
259
        }
260
261
        $this->saveProduct($product);
262
    }
263
264
    /**
265
     * @Given the store has( also) :firstProductName and :secondProductName products
266
     * @Given the store has( also) :firstProductName, :secondProductName and :thirdProductName products
267
     * @Given the store has( also) :firstProductName, :secondProductName, :thirdProductName and :fourthProductName products
268
     */
269
    public function theStoreHasProducts(...$productsNames)
270
    {
271
        foreach ($productsNames as $productName) {
272
            $this->saveProduct($this->createProduct($productName));
273
        }
274
    }
275
276
    /**
277
     * @Given /^(this channel) has "([^"]+)", "([^"]+)", "([^"]+)" and "([^"]+)" products$/
278
     */
279
    public function thisChannelHasProducts(ChannelInterface $channel, ...$productsNames)
280
    {
281
        foreach ($productsNames as $productName) {
282
            $product = $this->createProduct($productName);
283
            $product->addChannel($channel);
284
285
            $this->saveProduct($product);
286
        }
287
    }
288
289
    /**
290
     * @Given /^the (product "[^"]+") has(?:| a) "([^"]+)" variant priced at ("[^"]+")$/
291
     * @Given /^(this product) has "([^"]+)" variant priced at ("[^"]+")$/
292
     */
293
    public function theProductHasVariantPricedAt(ProductInterface $product, $productVariantName, $price)
294
    {
295
        $this->createProductVariant(
296
            $product,
297
            $productVariantName,
298
            $price,
299
            StringInflector::nameToUppercaseCode($productVariantName)
300
        );
301
    }
302
303
    /**
304
     * @Given /^(this product) has "([^"]+)" variant priced at ("[^"]+") identified by "([^"]+)"$/
305
     */
306
    public function theProductHasVariantPricedAtIdentifiedBy(
307
        ProductInterface $product,
308
        $productVariantName,
309
        $price,
310
        $code
311
    ) {
312
        $this->createProductVariant($product, $productVariantName, $price, $code);
313
    }
314
315
    /**
316
     * @Given /^there is product "([^"]+)" available in ((?:this|that|"[^"]+") channel)$/
317
     * @Given /^the store has a product "([^"]+)" available in ("([^"]+)" channel)$/
318
     */
319
    public function thereIsProductAvailableInGivenChannel($productName, ChannelInterface $channel)
320
    {
321
        $product = $this->createProduct($productName);
322
323
        $product->setDescription('Awesome ' . $productName);
324
        $product->addChannel($channel);
325
326
        $this->saveProduct($product);
327
    }
328
329
    /**
330
     * @Given /^([^"]+) belongs to ("[^"]+" tax category)$/
331
     */
332
    public function productBelongsToTaxCategory(ProductInterface $product, TaxCategoryInterface $taxCategory)
333
    {
334
        /** @var ProductVariantInterface $variant */
335
        $variant = $this->defaultVariantResolver->getVariant($product);
336
        $variant->setTaxCategory($taxCategory);
337
338
        $this->objectManager->flush();
339
    }
340
341
    /**
342
     * @Given /^(it) comes in the following variations:$/
343
     */
344
    public function itComesInTheFollowingVariations(ProductInterface $product, TableNode $table)
345
    {
346
        foreach ($table->getHash() as $variantHash) {
347
            /** @var ProductVariantInterface $variant */
348
            $variant = $this->productVariantFactory->createNew();
349
350
            $variant->setName($variantHash['name']);
351
            $variant->setCode(StringInflector::nameToUppercaseCode($variantHash['name']));
352
            $variant->setPrice($this->getPriceFromString(str_replace(['$', '€', '£'], '', $variantHash['price'])));
353
            $variant->setProduct($product);
354
            $product->addVariant($variant);
355
        }
356
357
        $this->objectManager->flush();
358
    }
359
360
    /**
361
     * @Given /^("[^"]+" variant of product "[^"]+") belongs to ("[^"]+" tax category)$/
362
     */
363
    public function productVariantBelongsToTaxCategory(
364
        ProductVariantInterface $productVariant,
365
        TaxCategoryInterface $taxCategory
366
    ) {
367
        $productVariant->setTaxCategory($taxCategory);
368
        $this->objectManager->flush($productVariant);
369
    }
370
371
    /**
372
     * @Given /^(this product) has ([^"]+) attribute "([^"]+)" with value "([^"]+)"$/
373
     */
374
    public function thisProductHasAttributeWithValue(ProductInterface $product, $productAttributeType, $productAttributeName, $value)
375
    {
376
        $attribute = $this->createProductAttribute($productAttributeType,$productAttributeName);
377
        $attributeValue = $this->createProductAttributeValue($value, $attribute);
378
        $product->addAttribute($attributeValue);
379
380
        $this->objectManager->flush();
381
    }
382
383
    /**
384
     * @Given /^(this product) has percent attribute "([^"]+)" with value ([^"]+)%$/
385
     */
386
    public function thisProductHasPercentAttributeWithValue(ProductInterface $product, $productAttributeName, $value)
387
    {
388
        $attribute = $this->createProductAttribute('percent',$productAttributeName);
389
        $attributeValue = $this->createProductAttributeValue($value/100, $attribute);
390
        $product->addAttribute($attributeValue);
391
392
        $this->objectManager->flush();
393
    }
394
395
    /**
396
     * @Given /^(this product) has ([^"]+) attribute "([^"]+)" set to "([^"]+)"$/
397
     */
398
    public function thisProductHasCheckboxAttributeWithValue(ProductInterface $product, $productAttributeType, $productAttributeName, $value)
399
    {
400
        $attribute = $this->createProductAttribute($productAttributeType, $productAttributeName);
401
        $booleanValue = ('Yes' === $value);
402
        $attributeValue = $this->createProductAttributeValue($booleanValue, $attribute);
0 ignored issues
show
Documentation introduced by
$booleanValue is of type boolean, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
403
        $product->addAttribute($attributeValue);
404
405
        $this->objectManager->flush();
406
    }
407
408
    /**
409
     * @Given /^(this product) has ([^"]+) attribute "([^"]+)" with date "([^"]+)"$/
410
     */
411
    public function thisProductHasDateTimeAttributeWithDate(ProductInterface $product, $productAttributeType, $productAttributeName, $date)
412
    {
413
        $attribute = $this->createProductAttribute($productAttributeType, $productAttributeName);
414
        $attributeValue = $this->createProductAttributeValue(new \DateTime($date), $attribute);
0 ignored issues
show
Documentation introduced by
new \DateTime($date) is of type object<DateTime>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
415
416
        $product->addAttribute($attributeValue);
417
418
        $this->objectManager->flush();
419
    }
420
421
    /**
422
     * @Given /^(this product) has option "([^"]+)" with values "([^"]+)" and "([^"]+)"$/
423
     * @Given /^(this product) has option "([^"]+)" with values "([^"]+)", "([^"]+)" and "([^"]+)"$/
424
     */
425
    public function thisProductHasOptionWithValues(ProductInterface $product, $optionName, ...$values)
426
    {
427
        /** @var ProductOptionInterface $option */
428
        $option = $this->productOptionFactory->createNew();
429
430
        $option->setName($optionName);
431
        $option->setCode(StringInflector::nameToUppercaseCode($optionName));
432
433
        $this->sharedStorage->set(sprintf('%s_option', $optionName), $option);
434
435
        foreach ($values as $key => $value) {
436
            $optionValue = $this->addProductOption($option, $value, StringInflector::nameToUppercaseCode($value));
437
            $this->sharedStorage->set(sprintf('%s_option_%s_value', $value, strtolower($optionName)), $optionValue);
438
        }
439
440
        $product->addOption($option);
441
        $product->setVariantSelectionMethod(ProductInterface::VARIANT_SELECTION_MATCH);
442
443
        $this->objectManager->persist($option);
444
        $this->objectManager->flush();
445
    }
446
447
    /**
448
     * @Given /^there (?:is|are) (\d+) unit(?:|s) of (product "([^"]+)") available in the inventory$/
449
     * @When product :product quantity is changed to :quantity
450
     */
451
    public function thereIsQuantityOfProducts($quantity, ProductInterface $product)
452
    {
453
        /** @var ProductVariantInterface $productVariant */
454
        $productVariant = $this->defaultVariantResolver->getVariant($product);
455
        $productVariant->setOnHand($quantity);
456
457
        $this->objectManager->flush();
458
    }
459
460
    /**
461
     * @Given /^the (product "([^"]+)") is out of stock$/
462
     */
463
    public function theProductIsOutOfStock(ProductInterface $product)
464
    {
465
        /** @var ProductVariantInterface $productVariant */
466
        $productVariant = $this->defaultVariantResolver->getVariant($product);
467
        $productVariant->setTracked(true);
468
        $productVariant->setOnHand(0);
469
470
        $this->objectManager->flush();
471
    }
472
473
    /**
474
     * @When other customer has bought :quantity :product products by this time
475
     */
476
    public function otherCustomerHasBoughtProductsByThisTime($quantity, ProductInterface $product)
477
    {
478
        /** @var ProductVariantInterface $productVariant */
479
        $productVariant = $this->defaultVariantResolver->getVariant($product);
480
        $productVariant->setOnHand($productVariant->getOnHand() - $quantity);
481
482
        $this->objectManager->flush();
483
    }
484
485
    /**
486
     * @Given /^(this product) is tracked by the inventory$/
487
     * @Given /^(?:|the )("[^"]+" product) is(?:| also) tracked by the inventory$/
488
     */
489
    public function thisProductIsTrackedByTheInventory(ProductInterface $product)
490
    {
491
        /** @var ProductVariantInterface $productVariant */
492
        $productVariant = $this->defaultVariantResolver->getVariant($product);
493
        $productVariant->setTracked(true);
494
495
        $this->objectManager->flush();
496
    }
497
498
    /**
499
     * @Given /^(this product) is available in "([^"]+)" ([^"]+) priced at ("[^"]+")$/
500
     */
501
    public function thisProductIsAvailableInSize(ProductInterface $product, $optionValueName, $optionName, $price)
502
    {
503
        /** @var ProductVariantInterface $variant */
504
        $variant = $this->productVariantFactory->createNew();
505
506
        $optionValue = $this->sharedStorage->get(sprintf('%s_option_%s_value', $optionValueName, $optionName));
507
508
        $variant->addOptionValue($optionValue);
509
        $variant->setPrice($price);
510
        $variant->setCode(sprintf("%s_%s", $product->getCode(), $optionValueName));
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal %s_%s does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
511
512
        $product->addVariant($variant);
513
        $this->objectManager->flush();
514
    }
515
516
    /**
517
     * @Given /^(this product) has (this product option)$/
518
     * @Given /^(this product) has a ("[^"]+" option)$/
519
     * @Given /^(this product) has an ("[^"]+" option)$/
520
     */
521
    public function thisProductHasThisProductOption(ProductInterface $product, ProductOptionInterface $option)
522
    {
523
        $product->addOption($option);
524
525
        $this->objectManager->flush();
526
    }
527
528
    /**
529
     * @Given /^there are ([^"]+) units of ("[^"]+" variant of product "[^"]+") available in the inventory$/
530
     */
531
    public function thereAreItemsOfProductInVariantAvailableInTheInventory($quantity, ProductVariantInterface $productVariant)
532
    {
533
        $productVariant->setTracked(true);
534
        $productVariant->setOnHand($quantity);
535
536
        $this->objectManager->flush();
537
    }
538
539
    /**
540
     * @Given /^the ("[^"]+" product variant) is tracked by the inventory$/
541
     */
542
    public function theProductVariantIsTrackedByTheInventory(ProductVariantInterface $productVariant)
543
    {
544
        $productVariant->setTracked(true);
545
546
        $this->objectManager->flush();
547
    }
548
549
    /**
550
     * @Given /^(this product)'s price is ("[^"]+")$/
551
     * @Given /^the (product "[^"]+") changed its price to ("[^"]+")$/
552
     */
553
    public function theProductChangedItsPriceTo(ProductInterface $product, $price)
554
    {
555
        /** @var ProductVariantInterface $productVariant */
556
        $productVariant = $this->defaultVariantResolver->getVariant($product);
557
        $productVariant->setPrice($price);
558
559
        $this->objectManager->flush();
560
    }
561
562
    /**
563
     * @Given /^(this product) has(?:| also) an image "([^"]+)" with a code "([^"]+)"$/
564
     * @Given /^the ("[^"]+" product) has(?:| also) an image "([^"]+)" with a code "([^"]+)"$/
565
     */
566
    public function thisProductHasAnImageWithACode(ProductInterface $product, $imagePath, $imageCode)
567
    {
568
        $filesPath = $this->getParameter('files_path');
569
570
        /** @var ImageInterface $productImage */
571
        $productImage = $this->productImageFactory->createNew();
572
        $productImage->setFile(new UploadedFile($filesPath.$imagePath, basename($imagePath)));
573
        $productImage->setCode($imageCode);
574
        $this->imageUploader->upload($productImage);
575
576
        $product->addImage($productImage);
577
578
        $this->objectManager->flush($product);
579
    }
580
581
    /**
582
     * @Given /^(it) has different prices for different channels and currencies$/
583
     */
584
    public function itHasDifferentPricesForDifferentChannelsAndCurrencies(ProductInterface $product)
585
    {
586
        /** @var ProductVariantInterface $variant */
587
        $variant = $this->defaultVariantResolver->getVariant($product);
588
589
        $variant->setPricingCalculator(Calculators::CHANNEL_AND_CURRENCY_BASED);
590
    }
591
592
    /**
593
     * @Given /^(it) has price ("[^"]+") for ("[^"]+" channel) and "([^"]+)" currency$/
594
     */
595
    public function itHasPriceForChannelAndCurrency(
596
        ProductInterface $product,
597
        $price,
598
        ChannelInterface $channel,
599
        $currency
600
    ) {
601
        /** @var ProductVariantInterface $variant */
602
        $variant = $this->defaultVariantResolver->getVariant($product);
603
604
        $pricingConfiguration = $variant->getPricingConfiguration();
605
        $pricingConfiguration[$channel->getCode()][$currency] = $price;
606
607
        $variant->setPricingConfiguration($pricingConfiguration);
608
609
        $this->objectManager->flush();
610
    }
611
612
    /**
613
     * @param string $type
614
     * @param string $name
615
     * @param string $code
616
     *
617
     * @return ProductAttributeInterface
618
     */
619
    private function createProductAttribute($type, $name, $code = 'PA112')
620
    {
621
        $productAttribute = $this->productAttributeFactory->createTyped($type);
622
        $productAttribute->setCode($code);
623
        $productAttribute->setName($name);
624
625
        $this->objectManager->persist($productAttribute);
626
627
        return $productAttribute;
628
    }
629
630
    /**
631
     * @param string $value
632
     *
633
     * @return ProductAttributeValueInterface
634
     */
635
    private function createProductAttributeValue($value, ProductAttributeInterface $attribute)
636
    {
637
        /** @var ProductAttributeValueInterface $attributeValue */
638
        $attributeValue = $this->attributeValueFactory->createNew();
639
        $attributeValue->setAttribute($attribute);
640
        $attributeValue->setValue($value);
641
642
        $this->objectManager->persist($attributeValue);
643
644
        return $attributeValue;
645
    }
646
647
    /**
648
     * @param string $price
649
     *
650
     * @return int
651
     */
652
    private function getPriceFromString($price)
653
    {
654
        return (int) round(($price * 100), 2);
655
    }
656
657
    /**
658
     * @param string $productName
659
     * @param int $price
660
     *
661
     * @return ProductInterface
662
     */
663
    private function createProduct($productName, $price = 0, $date = null)
664
    {
665
        /** @var ProductInterface $product */
666
        $product = $this->productFactory->createWithVariant();
667
668
        $product->setName($productName);
669
        $product->setCode(StringInflector::nameToUppercaseCode($productName));
670
        $product->setSlug($this->slugGenerator->generate($productName));
671
        $product->setCreatedAt(new \DateTime($date));
672
673
        /** @var ProductVariantInterface $productVariant */
674
        $productVariant = $this->defaultVariantResolver->getVariant($product);
675
        $productVariant->setPrice($price);
676
        $productVariant->setCode($product->getCode());
677
678
        return $product;
679
    }
680
681
    /**
682
     * @param ProductOptionInterface $option
683
     * @param string $value
684
     * @param string $code
685
     *
686
     * @return ProductOptionValueInterface
687
     */
688
    private function addProductOption(ProductOptionInterface $option, $value, $code)
689
    {
690
        /** @var ProductOptionValueInterface $optionValue */
691
        $optionValue = $this->productOptionValueFactory->createNew();
692
693
        $optionValue->setValue($value);
694
        $optionValue->setCode($code);
695
        $optionValue->setOption($option);
696
697
        $option->addValue($optionValue);
698
699
        return $optionValue;
700
    }
701
702
    /**
703
     * @param ProductInterface $product
704
     */
705
    private function saveProduct(ProductInterface $product)
706
    {
707
        $this->productRepository->add($product);
708
        $this->sharedStorage->set('product', $product);
709
    }
710
711
    /**
712
     * @param string $name
713
     *
714
     * @return NodeElement
715
     */
716
    private function getParameter($name)
717
    {
718
        return isset($this->minkParameters[$name]) ? $this->minkParameters[$name] : null;
719
    }
720
721
    /**
722
     * @param ProductInterface $product
723
     * @param $productVariantName
724
     * @param int $price
725
     * @param string $code
726
     */
727
    private function createProductVariant(ProductInterface $product, $productVariantName, $price, $code)
728
    {
729
        $product->setVariantSelectionMethod(ProductInterface::VARIANT_SELECTION_CHOICE);
730
731
        /** @var ProductVariantInterface $variant */
732
        $variant = $this->productVariantFactory->createNew();
733
734
        $variant->setName($productVariantName);
735
        $variant->setCode($code);
736
        $variant->setPrice($price);
737
        $variant->setProduct($product);
738
        $product->addVariant($variant);
739
740
        $this->objectManager->flush();
741
742
        $this->sharedStorage->set('variant', $variant);
743
    }
744
}
745