Your IP : 127.0.0.1
<?php
declare(strict_types=1);
namespace Destoff\Custom\Rewrite\Product;
use Magento\Catalog\Model\Product\Copier as MageCopier;
use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Catalog\Model\Attribute\ScopeOverriddenValue;
use Magento\Catalog\Model\Product;
use Magento\Catalog\Model\Product\Attribute\Source\Status;
use Magento\Catalog\Model\Product\Option\Repository as OptionRepository;
use Magento\Catalog\Model\ProductFactory;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\EntityManager\MetadataPool;
use Magento\Store\Model\Store;
use Magento\UrlRewrite\Model\Exception\UrlAlreadyExistsException;
use Magento\Catalog\Model\Product\CopyConstructorInterface;
use Magento\Framework\App\RequestInterface;
use Magento\Catalog\Model\ProductRepository;
use Magento\Store\Model\StoreManagerInterface;
USE Magento\Catalog\Model\Product\Action;
use Magento\CatalogInventory\Api\StockRegistryInterface;
use Magento\CatalogInventory\Model\Indexer\Stock\Processor;
use Magento\CatalogInventory\Api\StockItemRepositoryInterface;
use Magento\CatalogInventory\Api\Data\StockItemInterface;
class Copier extends MageCopier
{
public function __construct(
CopyConstructorInterface $copyConstructor,
ProductFactory $productFactory,
ScopeOverriddenValue $scopeOverriddenValue,
OptionRepository $optionRepository,
MetadataPool $metadataPool,
RequestInterface $request,
ProductRepository $productRepo,
StoreManagerInterface $storeManager,
Action $productAction,
StockRegistryInterface $stockRegistry,
Processor $stockIndexerProcessor,
StockItemRepositoryInterface $stockItemRepository,
\Magento\Framework\Api\DataObjectHelper $dataObjectHelper
) {
$this->productFactory = $productFactory;
$this->copyConstructor = $copyConstructor;
$this->scopeOverriddenValue = $scopeOverriddenValue;
$this->optionRepository = $optionRepository;
$this->metadataPool = $metadataPool;
$this->request = $request;
$this->productRepo = $productRepo;
$this->storeManager = $storeManager;
$this->productAction = $productAction;
$this->stockRegistry = $stockRegistry;
$this->stockIndexerProcessor = $stockIndexerProcessor;
$this->stockItemRepository = $stockItemRepository;
$this->dataObjectHelper = $dataObjectHelper;
parent::__construct($copyConstructor, $productFactory, $scopeOverriddenValue, $optionRepository, $metadataPool);
}
public function copy(Product $product): Product
{
$data = $this->request->getParams();
$storeIds = array_keys($this->storeManager->getStores(true));
$productCopy = clone $product;
$product->getWebsiteIds();
$product->getCategoryIds();
$metadata = $this->metadataPool->getMetadata(ProductInterface::class);
/** @var Product $duplicate */
$duplicate = $this->productFactory->create();
$productData = $productCopy->getData();
$productCopy->setData('media_gallery', null);
// echo "<pre>";
// print_r($productCopy->getData('media_gallery'));die;
if(isset($productData['total_sale'])) {
$productData['total_sale'] = 0;
}
$productData = $this->removeStockItem($productData);
$duplicate->setData($productData);
$duplicate->setOptions([]);
$duplicate->setMediaGallery(null);
$duplicate->setIsDuplicate(true);
$duplicate->setOriginalLinkId($productCopy->getData($metadata->getLinkField()));
$duplicate->setStatus(Status::STATUS_DISABLED);
$duplicate->setCreatedAt(null);
$duplicate->setUpdatedAt(null);
$duplicate->setId(null);
$duplicate->setStoreId(Store::DEFAULT_STORE_ID);
$this->copyConstructor->build($productCopy, $duplicate);
$this->setDefaultUrl($productCopy, $duplicate);
$this->setStoresUrl($productCopy, $duplicate);
$this->optionRepository->duplicate($productCopy, $duplicate);
$duplicateProId = $duplicate->getId();
$inventoryData = [
'qty' => $data['product']['quantity_and_stock_status']['qty'] ?? null,
'is_qty_decimal' => $data['product']['quantity_and_stock_status']['is_in_stock'] ?? null,
'is_in_stock' => $data['product']['stock_data']['is_qty_decimal'] ?? 0
];
$stockItemDo = $this->stockRegistry->getStockItem($duplicateProId, 0);
$stockItemId = $stockItemDo->getId();
$this->dataObjectHelper->populateWithArray($stockItemDo, $inventoryData, StockItemInterface::class);
$stockItemDo->setItemId($stockItemId);
$this->stockItemRepository->save($stockItemDo);
// echo "<pre>";
// print_r($data);die;
// $this->productAction->updateAttributes(
// [$duplicateProId],
// [
// ['quantity_and_stock_status']['is_in_stock'] => $data['product']['quantity_and_stock_status']['qty'] ?? null,
// ['quantity_and_stock_status']['qty'] => $data['product']['quantity_and_stock_status']['is_in_stock'] ?? null,
// ['stock_data']['is_qty_decimal'] => $data['product']['stock_data']['is_qty_decimal'] ?? 0
// ],
// 0
// );
// $storeProduct = $this->productFactory->create()->load($duplicateProId);
// $storeProduct->setQuantityAndStockStatus([
// 'qty' => $data['product']['quantity_and_stock_status']['qty'] ?? null,
// 'is_in_stock' => $data['product']['quantity_and_stock_status']['is_in_stock'] ?? null
// ]);
// $storeProduct->setStockData(
// [
// 'is_qty_decimal' => $data['product']['stock_data']['is_qty_decimal'] ?? 0
// ]
// )->save();
if (isset($data['store']) && isset($data['id'])) {
$originalProductId = $data['id'];
foreach($storeIds as $storeId) {
if (empty($storeId) || ($originalProductId == $storeId) || $storeId === 0) {
continue;
}
$name = $this->productFactory->create()->getResource()->getAttributeRawValue($originalProductId, 'name', $storeId);
$description = $this->productFactory->create()->getResource()->getAttributeRawValue($originalProductId, 'description', $storeId);
$shortDescription = $this->productFactory->create()->getResource()->getAttributeRawValue($originalProductId, 'short_description', $storeId);
$metaKeyword = $this->productFactory->create()->getResource()->getAttributeRawValue($originalProductId, 'meta_keyword', $storeId);
$metaTitle = $this->productFactory->create()->getResource()->getAttributeRawValue($originalProductId, 'meta_title', $storeId);
$metaDescription = $this->productFactory->create()->getResource()->getAttributeRawValue($originalProductId, 'meta_description', $storeId);
$this->productAction->updateAttributes(
[$duplicateProId],
[
'name' => $name,
'description' => $description,
'short_description' => $shortDescription,
'meta_keyword' => $metaKeyword,
'meta_title' => $metaTitle,
'meta_description' => $metaDescription
],
$storeId
);
// $storeProduct = null;
// $storeProduct = $this->productFactory->create()->load($duplicateProId);
// $storeProduct->setStoreId($storeId);
// $storeProduct->setName($name);
// $storeProduct->setDescription($description);
// $storeProduct->setShortDescription($shortDescription);
// $storeProduct->setMetaKeyword($metaKeyword);
// $storeProduct->setMetaTitle($metaTitle);
// $storeProduct->setMetaDescription($metaDescription);
// $storeProduct->save();
}
}
$this->stockIndexerProcessor->reindexList([$duplicateProId]);
return $duplicate;
}
private function setDefaultUrl(Product $product, Product $duplicate) : void
{
$duplicate->setStoreId(Store::DEFAULT_STORE_ID);
$resource = $product->getResource();
$attribute = $resource->getAttribute('url_key');
$productId = $product->getId();
$urlKey = $resource->getAttributeRawValue($productId, 'url_key', Store::DEFAULT_STORE_ID);
do {
$urlKey = $this->modifyUrl($urlKey);
$duplicate->setUrlKey($urlKey);
} while (!$attribute->getEntity()->checkAttributeUniqueValue($attribute, $duplicate));
$duplicate->setData('url_path', null);
$duplicate->save();
}
private function setStoresUrl(Product $product, Product $duplicate) : void
{
$storeIds = $duplicate->getStoreIds();
// echo "sdf<pre>";
// print_r($storeIds);die;
$productId = $product->getId();
$productResource = $product->getResource();
$attribute = $productResource->getAttribute('url_key');
$duplicate->setData('save_rewrites_history', false);
foreach ($storeIds as $storeId) {
$useDefault = !$this->scopeOverriddenValue->containsValue(
ProductInterface::class,
$product,
'url_key',
$storeId
);
if ($useDefault) {
continue;
}
$duplicate->setStoreId($storeId);
$urlKey = $productResource->getAttributeRawValue($productId, 'url_key', $storeId);
$iteration = 0;
do {
if ($iteration === 10) {
throw new UrlAlreadyExistsException();
}
$urlKey = $this->modifyUrl($urlKey);
$duplicate->setUrlKey($urlKey);
$iteration++;
} while (!$attribute->getEntity()->checkAttributeUniqueValue($attribute, $duplicate));
$duplicate->setData('url_path', null);
$productResource->saveAttribute($duplicate, 'url_path');
$productResource->saveAttribute($duplicate, 'url_key');
}
$duplicate->setStoreId(Store::DEFAULT_STORE_ID);
}
private function modifyUrl(string $urlKey) : string
{
return preg_match('/(.*)-(\d+)$/', $urlKey, $matches)
? $matches[1] . '-' . ($matches[2] + 1)
: $urlKey . '-1';
}
private function removeStockItem(array $productData): array
{
if (isset($productData[ProductInterface::EXTENSION_ATTRIBUTES_KEY])) {
$extensionAttributes = $productData[ProductInterface::EXTENSION_ATTRIBUTES_KEY];
if (null !== $extensionAttributes->getStockItem()) {
$extensionAttributes->setData('stock_item', null);
}
}
return $productData;
}
}