Completed
Push — master ( d08296...3ca74c )
by Fabian
12s
created

ProductBuilder::withWeight()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace TddWizard\Fixtures\Catalog;
4
5
use Magento\Catalog\Api\Data\ProductInterface;
6
use Magento\Catalog\Api\Data\ProductWebsiteLinkInterface;
7
use Magento\Catalog\Api\Data\ProductWebsiteLinkInterfaceFactory;
8
use Magento\Catalog\Api\ProductRepositoryInterface;
9
use Magento\Catalog\Api\ProductWebsiteLinkRepositoryInterface;
10
use Magento\Catalog\Model\Product;
11
use Magento\Catalog\Model\Product\Attribute\Source\Status;
12
use Magento\Catalog\Model\Product\Visibility;
13
use Magento\CatalogInventory\Api\Data\StockItemInterface;
14
use Magento\CatalogInventory\Api\StockItemRepositoryInterface;
15
use Magento\Framework\ObjectManagerInterface;
16
use Magento\Indexer\Model\IndexerFactory;
17
18
/**
19
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
20
 */
21
class ProductBuilder
22
{
23
    /**
24
     * @var ProductInterface
25
     */
26
    protected $product;
27
    /**
28
     * @var ProductRepositoryInterface
29
     */
30
    private $productRepository;
31
    /**
32
     * @var mixed[][]
33
     */
34
    private $storeSpecificValues = [];
35
    /**
36
     * @var int[]
37
     */
38
    private $websiteIds = [];
39
    /**
40
     * @var ProductWebsiteLinkRepositoryInterface
41
     */
42
    private $websiteLinkRepository;
43
    /**
44
     * @var StockItemRepositoryInterface
45
     */
46
    private $stockItemRepository;
47
    /**
48
     * @var ProductWebsiteLinkInterfaceFactory
49
     */
50
    private $websiteLinkFactory;
51
    /**
52
     * @var IndexerFactory
53
     */
54
    private $indexerFactory;
55
56
    public function __construct(
57
        ProductRepositoryInterface $productRepository,
58
        StockItemRepositoryInterface $stockItemRepository,
59
        ProductWebsiteLinkRepositoryInterface $websiteLinkRepository,
60
        ProductWebsiteLinkInterfaceFactory $websiteLinkFactory,
61
        IndexerFactory $indexerFactory,
62
        ProductInterface $product,
63
        array $websiteIds,
64
        array $storeSpecificValues
65
    ) {
66
        $this->productRepository = $productRepository;
67
        $this->websiteLinkRepository = $websiteLinkRepository;
68
        $this->stockItemRepository = $stockItemRepository;
69
        $this->websiteLinkFactory = $websiteLinkFactory;
70
        $this->indexerFactory = $indexerFactory;
71
        $this->product = $product;
72
        $this->websiteIds = $websiteIds;
73
        $this->storeSpecificValues = $storeSpecificValues;
74
    }
75
76
    public function __clone()
77
    {
78
        $this->product = clone $this->product;
79
    }
80
81
    public static function aSimpleProduct(ObjectManagerInterface $objectManager = null) : ProductBuilder
82
    {
83
        if ($objectManager === null) {
84
            $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
0 ignored issues
show
Bug introduced by
The type Magento\TestFramework\Helper\Bootstrap was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
85
        }
86
        /** @var ProductInterface $product */
87
        $product = $objectManager->create(ProductInterface::class);
88
89
        $product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE)
90
            ->setAttributeSetId(4)
91
            ->setName('Simple Product')
92
            ->setPrice(10)
93
            ->setVisibility(Visibility::VISIBILITY_BOTH)
94
            ->setStatus(Status::STATUS_ENABLED);
95
        $product->addData([
96
            'tax_class_id' => 1,
97
            'description' => 'Description',
98
        ]);
99
        /** @var StockItemInterface $stockItem */
100
        $stockItem = $objectManager->create(StockItemInterface::class);
101
        $stockItem->setManageStock(true)
102
            ->setQty(100)
103
            ->setIsQtyDecimal(false)
104
            ->setIsInStock(true);
105
        $product->setExtensionAttributes(
106
            $product->getExtensionAttributes()->setStockItem($stockItem)
107
        );
108
109
        return new static(
110
            $objectManager->create(ProductRepositoryInterface::class),
111
            $objectManager->create(StockItemRepositoryInterface::class),
112
            $objectManager->create(ProductWebsiteLinkRepositoryInterface::class),
113
            $objectManager->create(ProductWebsiteLinkInterfaceFactory::class),
114
            $objectManager->create(IndexerFactory::class),
115
            $product,
116
            [1],
117
            []
118
        );
119
    }
120
121
    public function withData(array $data) : ProductBuilder
122
    {
123
        $builder = clone $this;
124
125
        $builder->product->addData($data);
126
127
        return $builder;
128
    }
