Completed
Pull Request — master (#8)
by
unknown
05:28
created

ProductBuilder::withData()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 7
rs 9.4285
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
17
class ProductBuilder
18
{
19
    /**
20
     * @var ProductInterface
21
     */
22
    private $product;
23
    /**
24
     * @var ProductRepositoryInterface
25
     */
26
    private $productRepository;
27
    /**
28
     * @var mixed[][]
29
     */
30
    private $storeSpecificValues = [];
31
    /**
32
     * @var int[]
33
     */
34
    private $websiteIds = [];
35
    /**
36
     * @var ProductWebsiteLinkRepositoryInterface
37
     */
38
    private $websiteLinkRepository;
39
    /**
40
     * @var StockItemRepositoryInterface
41
     */
42
    private $stockItemRepository;
43
    /**
44
     * @var ProductWebsiteLinkInterfaceFactory
45
     */
46
    private $websiteLinkFactory;
47
48
    public function __construct(
49
        ProductRepositoryInterface $productRepository,
50
        StockItemRepositoryInterface $stockItemRepository,
51
        ProductWebsiteLinkRepositoryInterface $websiteLinkRepository,
52
        ProductWebsiteLinkInterfaceFactory $websiteLinkFactory,
53
        ProductInterface $product,
54
        array $websiteIds,
55
        array $storeSpecificValues
56
    ) {
57
        $this->productRepository = $productRepository;
58
        $this->websiteLinkRepository = $websiteLinkRepository;
59
        $this->stockItemRepository = $stockItemRepository;
60
        $this->websiteLinkFactory = $websiteLinkFactory;
61
        $this->product = $product;
62
        $this->websiteIds = $websiteIds;
63
        $this->storeSpecificValues = $storeSpecificValues;
64
    }
65
66
    public function __clone()
67
    {
68
        $this->product = clone $this->product;
69
    }
70
71
    public static function aSimpleProduct(ObjectManagerInterface $objectManager = null) : ProductBuilder
72
    {
73
        if ($objectManager === null) {
74
            $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...
75
        }
76
        /** @var ProductInterface $product */
77
        $product = $objectManager->create(ProductInterface::class);
78
79
        $product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE)
80
            ->setAttributeSetId(4)
81
            ->setName('Simple Product')
82
            ->setPrice(10)
83
            ->setVisibility(Visibility::VISIBILITY_BOTH)
84
            ->setStatus(Status::STATUS_ENABLED);
85
        $product->addData([
86
            'tax_class_id' => 1,
87
            'description' => 'Description',
88
        ]);
89
        /** @var StockItemInterface $stockItem */
90
        $stockItem = $objectManager->create(StockItemInterface::class);
91
        $stockItem->setManageStock(true)
92
            ->setQty(100)
93
            ->setIsQtyDecimal(false)
94
            ->setIsInStock(true);
95
        $product->setExtensionAttributes(
96
            $product->getExtensionAttributes()->setStockItem($stockItem)
97
        );
98
99
        return new self(
100
            $objectManager->create(ProductRepositoryInterface::class),
101
            $objectManager->create(StockItemRepositoryInterface::class),
102
            $objectManager->create(ProductWebsiteLinkRepositoryInterface::class),
103
            $objectManager->create(ProductWebsiteLinkInterfaceFactory::class),
104
            $product,
105
            [1],
106
            []
107
        );
108
    }
109
110
    public function withData(array $data) : ProductBuilder
111
    {
112
        $builder = clone $this;
113
114
        $builder->product->addData($data);
115
116
        return $builder;
117
    }
118
119
    public function withSku(string $sku) : ProductBuilder
120
    {
121
        $builder = clone $this;
122
        $builder->product->setSku($sku);
123
        return $builder;
124
    }
125
126
    public function withName(string $name, $storeId = null) : ProductBuilder
127
    {
128
        $builder = clone $this;
129
        if ($storeId) {
130
            $builder->storeSpecificValues[$storeId][ProductInterface::NAME] = $name;
131
        } else {
132
            $builder->product->setName($name);
133
        }
134
        return $builder;
135
    }
136
137
    /**
138
     * @param int $status
139
     * @param int|null $storeId Pass store ID to set value for specific store.
140
     *                          Attention: Status is configured per website, will affect all stores of the same website
141
     * @return ProductBuilder
142
     */
143
    public function withStatus(int $status, $storeId = null) : ProductBuilder
144
    {
145
        $builder = clone $this;
146
        if ($storeId) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $storeId of type null|integer 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...
147
            $builder->storeSpecificValues[$storeId][ProductInterface::STATUS] = $status;
148
        } else {
149
            $builder->product->setStatus($status);
150
        }
151
        return $builder;
152
    }
