Completed
Push — master ( 2973d0...13f9fe )
by Michał
10:17
created

ProductAttributeContext::provideProductAttribute()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 15
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 8
nc 4
nop 3
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,
65
        AttributeFactoryInterface $productAttributeFactory,
66
        FactoryInterface $productAttributeValueFactory,
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 value "([^"]+)"$/
109
     * @Given /^(this product) has (.+?) attribute "([^"]+)" with value "([^"]+)" in ("[^"]+" locale)$/
110
     */
111
    public function thisProductHasAttributeWithValue(
112
        ProductInterface $product,
113
        $productAttributeType,
114
        $productAttributeName,
115
        $value,
116
        $language = 'en_US'
117
    ) {
118
        $attribute = $this->provideProductAttribute($productAttributeType, $productAttributeName);
119
        $attributeValue = $this->createProductAttributeValue($value, $attribute, $language);
120
        $product->addAttribute($attributeValue);
121
122
        $this->objectManager->flush();
123
    }
124
125
    /**
126
     * @Given /^(this product) has percent attribute "([^"]+)" with value ([^"]+)%$/
127
     */
128
    public function thisProductHasPercentAttributeWithValue(ProductInterface $product, $productAttributeName, $value)
129
    {
130
        $attribute = $this->provideProductAttribute('percent', $productAttributeName);
131
        $attributeValue = $this->createProductAttributeValue($value/100, $attribute);
132
        $product->addAttribute($attributeValue);
133
134
        $this->objectManager->flush();
135
    }
136
137
    /**
138
     * @Given /^(this product) has ([^"]+) attribute "([^"]+)" set to "([^"]+)"$/
139
     */
140
    public function thisProductHasCheckboxAttributeWithValue(ProductInterface $product, $productAttributeType, $productAttributeName, $value)
141
    {
142
        $attribute = $this->provideProductAttribute($productAttributeType, $productAttributeName);
143
        $booleanValue = ('Yes' === $value);
144
        $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...
145
        $product->addAttribute($attributeValue);
146
147
        $this->objectManager->flush();
148
    }
149
150
    /**
151
     * @Given /^(this product) has percent attribute "([^"]+)" at position (\d+)$/
152
     */
153
    public function thisProductHasPercentAttributeWithValueAtPosition(ProductInterface $product, $productAttributeName, $position)
154
    {
155
        $attribute = $this->provideProductAttribute('percent', $productAttributeName);
156
        $attribute->setPosition($position);
157
        $attributeValue = $this->createProductAttributeValue(rand(1, 100)/100, $attribute);
158
159
        $product->addAttribute($attributeValue);
160
161
        $this->objectManager->flush();
162
    }
163
164
    /**
165
     * @Given /^(this product) has ([^"]+) attribute "([^"]+)" with date "([^"]+)"$/
166
     */
167
    public function thisProductHasDateTimeAttributeWithDate(ProductInterface $product, $productAttributeType, $productAttributeName, $date)
168
    {
169
        $attribute = $this->provideProductAttribute($productAttributeType, $productAttributeName);
170
        $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...
171
172
        $product->addAttribute($attributeValue);
173
174
        $this->objectManager->flush();
175
    }
176
177
    /**
178
     * @param string $type
179
     * @param string $name
180
     * @param string|null $code
181
     *
182
     * @return ProductAttributeInterface
183
     */
184
    private function createProductAttribute($type, $name, $code = null)
185
    {
186
        $productAttribute = $this->productAttributeFactory->createTyped($type);
187
188
        $code = $code ?: StringInflector::nameToCode($name);
189
190
        $productAttribute->setCode($code);
191
        $productAttribute->setName($name);
192
193
        return $productAttribute;
194
    }
195
196
    /**
197
     * @param string $type
198
     * @param string $name
199
     * @param string|null $code
200
     *
201
     * @return ProductAttributeInterface
202
     */
203
    private function provideProductAttribute($type, $name, $code = null)
204
    {
205
        $code = $code ?: StringInflector::nameToCode($name);
206
207
        /** @var ProductAttributeInterface $productAttribute */
208
        $productAttribute = $this->productAttributeRepository->findOneBy(['code' => $code]);
209
        if (null !== $productAttribute) {
210
            return $productAttribute;
211
        }
212
213
        $productAttribute = $this->createProductAttribute($type, $name, $code);
214
        $this->saveProductAttribute($productAttribute);
215
216
        return $productAttribute;
217
    }
218
219
    /**
220
     * @param string $value
221
     * @param ProductAttributeInterface $attribute
222
     * @param string $localeCode
223
     *
224
     * @return ProductAttributeValueInterface
225
     */
226
    private function createProductAttributeValue($value, ProductAttributeInterface $attribute, $localeCode = 'en_US')
227
    {
228
        /** @var ProductAttributeValueInterface $attributeValue */
229
        $attributeValue = $this->productAttributeValueFactory->createNew();
230
        $attributeValue->setAttribute($attribute);
231
        $attributeValue->setValue($value);
232
        $attributeValue->setLocaleCode($localeCode);
233
234
        $this->objectManager->persist($attributeValue);
235
236
        return $attributeValue;
237
    }
238
239
    /**
240
     * @param ProductAttributeInterface $productAttribute
241
     */
242
    private function saveProductAttribute(ProductAttributeInterface $productAttribute)
243
    {
244
        $this->productAttributeRepository->add($productAttribute);
245
        $this->sharedStorage->set('product_attribute', $productAttribute);
246
    }
247
}
248