Completed
Push — master ( 2c8981...1ecbe4 )
by Kamil
23:19
created

ProductContext   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 327
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 10

Importance

Changes 3
Bugs 0 Features 2
Metric Value
wmc 17
c 3
b 0
f 2
lcom 1
cbo 10
dl 0
loc 327
rs 10

16 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 21 1
A storeHasAProductPricedAt() 0 16 1
A theProductHasVariantPricedAt() 0 14 1
A thereIsProductAvailableInGivenChannel() 0 12 1
A productBelongsToTaxCategory() 0 5 1
A itComesInTheFollowingVariations() 0 14 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
B thisProductHasOptionWithValues() 0 37 1
A thisProductIsAvailableInSize() 0 13 1
A createProductAttribute() 0 10 1
A createProductAttributeValue() 0 11 1
A getPriceFromString() 0 4 1
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 Doctrine\Common\Persistence\ObjectManager;
17
use Sylius\Component\Attribute\Factory\AttributeFactoryInterface;
18
use Sylius\Component\Core\Model\ChannelInterface;
19
use Sylius\Component\Core\Model\ProductInterface;
20
use Sylius\Component\Core\Model\ProductVariantInterface;
21
use Sylius\Component\Core\Repository\ProductRepositoryInterface;
22
use Sylius\Component\Core\Test\Services\SharedStorageInterface;
23
use Sylius\Component\Product\Model\AttributeInterface;
24
use Sylius\Component\Product\Model\AttributeValueInterface;
25
use Sylius\Component\Product\Model\OptionInterface;
26
use Sylius\Component\Product\Model\OptionValueInterface;
27
use Sylius\Component\Resource\Factory\FactoryInterface;
28
use Sylius\Component\Taxation\Model\TaxCategoryInterface;
29
30
/**
31
 * @author Arkadiusz Krakowiak <[email protected]>
32
 * @author Mateusz Zalewski <[email protected]>
33
 * @author Magdalena Banasiak <[email protected]>
34
 */
