66namespace Magento \Catalog \Model \Product ;
77
88use Magento \Catalog \Api \Data \ProductInterface ;
9+ use Magento \Catalog \Api \ProductRepositoryInterface ;
910use Magento \Catalog \Model \Attribute \ScopeOverriddenValue ;
1011use Magento \Catalog \Model \Product ;
1112use Magento \Catalog \Model \Product \Attribute \Source \Status ;
1213use Magento \Catalog \Model \Product \Option \Repository as OptionRepository ;
1314use Magento \Catalog \Model \ProductFactory ;
14- use Magento \Framework \ App \ ObjectManager ;
15+ use Magento \Catalog \ Model \ ResourceModel \ DuplicatedProductAttributesCopier ;
1516use Magento \Framework \EntityManager \MetadataPool ;
1617use Magento \Store \Model \Store ;
1718use Magento \UrlRewrite \Model \Exception \UrlAlreadyExistsException ;
@@ -50,25 +51,41 @@ class Copier
5051 */
5152 private $ scopeOverriddenValue ;
5253
54+ /**
55+ * @var ProductRepositoryInterface
56+ */
57+ private $ productRepository ;
58+
59+ /**
60+ * @var DuplicatedProductAttributesCopier
61+ */
62+ private $ attributeCopier ;
63+
5364 /**
5465 * @param CopyConstructorInterface $copyConstructor
5566 * @param ProductFactory $productFactory
5667 * @param ScopeOverriddenValue $scopeOverriddenValue
5768 * @param OptionRepository|null $optionRepository
5869 * @param MetadataPool|null $metadataPool
70+ * @param ProductRepositoryInterface $productRepository
71+ * @param DuplicatedProductAttributesCopier $attributeCopier
5972 */
6073 public function __construct (
6174 CopyConstructorInterface $ copyConstructor ,
6275 ProductFactory $ productFactory ,
6376 ScopeOverriddenValue $ scopeOverriddenValue ,
6477 OptionRepository $ optionRepository ,
65- MetadataPool $ metadataPool
78+ MetadataPool $ metadataPool ,
79+ ProductRepositoryInterface $ productRepository ,
80+ DuplicatedProductAttributesCopier $ attributeCopier
6681 ) {
6782 $ this ->productFactory = $ productFactory ;
6883 $ this ->copyConstructor = $ copyConstructor ;
6984 $ this ->scopeOverriddenValue = $ scopeOverriddenValue ;
7085 $ this ->optionRepository = $ optionRepository ;
7186 $ this ->metadataPool = $ metadataPool ;
87+ $ this ->productRepository = $ productRepository ;
88+ $ this ->attributeCopier = $ attributeCopier ;
7289 }
7390
7491 /**
@@ -79,11 +96,13 @@ public function __construct(
7996 */
8097 public function copy (Product $ product ): Product
8198 {
82- $ product ->getWebsiteIds ();
83- $ product ->getCategoryIds ();
84-
8599 $ metadata = $ this ->metadataPool ->getMetadata (ProductInterface::class);
86100
101+ /* Regardless in what scope the product was provided,
102+ for duplicating we want to clone product in Global scope first */
103+ if ((int )$ product ->getStoreId () !== Store::DEFAULT_STORE_ID ) {
104+ $ product = $ this ->productRepository ->getById ($ product ->getId (), true , Store::DEFAULT_STORE_ID );
105+ }
87106 /** @var Product $duplicate */
88107 $ duplicate = $ this ->productFactory ->create ();
89108 $ productData = $ product ->getData ();
@@ -102,6 +121,7 @@ public function copy(Product $product): Product
102121 $ duplicate ->setStoreId (Store::DEFAULT_STORE_ID );
103122 $ this ->copyConstructor ->build ($ product , $ duplicate );
104123 $ this ->setDefaultUrl ($ product , $ duplicate );
124+ $ this ->attributeCopier ->copyProductAttributes ($ product , $ duplicate );
105125 $ this ->setStoresUrl ($ product , $ duplicate );
106126 $ this ->optionRepository ->duplicate ($ product , $ duplicate );
107127
0 commit comments