Completed
Push — master ( a37554...50cd1a )
by Kamil
47:44 queued 26:04
created

thisProductHasSelectAttributeWithValues()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 17
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 17
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 13
nc 1
nop 6
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 Doctrine\Common\Persistence\ObjectManager;
16
use Sylius\Behat\Service\SharedStorageInterface;
17
use Sylius\Component\Attribute\Factory\AttributeFactoryInterface;
18
use Sylius\Component\Attribute\Repository\AttributeRepositoryInterface;
19
use Sylius\Component\Core\Formatter\StringInflector;
20
use Sylius\Component\Core\Model\ProductInterface;
21
use Sylius\Component\Product\Model\ProductAttributeInterface;
22
use Sylius\Component\Product\Model\ProductAttributeValueInterface;
23
use Sylius\Component\Resource\Factory\FactoryInterface;
24
25
/**
26
 * @author Anna Walasek <[email protected]>
27
 */
28
final class ProductAttributeContext implements Context
29
{
30
    /**
31
     * @var SharedStorageInterface
32
     */
33
    private $sharedStorage;
34
35
    /**
36
     * @var AttributeRepositoryInterface
37
     */
38
    private $productAttributeRepository;
39
40
    /**
41
     * @var AttributeFactoryInterface
42
     */
43
    private $productAttributeFactory;
44
45
    /**
46
     * @var FactoryInterface
47
     */
48
    private $productAttributeValueFactory;
49
50
    /**
51
     * @var ObjectManager
52
     */
53
    private $objectManager;
54
55
    /**
56
     * @param SharedStorageInterface $sharedStorage
57
     * @param AttributeRepositoryInterface $productAttributeRepository
58
     * @param AttributeFactoryInterface $productAttributeFactory
59
     * @param FactoryInterface $productAttributeValueFactory
60
     * @param ObjectManager $objectManager
61
     */
62
    public function __construct(
63
        SharedStorageInterface $sharedStorage,
64
        AttributeRepositoryInterface $productAttributeRepository,
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $productAttributeRepository exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
65
        AttributeFactoryInterface $productAttributeFactory,
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $productAttributeFactory exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
66
        FactoryInterface $productAttributeValueFactory,
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $productAttributeValueFactory exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
67
        ObjectManager $objectManager
68
    ) {
69
        $this->sharedStorage = $sharedStorage;
70
        $this->productAttributeRepository = $productAttributeRepository;
71
        $this->productAttributeFactory = $productAttributeFactory;
72
        $this->productAttributeValueFactory = $productAttributeValueFactory;
73
        $this->objectManager = $objectManager;
74
    }
75
76
    /**
77
     * @Given the store has a :type product attribute :name with code :code
78
     */
79
    public function theStoreHasAProductAttributeWithCode($type, $name, $code)
80
    {
81
        $productAttribute = $this->createProductAttribute($type, $name, $code);
82
83
        $this->saveProductAttribute($productAttribute);
84
    }
85
86
    /**
87
     * @Given the store( also) has a :type product attribute :name at position :position
88
     */
89
    public function theStoreHasAProductAttributeWithPosition($type, $name, $position)
90
    {
91
        $productAttribute = $this->createProductAttribute($type, $name);
92
        $productAttribute->setPosition($position);
93
94
        $this->saveProductAttribute($productAttribute);
95
    }
96
97
    /**
98
     * @Given the store( also) has a :type product attribute :name
99
     */
100
    public function theStoreHasATextProductAttribute($type, $name)
101
    {
102
        $productAttribute = $this->createProductAttribute($type, $name);
103
104
        $this->saveProductAttribute($productAttribute);
105
    }
106
107
    /**
108
     * @Given /^(this product) has (.+?) attribute "([^"]+)" with values "([^"]+)", "([^"]+)"$/
109
     */
110
    public function thisProductHasSelectAttributeWithValues(
111
        ProductInterface $product,
112
        $productAttributeType,
113
        $productAttributeName,
114
        $firstAttributeValue,
115
        $secondAttributeValue,
116
        $language = 'en_US'
117
    ) {
118
        $values = [$firstAttributeValue, $secondAttributeValue];
119
120
        $attribute = $this->provideProductAttribute($productAttributeType, $productAttributeName);
121
        $attribute->setConfiguration(['multiple' => true, 'choices' => $values, 'min' => null, 'max' => null]);
122
        $attributeValue = $this->createProductAttributeValue(array_keys($values), $attribute, $language);
0 ignored issues
show
Documentation introduced by
array_keys($values) is of type array<integer,integer>, 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...
123
        $product->addAttribute($attributeValue);
124
125
        $this->objectManager->flush();
126
    }
127
128
    /**
129
     * @Given /^(this product) has (.+?) attribute "([^"]+)" with value "([^"]+)"$/
130
     * @Given /^(this product) has (.+?) attribute "([^"]+)" with value "([^"]+)" in ("[^"]+" locale)$/
131
     */
132
    public function thisProductHasAttributeWithValue(
133
        ProductInterface $product,
134
        $productAttributeType,
135
        $productAttributeName,
136
        $value,
137
        $language = 'en_US'
138
    ) {
139
        $attribute = $this->provideProductAttribute($productAttributeType, $productAttributeName);
140
        $attributeValue = $this->createProductAttributeValue($value, $attribute, $language);
141
        $product->addAttribute($attributeValue);
142
143
        $this->objectManager->flush();
144
    }
145
146
    /**
147
     * @Given /^(this product) has percent attribute "([^"]+)" with value ([^"]+)%$/
148
     */
149
    public function thisProductHasPercentAttributeWithValue(ProductInterface $product, $productAttributeName, $value)
150
    {
151
        $attribute = $this->provideProductAttribute('percent', $productAttributeName);
152
        $attributeValue = $this->createProductAttributeValue($value/100, $attribute);
153
        $product->addAttribute($attributeValue);
154
155
        $this->objectManager->flush();
156
    }
157
158
    /**
159
     * @Given /^(this product) has ([^"]+) attribute "([^"]+)" set to "([^"]+)"$/
160
     */
161
    public function thisProductHasCheckboxAttributeWithValue(ProductInterface $product, $productAttributeType, $productAttributeName, $value)
162
    {
163
        $attribute = $this->provideProductAttribute($productAttributeType, $productAttributeName);
164
        $booleanValue = ('Yes' === $value);
165
        $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...
166
        $product->addAttribute($attributeValue);
167
168
        $this->objectManager->flush();
169
    }
170
171
    /**
172
     * @Given /^(this product) has percent attribute "([^"]+)" at position (\d+)$/
173
     */
174
    public function thisProductHasPercentAttributeWithValueAtPosition(ProductInterface $product, $productAttributeName, $position)
175
    {
176
        $attribute = $this->provideProductAttribute('percent', $productAttributeName);
177
        $attribute->setPosition($position);
178
        $attributeValue = $this->createProductAttributeValue(rand(1, 100)/100, $attribute);
179
180
        $product->addAttribute($attributeValue);
181
182
        $this->objectManager->flush();
183
    }
184
185
    /**
186
     * @Given /^(this product) has ([^"]+) attribute "([^"]+)" with date "([^"]+)"$/
187
     */
188
    public function thisProductHasDateTimeAttributeWithDate(ProductInterface $product, $productAttributeType, $productAttributeName, $date)
189
    {
190
        $attribute = $this->provideProductAttribute($productAttributeType, $productAttributeName);
191
        $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...
192
193
        $product->addAttribute($attributeValue);
194
195
        $this->objectManager->flush();
196
    }
197
198
    /**
199
     * @param string $type
200
     * @param string $name
201
     * @param string|null $code
202
     *
203
     * @return ProductAttributeInterface
204
     */
205
    private function createProductAttribute($type, $name, $code = null)
206
    {
207
        $productAttribute = $this->productAttributeFactory->createTyped($type);
208
209
        $code = $code ?: StringInflector::nameToCode($name);
210
211
        $productAttribute->setCode($code);
212
        $productAttribute->setName($name);
213
214
        return $productAttribute;
215
    }
216
217
    /**
218
     * @param string $type
219
     * @param string $name
220
     * @param string|null $code
221
     *
222
     * @return ProductAttributeInterface
223
     */
224
    private function provideProductAttribute($type, $name, $code = null)
225
    {
226
        $code = $code ?: StringInflector::nameToCode($name);
227
228
        /** @var ProductAttributeInterface $productAttribute */
229
        $productAttribute = $this->productAttributeRepository->findOneBy(['code' => $code]);
230
        if (null !== $productAttribute) {
231
            return $productAttribute;
232
        }
233
234
        $productAttribute = $this->createProductAttribute($type, $name, $code);
235
        $this->saveProductAttribute($productAttribute);
236
237
        return $productAttribute;
238
    }
239
240
    /**
241
     * @param string $value
242
     * @param ProductAttributeInterface $attribute
243
     * @param string $localeCode
244
     *
245
     * @return ProductAttributeValueInterface
246
     */
247
    private function createProductAttributeValue($value, ProductAttributeInterface $attribute, $localeCode = 'en_US')
248
    {
249
        /** @var ProductAttributeValueInterface $attributeValue */
250
        $attributeValue = $this->productAttributeValueFactory->createNew();
251
        $attributeValue->setAttribute($attribute);
252
        $attributeValue->setValue($value);
253
        $attributeValue->setLocaleCode($localeCode);
254
255
        $this->objectManager->persist($attributeValue);
256
257
        return $attributeValue;
258
    }
259
260
    /**
261
     * @param ProductAttributeInterface $productAttribute
262
     */
263
    private function saveProductAttribute(ProductAttributeInterface $productAttribute)
264
    {
265
        $this->productAttributeRepository->add($productAttribute);
266
        $this->sharedStorage->set('product_attribute', $productAttribute);
267
    }
268
}
269