Your IP : 127.0.0.1


Current Path : /home/dev2.destoffenstraat.com/app/code/Destoff/Custom/Rewrite/Product/
Upload File :
Current File : /home/dev2.destoffenstraat.com/app/code/Destoff/Custom/Rewrite/Product/Copier.php

<?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;
    }

}