Skip to content

Commit 1e055fb

Browse files
author
Maksym Aposov
committed
MAGETWO-36369: [GitHub] Unable to save product per website wise #1245
1 parent 82109a5 commit 1e055fb

File tree

3 files changed

+115
-11
lines changed

3 files changed

+115
-11
lines changed

app/code/Magento/CatalogUrlRewrite/Model/ProductUrlPathGenerator.php

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
*/
66
namespace Magento\CatalogUrlRewrite\Model;
77

8+
use Magento\Store\Model\Store;
9+
810
class ProductUrlPathGenerator
911
{
1012
const XML_PATH_PRODUCT_URL_SUFFIX = 'catalog/seo/product_url_suffix';
@@ -25,19 +27,25 @@ class ProductUrlPathGenerator
2527
/** @var \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator */
2628
protected $categoryUrlPathGenerator;
2729

30+
/** @var \Magento\Catalog\Api\ProductRepositoryInterface */
31+
protected $productRepository;
32+
2833
/**
2934
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
3035
* @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
3136
* @param CategoryUrlPathGenerator $categoryUrlPathGenerator
37+
* @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
3238
*/
3339
public function __construct(
3440
\Magento\Store\Model\StoreManagerInterface $storeManager,
3541
\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
36-
\Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator $categoryUrlPathGenerator
42+
\Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator $categoryUrlPathGenerator,
43+
\Magento\Catalog\Api\ProductRepositoryInterface $productRepository
3744
) {
3845
$this->storeManager = $storeManager;
3946
$this->scopeConfig = $scopeConfig;
4047
$this->categoryUrlPathGenerator = $categoryUrlPathGenerator;
48+
$this->productRepository = $productRepository;
4149
}
4250

4351
/**
@@ -52,12 +60,34 @@ public function getUrlPath($product, $category = null)
5260
{
5361
$path = $product->getData('url_path');
5462
if ($path === null) {
55-
$path = $this->generateUrlKey($product);
63+
$path = $product->getUrlKey() === false
64+
? $this->_prepareProductDefaultUrlKey($product)
65+
: $this->_prepareProductUrlKey($product);
5666
}
57-
return $category === null ? $path
67+
return $category === null
68+
? $path
5869
: $this->categoryUrlPathGenerator->getUrlPath($category) . '/' . $path;
5970
}
6071

72+
/**
73+
* Prepare URL Key with stored product data (fallback for "Use Default Value" logic)
74+
*
75+
* @param \Magento\Catalog\Model\Product $product
76+
* @return mixed|null|string
77+
*/
78+
protected function _prepareProductDefaultUrlKey(\Magento\Catalog\Model\Product $product)
79+
{
80+
$storedProduct = $this->productRepository->getById($product->getId(), false, Store::DEFAULT_STORE_ID);
81+
$storedUrlKey = $storedProduct->getUrlKey();
82+
$result = null;
83+
if ($storedUrlKey !== false) {
84+
$result = $storedUrlKey;
85+
} else {
86+
$result = $product->formatUrlKey($storedProduct->getName());
87+
}
88+
return $result;
89+
}
90+
6191
/**
6292
* Retrieve Product Url path with suffix
6393
*
@@ -91,6 +121,20 @@ public function getCanonicalUrlPath($product, $category = null)
91121
* @return string
92122
*/
93123
public function generateUrlKey($product)
124+
{
125+
if ($product->getUrlKey() === false) {
126+
return false;
127+
}
128+
return $this->_prepareProductUrlKey($product);
129+
}
130+
131+
/**
132+
* Prepare url key for product
133+
*
134+
* @param \Magento\Catalog\Model\Product $product
135+
* @return string
136+
*/
137+
protected function _prepareProductUrlKey(\Magento\Catalog\Model\Product $product)
94138
{
95139
$urlKey = $product->getUrlKey();
96140
return $product->formatUrlKey($urlKey === '' || $urlKey === null ? $product->getName() : $urlKey);

app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/ProductUrlPathGeneratorTest.php

Lines changed: 67 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@
55
*/
66
namespace Magento\CatalogUrlRewrite\Test\Unit\Model;
77

8-
use \Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator;
9-
10-
use Magento\Store\Model\ScopeInterface;
8+
use Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator;
119
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
10+
use Magento\Store\Model\ScopeInterface;
1211

1312
class ProductUrlPathGeneratorTest extends \PHPUnit_Framework_TestCase
1413
{
@@ -27,13 +26,26 @@ class ProductUrlPathGeneratorTest extends \PHPUnit_Framework_TestCase
2726
/** @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject */
2827
protected $product;
2928

29+
/** @var \Magento\Catalog\Api\ProductRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject */
30+
protected $productRepository;
31+
3032
/** @var \Magento\Catalog\Model\Category|\PHPUnit_Framework_MockObject_MockObject */
3133
protected $category;
3234

3335
protected function setUp()
3436
{
3537
$this->category = $this->getMock('Magento\Catalog\Model\Category', [], [], '', false);
36-
$productMethods = ['__wakeup', 'getData', 'getUrlKey', 'getName', 'formatUrlKey', 'getId'];
38+
$productMethods = [
39+
'__wakeup',
40+
'getData',
41+
'getUrlKey',
42+
'getName',
43+
'formatUrlKey',
44+
'getId',
45+
'load',
46+
'setStoreId',
47+
];
48+
3749
$this->product = $this->getMock('Magento\Catalog\Model\Product', $productMethods, [], '', false);
3850
$this->storeManager = $this->getMock('Magento\Store\Model\StoreManagerInterface');
3951
$this->scopeConfig = $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface');
@@ -44,13 +56,16 @@ protected function setUp()
4456
'',
4557
false
4658
);
59+
$this->productRepository = $this->getMock('Magento\Catalog\Api\ProductRepositoryInterface');
60+
$this->productRepository->expects($this->any())->method('getById')->willReturn($this->product);
4761

4862
$this->productUrlPathGenerator = (new ObjectManager($this))->getObject(
4963
'Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator',
5064
[
5165
'storeManager' => $this->storeManager,
5266
'scopeConfig' => $this->scopeConfig,
53-
'categoryUrlPathGenerator' => $this->categoryUrlPathGenerator
67+
'categoryUrlPathGenerator' => $this->categoryUrlPathGenerator,
68+
'productRepository' => $this->productRepository,
5469
]
5570
);
5671
}
@@ -64,6 +79,7 @@ public function getUrlPathDataProvider()
6479
'path based on url key' => ['url-key', null, 'url-key'],
6580
'path based on product name 1' => ['', 'product-name', 'product-name'],
6681
'path based on product name 2' => [null, 'product-name', 'product-name'],
82+
'path based on product name 3' => [false, 'product-name', 'product-name']
6783
];
6884
}
6985