153
154
    public function withVisibility(int $visibility, $storeId = null) : ProductBuilder
155
    {
156
        $builder = clone $this;
157
        if ($storeId) {
158
            $builder->storeSpecificValues[$storeId][ProductInterface::VISIBILITY] = $visibility;
159
        } else {
160
            $builder->product->setVisibility($visibility);
161
        }
162
        return $builder;
163
    }
164
165
    public function withWebsiteIds(array $websiteIds) : ProductBuilder
166
    {
167
        $builder = clone $this;
168
        $builder->websiteIds = $websiteIds;
169
        return $builder;
170
    }
171
172
    public function withPrice(float $price) : ProductBuilder
173
    {
174
        $builder = clone $this;
175
        $builder->product->setPrice($price);
176
        return $builder;
177
    }
178
179
    public function withTaxClassId($taxClassId) : ProductBuilder
180
    {
181
        $builder = clone $this;
182
        $builder->product->setData('tax_class_id', $taxClassId);
183
        return $builder;
184
    }
185
186
    public function withIsInStock(bool $inStock) : ProductBuilder
187
    {
188
        $builder = clone $this;
189
        $builder->product->getExtensionAttributes()->getStockItem()->setIsInStock($inStock);
190
        return $builder;
191
    }
192
193
    public function withStockQty($qty) : ProductBuilder
194
    {
195
        $builder = clone $this;
196
        $builder->product->getExtensionAttributes()->getStockItem()->setQty($qty);
197
        return $builder;
198
    }
199
200
    public function withCustomAttributes(array $values, $storeId = null) : ProductBuilder
201
    {
202
        $builder = clone $this;
203
        foreach ($values as $code => $value) {
204
            if ($storeId) {
205
                $builder->storeSpecificValues[$storeId][$code] = $value;
206
            } else {
207
                $builder->product->setCustomAttribute($code, $value);
208
            }
209
        }
210
        return $builder;
211
    }
212
213
    public function build() : ProductInterface
214
    {
215
        FulltextIndex::ensureTablesAreCreated();
216
        $builder = clone $this;
217
        if (!$builder->product->getSku()) {
218
            $builder->product->setSku(sha1(uniqid('', true)));
219
        }
220
        $builder->product->addData([
221
            'url_key' => $builder->product->getSku()
222
        ]);
223
        $product = $builder->productRepository->save($builder->product);
224
        foreach ($builder->websiteIds as $websiteId) {
225
            /** @var ProductWebsiteLinkInterface $websiteLink */
226
            $websiteLink = $builder->websiteLinkFactory->create();
227
            $websiteLink->setWebsiteId($websiteId)->setSku($product->getSku());
228
            $builder->websiteLinkRepository->save($websiteLink);
229
        }
230
        foreach ($builder->storeSpecificValues as $storeId => $values) {
231
            /** @var Product $storeProduct */
232
            $storeProduct = clone $product;
233
            $storeProduct->setStoreId($storeId);
234
            $storeProduct->addData($values);
235
            $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

235
            /** @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...
236
        }
237
        return $product;
238
    }
239
}
240