Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
VariationHandler.php
Go to the documentation of this file.
1 <?php
8 
11 
19 {
25 
30 
35 
39  protected $entityFactory;
40 
44  protected $productFactory;
45 
49  private $attributes;
50 
56 
65  public function __construct(
67  \Magento\Eav\Model\Entity\Attribute\SetFactory $attributeSetFactory,
68  \Magento\Eav\Model\EntityFactory $entityFactory,
69  \Magento\Catalog\Model\ProductFactory $productFactory,
70  \Magento\CatalogInventory\Api\StockConfigurationInterface $stockConfiguration,
71  \Magento\Catalog\Model\Product\Gallery\Processor $mediaGalleryProcessor
72  ) {
73  $this->configurableProduct = $configurableProduct;
74  $this->attributeSetFactory = $attributeSetFactory;
75  $this->entityFactory = $entityFactory;
76  $this->productFactory = $productFactory;
77  $this->stockConfiguration = $stockConfiguration;
78  $this->mediaGalleryProcessor = $mediaGalleryProcessor;
79  }
80 
89  public function generateSimpleProducts($parentProduct, $productsData)
90  {
91  $generatedProductIds = [];
92  $this->attributes = null;
94  foreach ($productsData as $simpleProductData) {
95  $newSimpleProduct = $this->productFactory->create();
96  if (isset($simpleProductData['configurable_attribute'])) {
97  $configurableAttribute = json_decode($simpleProductData['configurable_attribute'], true);
98  unset($simpleProductData['configurable_attribute']);
99  } else {
100  throw new LocalizedException(
101  __('Contribution must have attributes specified. Enter attributes and try again.')
102  );
103  }
104 
105  $this->fillSimpleProductData(
106  $newSimpleProduct,
107  $parentProduct,
108  array_merge($simpleProductData, $configurableAttribute)
109  );
110  $newSimpleProduct->save();
111 
112  $generatedProductIds[] = $newSimpleProduct->getId();
113  }
114  return $generatedProductIds;
115  }
116 
125  {
126  $this->prepareAttributeSet($product);
127  }
128 
136  public function prepareAttributeSet(\Magento\Catalog\Model\Product $product)
137  {
138  $attributes = $this->configurableProduct->getUsedProductAttributes($product);
139  $attributeSetId = $product->getNewVariationsAttributeSetId();
141  $attributeSet = $this->attributeSetFactory->create()->load($attributeSetId);
142  $attributeSet->addSetInfo(
143  $this->entityFactory->create()->setType(\Magento\Catalog\Model\Product::ENTITY)->getTypeId(),
144  $attributes
145  );
146  foreach ($attributes as $attribute) {
147  /* @var $attribute \Magento\Catalog\Model\Entity\Attribute */
148  if (!$attribute->isInSet($attributeSetId)) {
149  $attribute->setAttributeSetId(
151  )->setAttributeGroupId(
152  $attributeSet->getDefaultGroupId($attributeSetId)
153  )->save();
154  }
155  }
156  }
157 
169  protected function fillSimpleProductData(
170  \Magento\Catalog\Model\Product $product,
171  \Magento\Catalog\Model\Product $parentProduct,
172  $postData
173  ) {
174  $typeId = isset($postData['weight']) && !empty($postData['weight'])
175  ? ProductType::TYPE_SIMPLE
176  : ProductType::TYPE_VIRTUAL;
177 
178  $product->setStoreId(
180  )->setTypeId(
181  $typeId
182  )->setAttributeSetId(
183  $parentProduct->getNewVariationsAttributeSetId()
184  );
185 
186  if ($this->attributes === null) {
187  $this->attributes = $product->getTypeInstance()->getSetAttributes($product);
188  }
189  foreach ($this->attributes as $attribute) {
190  if ($attribute->getIsUnique() ||
191  $attribute->getAttributeCode() == 'url_key' ||
192  $attribute->getFrontend()->getInputType() == 'gallery' ||
193  $attribute->getFrontend()->getInputType() == 'media_image' ||
194  !$attribute->getIsVisible()
195  ) {
196  continue;
197  }
198 
199  $product->setData($attribute->getAttributeCode(), $parentProduct->getData($attribute->getAttributeCode()));
200  }
201 
202  $keysFilter = ['item_id', 'product_id', 'stock_id', 'type_id', 'website_id'];
203  $postData['stock_data'] = array_diff_key((array)$parentProduct->getStockData(), array_flip($keysFilter));
204  if (!isset($postData['stock_data']['is_in_stock'])) {
205  $stockStatus = $parentProduct->getQuantityAndStockStatus();
206  $postData['stock_data']['is_in_stock'] = $stockStatus['is_in_stock'];
207  }
208  $postData = $this->processMediaGallery($product, $postData);
209  $postData['status'] = isset($postData['status'])
210  ? $postData['status']
211  : \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED;
212  $product->addData(
213  $postData
214  )->setWebsiteIds(
215  $parentProduct->getWebsiteIds()
216  )->setVisibility(
217  \Magento\Catalog\Model\Product\Visibility::VISIBILITY_NOT_VISIBLE
218  );
219  }
220 
230  {
231  $imagesForCopy = [];
232  foreach ($productsData as $variationId => $simpleProductData) {
233  if (!isset($simpleProductData['media_gallery']['images'])) {
234  continue;
235  }
236 
237  foreach ($simpleProductData['media_gallery']['images'] as $imageId => $image) {
238  $image['variation_id'] = $variationId;
239  if (isset($imagesForCopy[$imageId][0])) {
240  // skip duplicate image for first product
241  unset($imagesForCopy[$imageId][0]);
242  }
243  $imagesForCopy[$imageId][] = $image;
244  }
245  }
246  foreach ($imagesForCopy as $imageId => $variationImages) {
247  foreach ($variationImages as $image) {
248  $file = $image['file'];
249  $variationId = $image['variation_id'];
250  $newFile = $this->mediaGalleryProcessor->duplicateImageFromTmp($file);
251  $productsData[$variationId]['media_gallery']['images'][$imageId]['file'] = $newFile;
252  foreach ($this->mediaGalleryProcessor->getMediaAttributeCodes() as $attribute) {
253  if (isset($productsData[$variationId][$attribute])
254  && $productsData[$variationId][$attribute] == $file
255  ) {
256  $productsData[$variationId][$attribute] = $newFile;
257  }
258  }
259  }
260  }
261  return $productsData;
262  }
263 
271  {
272  if (!empty($productData['image'])) {
273  $image = $productData['image'];
274  if (!isset($productData['media_gallery']['images'])) {
275  $productData['media_gallery']['images'] = [];
276  }
277  if (false === array_search($image, array_column($productData['media_gallery']['images'], 'file'))) {
278  $productData['small_image'] = $productData['thumbnail'] = $image;
279  $productData['media_gallery']['images'][] = [
280  'position' => 1,
281  'file' => $image,
282  'disabled' => 0,
283  'label' => '',
284  ];
285  }
286  }
287  if ($product->getMediaGallery('images') && !empty($productData['media_gallery']['images'])) {
288  $gallery = array_map(
289  function ($image) {
290  $image['removed'] = 1;
291  return $image;
292  },
293  $product->getMediaGallery('images')
294  );
295  $gallery = array_merge($productData['media_gallery']['images'], $gallery);
296  $productData['media_gallery']['images'] = $gallery;
297  }
298  return $productData;
299  }
300 }
__construct(Type\Configurable $configurableProduct, \Magento\Eav\Model\Entity\Attribute\SetFactory $attributeSetFactory, \Magento\Eav\Model\EntityFactory $entityFactory, \Magento\Catalog\Model\ProductFactory $productFactory, \Magento\CatalogInventory\Api\StockConfigurationInterface $stockConfiguration, \Magento\Catalog\Model\Product\Gallery\Processor $mediaGalleryProcessor)
prepareAttributeSetToBeBaseForNewVariations(\Magento\Catalog\Model\Product $product)
$productsData
Definition: products.php:19
__()
Definition: __.php:13
fillSimpleProductData(\Magento\Catalog\Model\Product $product, \Magento\Catalog\Model\Product $parentProduct, $postData)
$productData