35
final class ProductContext implements Context
36
{
37
    /**
38
     * @var SharedStorageInterface
39
     */
40
    private $sharedStorage;
41
42
    /**
43
     * @var ProductRepositoryInterface
44
     */
45
    private $productRepository;
46
47
    /**
48
     * @var FactoryInterface
49
     */
50
    private $productFactory;
51
52
    /**
53
     * @var AttributeFactoryInterface
54
     */
55
    private $productAttributeFactory;
56
57
    /**
58
     * @var FactoryInterface
59
     */
60
    private $productVariantFactory;
61
62
    /**
63
     * @var FactoryInterface
64
     */
65
    private $attributeValueFactory;
66
67
    /**
68
     * @var FactoryInterface
69
     */
70
    private $productOptionFactory;
71
72
    /**
73
     * @var FactoryInterface
74
     */
75
    private $productOptionValueFactory;
76
77
    /**
78
     * @var ObjectManager
79
     */
80
    private $objectManager;
81
82
    /**
83
     * @param SharedStorageInterface $sharedStorage
84
     * @param ProductRepositoryInterface $productRepository
85
     * @param FactoryInterface $productFactory
86
     * @param AttributeFactoryInterface $productAttributeFactory
87
     * @param FactoryInterface $productVariantFactory
88
     * @param FactoryInterface $attributeValueFactory
89
     * @param FactoryInterface $productOptionFactory
90
     * @param FactoryInterface $productOptionValueFactory
91
     * @param ObjectManager $objectManager
92
     */
93
    public function __construct(
94
        SharedStorageInterface $sharedStorage,
95
        ProductRepositoryInterface $productRepository,
96
        FactoryInterface $productFactory,
97
        AttributeFactoryInterface $productAttributeFactory,
98
        FactoryInterface $attributeValueFactory,
99
        FactoryInterface $productVariantFactory,
100
        FactoryInterface $productOptionFactory,
101
        FactoryInterface $productOptionValueFactory,
102
        ObjectManager $objectManager
103
    ) {
104
        $this->sharedStorage = $sharedStorage;
105
        $this->productRepository = $productRepository;
106
        $this->productFactory = $productFactory;
107
        $this->productAttributeFactory = $productAttributeFactory;
108
        $this->attributeValueFactory = $attributeValueFactory;
109
        $this->productVariantFactory = $productVariantFactory;
110
        $this->productOptionFactory = $productOptionFactory;
111
        $this->productOptionValueFactory = $productOptionValueFactory;
112
        $this->objectManager = $objectManager;
113
    }
114
115
    /**
116
     * @Given /^the store has a product "([^"]+)"$/
117
     * @Given /^the store has a product "([^"]+)" priced at ("[^"]+")$/
118
     */
119
    public function storeHasAProductPricedAt($productName, $price = 0)
120
    {
121
        /** @var ProductInterface $product */
122
        $product = $this->productFactory->createNew();
123
124
        $product->setName($productName);
125
        $product->setPrice($price);
126
        $product->setDescription('Awesome '.$productName);
127
128
        $channel = $this->sharedStorage->get('channel');
129
        $product->addChannel($channel);
130
131
        $this->productRepository->add($product);
132
133
        $this->sharedStorage->set('product', $product);
134
    }
135
136
    /**
137
     * @Given /^the (product "[^"]+") has "([^"]+)" variant priced at ("[^"]+")$/
138
     * @Given /^(this product) has "([^"]+)" variant priced at ("[^"]+")$/
139
     */
140
    public function theProductHasVariantPricedAt(ProductInterface $product, $productVariantName, $price)
141
    {
142
        /** @var ProductVariantInterface $variant */
143
        $variant = $this->productVariantFactory->createNew();
144
145
        $variant->setPresentation($productVariantName);
146
        $variant->setPrice($price);
147
        $variant->setProduct($product);
148
        $product->addVariant($variant);
149
150
        $this->objectManager->flush();
151
152
        $this->sharedStorage->set('variant', $variant);
153
    }
154
155
    /**
156
     * @Given /^there is product "([^"]+)" available in ((?:this|that|"[^"]+") channel)$/
157
     */
158
    public function thereIsProductAvailableInGivenChannel($productName, ChannelInterface $channel)
159
    {
160
        /** @var ProductInterface $product */
161
        $product = $this->productFactory->createNew();
162
163
        $product->setName($productName);
164
        $product->setPrice(0);
165
        $product->setDescription('Awesome ' . $productName);
166
        $product->addChannel($channel);
167
168
        $this->productRepository->add($product);
169
    }
170
171
    /**
172
     * @Given /^([^"]+) belongs to ("[^"]+" tax category)$/
173
     */
174
    public function productBelongsToTaxCategory(ProductInterface $product, TaxCategoryInterface $taxCategory)
175
    {
176
        $product->getMasterVariant()->setTaxCategory($taxCategory);
177
        $this->objectManager->flush();
178
    }
179
180
    /**
181
     * @Given /^(it) comes in the following variations:$/
182
     */
183
    public function itComesInTheFollowingVariations(ProductInterface $product, TableNode $table)
184
    {
185
        foreach ($table->getHash() as $variantHash) {
186
            /** @var ProductVariantInterface $variant */
187
            $variant = $this->productVariantFactory->createNew();
188
189
            $variant->setPresentation($variantHash['name']);
190
            $variant->setPrice($this->getPriceFromString(str_replace(['$', '€', '£'], '', $variantHash['price'])));
191
            $variant->setProduct($product);
192
            $product->addVariant($variant);
193
        }
194
195
        $this->objectManager->flush();
196
    }
197
198
    /**
199
     * @Given /^("[^"]+" variant of product "[^"]+") belongs to ("[^"]+" tax category)$/
200
     */
201
    public function productVariantBelongsToTaxCategory(
202
        ProductVariantInterface $productVariant,
203
        TaxCategoryInterface $taxCategory
204
    ) {
205
        $productVariant->setTaxCategory($taxCategory);
206
        $this->objectManager->flush($productVariant);
207
    }
208
209
    /**
210
     * @Given /^(this product) has ([^"]+) attribute "([^"]+)" with value "([^"]+)"$/
211
     */
212
    public function thisProductHasAttributeWithValue(ProductInterface $product, $productAttributeType, $productAttributeName, $value)
213
    {
214
        $attribute = $this->createProductAttribute($productAttributeType,$productAttributeName);
215
        $attributeValue = $this->createProductAttributeValue($value, $attribute);
216
        $product->addAttribute($attributeValue);
217
218
        $this->objectManager->flush();
219
    }
220
221
    /**
222
     * @Given /^(this product) has percent attribute "([^"]+)" with value ([^"]+)%$/
223
     */
224
    public function thisProductHasPercentAttributeWithValue(ProductInterface $product, $productAttributeName, $value)
225
    {
226
        $attribute = $this->createProductAttribute('percent',$productAttributeName);
227
        $attributeValue = $this->createProductAttributeValue($value/100, $attribute);
228
        $product->addAttribute($attributeValue);
229
230
        $this->objectManager->flush();
231
    }
232
233
    /**
234
     * @Given /^(this product) has ([^"]+) attribute "([^"]+)" set to "([^"]+)"$/
235
     */
236
    public function thisProductHasCheckboxAttributeWithValue(ProductInterface $product, $productAttributeType, $productAttributeName, $value)
237
    {
238
        $attribute = $this->createProductAttribute($productAttributeType, $productAttributeName);
239
        $booleanValue = ('Yes' === $value);
240
        $attributeValue = $this->createProductAttributeValue($booleanValue, $attribute);
241
        $product->addAttribute($attributeValue);
242
243
        $this->objectManager->flush();
244
    }
245
246
    /**
247
     * @Given /^(this product) has ([^"]+) attribute "([^"]+)" with date "([^"]+)"$/
248
     */
249
    public function thisProductHasDateTimeAttributeWithDate(ProductInterface $product, $productAttributeType, $productAttributeName, $date)
250
    {
251
        $attribute = $this->createProductAttribute($productAttributeType, $productAttributeName);
252
        $attributeValue = $this->createProductAttributeValue(new \DateTime($date), $attribute);
253
254
        $product->addAttribute($attributeValue);
255
256
        $this->objectManager->flush();
257
    }
258
259
    /**
260
     * @Given /^(this product) has option "([^"]+)" with values "([^"]+)" and "([^"]+)"$/
261
     */
262
    public function thisProductHasOptionWithValues(ProductInterface $product, $optionName, $firstValue, $secondValue)
263
    {
264
        /** @var OptionInterface $variant */
265
        $option = $this->productOptionFactory->createNew();
266
267
        $option->setName($optionName);
268
        $option->setCode('PO1');
269
270
        /** @var OptionValueInterface $optionValue */
271
        $firstOptionValue = $this->productOptionValueFactory->createNew();
272
273
        $firstOptionValue->setValue($firstValue);
274
        $firstOptionValue->setCode('POV1');
275
        $firstOptionValue->setOption($option);
276
277
        /** @var OptionValueInterface $optionValue */
278
        $secondOptionValue = $this->productOptionValueFactory->createNew();
279
280
        $secondOptionValue->setValue($secondValue);
281
        $secondOptionValue->setCode('POV2');
282
        $secondOptionValue->setOption($option);
283
284
        $option->addValue($firstOptionValue);
285
        $option->addValue($secondOptionValue);
286
287
        $product->addOption($option);
288
        $product->setVariantSelectionMethod(ProductInterface::VARIANT_SELECTION_MATCH);
289
290
        $this->sharedStorage->set(sprintf('%s_option',$optionName), $option);
291
        $this->sharedStorage->set(sprintf('%s_option_value',$firstValue), $firstOptionValue);
292
        $this->sharedStorage->set(sprintf('%s_option_value',$secondValue), $secondOptionValue);
293
294
        $this->objectManager->persist($option);
295
        $this->objectManager->persist($firstOptionValue);
296
        $this->objectManager->persist($secondOptionValue);
297
        $this->objectManager->flush();
298
    }
299
300
    /**
301
     * @Given /^(this product) is available in "([^"]+)" size priced at ("[^"]+")$/
302
     */
303
    public function thisProductIsAvailableInSize(ProductInterface $product, $optionValueName, $price)
304
    {
305
        /** @var ProductVariantInterface $variant */
306
        $variant = $this->productVariantFactory->createNew();
307
308
        $optionValue = $this->sharedStorage->get(sprintf('%s_option_value',$optionValueName));
309
310
        $variant->addOption($optionValue);
311
        $variant->setPrice($price);
312
313
        $product->addVariant($variant);
314
        $this->objectManager->flush();
315
    }
316
317
    /**
318
     * @param string $type
319
     * @param string $name
320
     * @param string $code
321
     *
322
     * @return AttributeInterface
323
     */
324
    private function createProductAttribute($type, $name, $code = 'PA112')
325
    {
326
        $productAttribute = $this->productAttributeFactory->createTyped($type);
327
        $productAttribute->setCode($code);
328
        $productAttribute->setName($name);
329
330
        $this->objectManager->persist($productAttribute);
331
332
        return $productAttribute;
333
    }
334
335
    /**
336
     * @param string $value
337
     *
338
     * @return AttributeValueInterface
339
     */
340
    private function createProductAttributeValue($value, AttributeInterface $attribute)
341
    {
342
        /** @var AttributeValueInterface $attributeValue */
343
        $attributeValue = $this->attributeValueFactory->createNew();
344
        $attributeValue->setAttribute($attribute);
345
        $attributeValue->setValue($value);
346
347
        $this->objectManager->persist($attributeValue);
348
349
        return $attributeValue;
350
    }
351
352
    /**
353
     * @param string $price
354
     *
355
     * @return int
356
     */
357
    private function getPriceFromString($price)
358
    {
359
        return (int) round(($price * 100), 2);
360
    }
361
}
362