129
130
    public function withSku(string $sku) : ProductBuilder
131
    {
132
        $builder = clone $this;
133
        $builder->product->setSku($sku);
134
        return $builder;
135
    }
136
137
    public function withName(string $name, $storeId = null) : ProductBuilder
138
    {
139
        $builder = clone $this;
140
        if ($storeId) {
141
            $builder->storeSpecificValues[$storeId][ProductInterface::NAME] = $name;
142
        } else {
143
            $builder->product->setName($name);
144
        }
145
        return $builder;
146
    }
147
148
    /**
149
     * @param int $status
150
     * @param int|null $storeId Pass store ID to set value for specific store.
151
     *                          Attention: Status is configured per website, will affect all stores of the same website
152
     * @return ProductBuilder
153
     */
154
    public function withStatus(int $status, $storeId = null) : ProductBuilder
155
    {
156
        $builder = clone $this;
157
        if ($storeId) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $storeId of type integer|null is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
158
            $builder->storeSpecificValues[$storeId][ProductInterface::STATUS] = $status;
159
        } else {
160
            $builder->product->setStatus($status);
161
        }
162
        return $builder;
163
    }
164
165
    public function withVisibility(int $visibility, $storeId = null) : ProductBuilder
166
    {
167
        $builder = clone $this;
168
        if ($storeId) {
169
            $builder->storeSpecificValues[$storeId][ProductInterface::VISIBILITY] = $visibility;
170
        } else {
171
            $builder->product->setVisibility($visibility);
172
        }
173
        return $builder;
174
    }
175
176
    public function withWebsiteIds(array $websiteIds) : ProductBuilder
177
    {
178
        $builder = clone $this;
179
        $builder->websiteIds = $websiteIds;
180
        return $builder;
181
    }
182
183
    public function withPrice(float $price) : ProductBuilder
184
    {
185
        $builder = clone $this;
186
        $builder->product->setPrice($price);
187
        return $builder;
188
    }
189
190
    public function withTaxClassId($taxClassId) : ProductBuilder
191
    {
192
        $builder = clone $this;
193
        $builder->product->setData('tax_class_id', $taxClassId);
194
        return $builder;
195
    }
196
197
    public function withIsInStock(bool $inStock) : ProductBuilder
198
    {
199
        $builder = clone $this;
200
        $builder->product->getExtensionAttributes()->getStockItem()->setIsInStock($inStock);
201
        return $builder;
202
    }
203
204
    public function withStockQty($qty) : ProductBuilder
205
    {
206
        $builder = clone $this;
207
        $builder->product->getExtensionAttributes()->getStockItem()->setQty($qty);
208
        return $builder;
209
    }
210
211
    public function withWeight($weight) : ProductBuilder
212
    {
213
        $builder = clone $this;
214
        $builder->product->setWeight($weight);
215
        return $builder;
216
    }
217
218
    public function withCustomAttributes(array $values, $storeId = null) : ProductBuilder
219
    {
220
        $builder = clone $this;
221
        foreach ($values as $code => $value) {
222
            if ($storeId) {
223
                $builder->storeSpecificValues[$storeId][$code] = $value;
224
            } else {
225
                $builder->product->setCustomAttribute($code, $value);
226
            }
227
        }
228
        return $builder;
229
    }
230
231
    public function build() : ProductInterface
232
    {
233
        FulltextIndex::ensureTablesAreCreated();
234
        $builder = clone $this;
235
        if (!$builder->product->getSku()) {
236
            $builder->product->setSku(sha1(uniqid('', true)));
237
        }
238
        $builder->product->setCustomAttribute('url_key', $builder->product->getSku());
239
        $product = $builder->productRepository->save($builder->product);
240
        foreach ($builder->websiteIds as $websiteId) {
241
            /** @var ProductWebsiteLinkInterface $websiteLink */
242
            $websiteLink = $builder->websiteLinkFactory->create();
243
            $websiteLink->setWebsiteId($websiteId)->setSku($product->getSku());
244
            $builder->websiteLinkRepository->save($websiteLink);
245
        }
246
        foreach ($builder->storeSpecificValues as $storeId => $values) {
247
            /** @var Product $storeProduct */
248
            $storeProduct = clone $product;
249
            $storeProduct->setStoreId($storeId);
250
            $storeProduct->addData($values);
251
            $storeProduct->save();
0 ignored issues
show
Deprecated Code introduced by
The function Magento\Framework\Model\AbstractModel::save() has been deprecated: 100.1.0 because entities must not be responsible for their own persistence. Service contracts should persist entities. Use resource model "save" to implement service contract persistence operations. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

251
            /** @scrutinizer ignore-deprecated */ $storeProduct->save();

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
252
        }
253
        $this->indexerFactory->create()->load('cataloginventory_stock')->reindexRow($product->getId());
254
        return $product;
255
    }
256
}
257