Skip to content

Commit b264180

Browse files
MAGETWO-85546: #12259: Save and Duplicated product not working #983
2 parents ba93925 + b3fd5e1 commit b264180

File tree

2 files changed

+111
-18
lines changed
  • app/code/Magento/Catalog/Model/Product
  • dev/tests/integration/testsuite/Magento/Catalog/Model/Product

2 files changed

+111
-18
lines changed

app/code/Magento/Catalog/Model/Product/Copier.php

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
11
<?php
22
/**
3-
* Catalog product copier. Creates product duplicate
4-
*
53
* Copyright © Magento, Inc. All rights reserved.
64
* See COPYING.txt for license details.
75
*/
86
namespace Magento\Catalog\Model\Product;
97

108
use Magento\Catalog\Api\Data\ProductInterface;
9+
use Magento\Catalog\Model\Product;
10+
use Magento\Framework\App\ObjectManager;
11+
use Magento\Framework\EntityManager\MetadataPool;
12+
use Magento\Catalog\Model\ProductFactory;
13+
use Magento\Catalog\Model\Product\Option\Repository as OptionRepository;
1114

15+
/**
16+
* Catalog product copier. Creates product duplicate
17+
*/
1218
class Copier
1319
{
1420
/**
15-
* @var Option\Repository
21+
* @var OptionRepository
1622
*/
1723
protected $optionRepository;
1824

@@ -22,22 +28,22 @@ class Copier
2228
protected $copyConstructor;
2329

2430
/**
25-
* @var \Magento\Catalog\Model\ProductFactory
31+
* @var ProductFactory
2632
*/
2733
protected $productFactory;
2834

2935
/**
30-
* @var \Magento\Framework\EntityManager\MetadataPool
36+
* @var MetadataPool
3137
*/
3238
protected $metadataPool;
3339

3440
/**
3541
* @param CopyConstructorInterface $copyConstructor
36-
* @param \Magento\Catalog\Model\ProductFactory $productFactory
42+
* @param ProductFactory $productFactory
3743
*/
3844
public function __construct(
3945
CopyConstructorInterface $copyConstructor,
40-
\Magento\Catalog\Model\ProductFactory $productFactory
46+
ProductFactory $productFactory
4147
) {
4248
$this->productFactory = $productFactory;
4349
$this->copyConstructor = $copyConstructor;
@@ -46,18 +52,16 @@ public function __construct(
4652
/**
4753
* Create product duplicate
4854
*
49-
* @param \Magento\Catalog\Model\Product $product
50-
* @return \Magento\Catalog\Model\Product
55+
* @param Product $product
56+
* @return Product
5157
*/
52-
public function copy(\Magento\Catalog\Model\Product $product)
58+
public function copy(Product $product)
5359
{
5460
$product->getWebsiteIds();
5561
$product->getCategoryIds();
5662

57-
/** @var \Magento\Framework\EntityManager\EntityMetadataInterface $metadata */
5863
$metadata = $this->getMetadataPool()->getMetadata(ProductInterface::class);
5964

60-
/** @var \Magento\Catalog\Model\Product $duplicate */
6165
$duplicate = $this->productFactory->create();
6266
$productData = $product->getData();
6367
$productData = $this->removeStockItem($productData);
@@ -83,6 +87,7 @@ public function copy(\Magento\Catalog\Model\Product $product)
8387
$duplicate->save();
8488
$isDuplicateSaved = true;
8589
} catch (\Magento\Framework\Exception\AlreadyExistsException $e) {
90+
} catch (\Magento\UrlRewrite\Model\Exception\UrlAlreadyExistsException $e) {
8691
}
8792
} while (!$isDuplicateSaved);
8893
$this->getOptionRepository()->duplicate($product, $duplicate);
@@ -94,27 +99,25 @@ public function copy(\Magento\Catalog\Model\Product $product)
9499
}
95100

96101
/**
97-
* @return Option\Repository
102+
* @return OptionRepository
98103
* @deprecated 101.0.0
99104
*/
100105
private function getOptionRepository()
101106
{
102107
if (null === $this->optionRepository) {
103-
$this->optionRepository = \Magento\Framework\App\ObjectManager::getInstance()
104-
->get(\Magento\Catalog\Model\Product\Option\Repository::class);
108+
$this->optionRepository = ObjectManager::getInstance()->get(OptionRepository::class);
105109
}
106110
return $this->optionRepository;
107111
}
108112

109113
/**
110-
* @return \Magento\Framework\EntityManager\MetadataPool
114+
* @return MetadataPool
111115
* @deprecated 101.0.0
112116
*/
113117
private function getMetadataPool()
114118
{
115119
if (null === $this->metadataPool) {
116-
$this->metadataPool = \Magento\Framework\App\ObjectManager::getInstance()
117-
->get(\Magento\Framework\EntityManager\MetadataPool::class);
120+
$this->metadataPool = ObjectManager::getInstance()->get(MetadataPool::class);
118121
}
119122
return $this->metadataPool;
120123
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\Catalog\Model\Product;
8+
9+
use Magento\Catalog\Model\ProductRepository;
10+
11+
class CopierTest extends \PHPUnit\Framework\TestCase
12+
{
13+
/**
14+
* @var \Magento\Framework\ObjectManagerInterface
15+
*/
16+
private $objectManager;
17+
18+
/**
19+
* @var \Magento\Catalog\Model\Product\Copier
20+
*/
21+
private $copier;
22+
23+
/**
24+
* @var \Magento\Catalog\Model\ProductRepository
25+
*/
26+
private $productRepository;
27+
28+
/**
29+
* Tests multiple duplication of the same product.
30+
*
31+
* @magentoDataFixture Magento/Catalog/_files/product_simple.php
32+
* @magentoAppArea adminhtml
33+
* @magentoDbIsolation disabled
34+
* @magentoAppIsolation enabled
35+
*/
36+
public function testDoubleCopy()
37+
{
38+
$product = $this->productRepository->get('simple');
39+
40+
$product1 = $this->copier->copy($product);
41+
$this->assertEquals(
42+
'simple-1',
43+
$product1->getSku()
44+
);
45+
$this->assertEquals(
46+
'simple-product-1',
47+
$product1->getUrlKey()
48+
);
49+
50+
$product2 = $this->copier->copy($product);
51+
$this->assertEquals(
52+
'simple-2',
53+
$product2->getSku()
54+
);
55+
$this->assertEquals(
56+
'simple-product-2',
57+
$product2->getUrlKey()
58+
);
59+
}
60+
61+
/**
62+
* @inheritdoc
63+
*/
64+
protected function setUp()
65+
{
66+
parent::setUp();
67+
$this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
68+
$this->copier = $this->objectManager->get(Copier::class);
69+
$this->productRepository = $this->objectManager->get(ProductRepository::class);
70+
}
71+
72+
/**
73+
* @inheritdoc
74+
*/
75+
protected function tearDown()
76+
{
77+
$skus = [
78+
'simple-1',
79+
'simple-2'
80+
];
81+
foreach ($skus as $sku) {
82+
try {
83+
$product = $this->productRepository->get($sku, false, null, true);
84+
$this->productRepository->delete($product);
85+
} catch (NoSuchEntityException $e) {
86+
}
87+
}
88+
parent::tearDown();
89+
}
90+
}

0 commit comments

Comments
 (0)