@@ -77,13 +93,34 @@ public function testGenerateUrlPath($urlKey, $productName, $result)
7793
{
7894
$this->product->expects($this->once())->method('getData')->with('url_path')
7995
->will($this->returnValue(null));
80-
$this->product->expects($this->once())->method('getUrlKey')->will($this->returnValue($urlKey));
96+
$this->product->expects($this->any())->method('getUrlKey')->will($this->returnValue($urlKey));
8197
$this->product->expects($this->any())->method('getName')->will($this->returnValue($productName));
8298
$this->product->expects($this->once())->method('formatUrlKey')->will($this->returnArgument(0));
8399

84100
$this->assertEquals($result, $this->productUrlPathGenerator->getUrlPath($this->product, null));
85101
}
86102

103+
/**
104+
* @param $productUrlKey
105+
* @param $expectedUrlKey
106+
*
107+
* @dataProvider generateUrlKeyDataProvider
108+
*/
109+
public function testGenerateUrlKey($productUrlKey, $expectedUrlKey)
110+
{
111+
$this->product->expects($this->any())->method('getUrlKey')->will($this->returnValue($productUrlKey));
112+
$this->product->expects($this->any())->method('formatUrlKey')->will($this->returnValue($productUrlKey));
113+
$this->assertEquals($expectedUrlKey, $this->productUrlPathGenerator->generateUrlKey($this->product));
114+
}
115+
116+
public function generateUrlKeyDataProvider()
117+
{
118+
return [
119+
'URL Key use default' => [false, false],
120+
'URL Key empty' => ['product-url', 'product-url'],
121+
];
122+
}
123+
87124
public function testGetUrlPath()
88125
{
89126
$this->product->expects($this->once())->method('getData')->with('url_path')
@@ -93,6 +130,29 @@ public function testGetUrlPath()
93130
$this->assertEquals('url-path', $this->productUrlPathGenerator->getUrlPath($this->product, null));
94131
}
95132

133+
/**
134+
*
135+
* @dataProvider getUrlPathDefaultUrlKeyDataProvider
136+
*/
137+
public function testGetUrlPathDefaultUrlKey($storedUrlKey, $productName, $expectedUrlKey)
138+
{
139+
$this->product->expects($this->once())->method('getData')->with('url_path')
140+
->will($this->returnValue(null));
141+
$this->product->expects($this->any())->method('getUrlKey')->willReturnOnConsecutiveCalls(false, $storedUrlKey);
142+
$this->product->expects($this->any())->method('getName')->will($this->returnValue($productName));
143+
$this->product->expects($this->any())->method('formatUrlKey')->will($this->returnArgument(0));
144+
$this->assertEquals($expectedUrlKey, $this->productUrlPathGenerator->getUrlPath($this->product, null));
145+
}
146+
147+
public function getUrlPathDefaultUrlKeyDataProvider()
148+
{
149+
return [
150+
['default-store-view-url-key', null, 'default-store-view-url-key'],
151+
[false, 'default-store-view-product-name', 'default-store-view-product-name']
152+
];
153+
154+
}
155+
96156
public function testGetUrlPathWithCategory()
97157
{
98158
$this->product->expects($this->once())->method('getData')->with('url_path')
@@ -124,7 +184,7 @@ public function testGetUrlPathWithSuffix()
124184
);
125185
}
126186

127-
public function testGetUrlPathWithSuffixAndCategoryAnsStore()
187+
public function testGetUrlPathWithSuffixAndCategoryAndStore()
128188
{
129189
$storeId = 1;
130190
$this->product->expects($this->once())->method('getData')->with('url_path')

app/code/Magento/Eav/Model/Entity/AbstractEntity.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
use Magento\Eav\Model\Entity\Attribute\Frontend\AbstractFrontend;
1414
use Magento\Eav\Model\Entity\Attribute\Source\AbstractSource;
1515
use Magento\Framework\App\Config\Element;
16-
use Magento\Framework\Model\AbstractModel;
1716
use Magento\Framework\Exception\LocalizedException;
17+
use Magento\Framework\Model\AbstractModel;
1818
use Magento\Framework\Model\Resource\Db\ObjectRelationProcessor;
1919
use Magento\Framework\Model\Resource\Db\TransactionManagerInterface;
2020

0 commit comments

Comments
 (0)