Skip to content

Commit ae9cd83

Browse files
authored
Merge pull request #3903 from magento-tango/TANGO-PR-2.2-03
TANGO-PR-2.2-03
2 parents eef6935 + 1c0403a commit ae9cd83

File tree

8 files changed

+258
-45
lines changed

8 files changed

+258
-45
lines changed

app/code/Magento/Cms/Model/Wysiwyg/Images/Storage.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,8 @@ public function getDirsCollection($path)
270270
$collection = $this->getCollection($path)
271271
->setCollectDirs(true)
272272
->setCollectFiles(false)
273-
->setCollectRecursively(false);
273+
->setCollectRecursively(false)
274+
->setOrder('basename', \Magento\Framework\Data\Collection\Filesystem::SORT_ORDER_ASC);
274275

275276
$conditions = $this->getConditionsForExcludeDirs();
276277

app/code/Magento/Cms/Test/Unit/Model/Wysiwyg/Images/StorageTest.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,10 @@ protected function generalTestGetDirsCollection($path, $collectionArray = [], $e
414414
->method('setCollectRecursively')
415415
->with(false)
416416
->willReturnSelf();
417+
$storageCollectionMock->expects($this->once())
418+
->method('setOrder')
419+
->with('basename', \Magento\Framework\Data\Collection\Filesystem::SORT_ORDER_ASC)
420+
->willReturnSelf();
417421
$storageCollectionMock->expects($this->once())
418422
->method('getIterator')
419423
->willReturn(new \ArrayIterator($collectionArray));

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1695,14 +1695,16 @@ public function saveAttribute(DataObject $object, $attributeCode)
16951695
$connection->beginTransaction();
16961696

16971697
try {
1698-
$select = $connection->select()->from($table, 'value_id')->where($where);
1699-
$origValueId = $connection->fetchOne($select);
1698+
$select = $connection->select()->from($table, ['value_id', 'value'])->where($where);
1699+
$origRow = $connection->fetchRow($select);
1700+
$origValueId = $origRow['value_id'] ?? false;
1701+
$origValue = $origRow['value'] ?? null;
17001702

17011703
if ($origValueId === false && $newValue !== null) {
17021704
$this->_insertAttribute($object, $attribute, $newValue);
17031705
} elseif ($origValueId !== false && $newValue !== null) {
17041706
$this->_updateAttribute($object, $attribute, $origValueId, $newValue);
1705-
} elseif ($origValueId !== false && $newValue === null) {
1707+
} elseif ($origValueId !== false && $newValue === null && $origValue !== null) {
17061708
$connection->delete($table, $where);
17071709
}
17081710
$this->_processAttributeValues();

app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php

Lines changed: 85 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
use Psr\Log\LoggerInterface;
1515
use Magento\UrlRewrite\Service\V1\Data\UrlRewrite as UrlRewriteData;
1616

17+
/**
18+
* DB storage implementation for url rewrites
19+
*/
1720
class DbStorage extends AbstractStorage
1821
{
1922
/**
@@ -37,15 +40,15 @@ class DbStorage extends AbstractStorage
3740
protected $resource;
3841

3942
/**
40-
* @var \Psr\Log\LoggerInterface
43+
* @var LoggerInterface
4144
*/
4245
private $logger;
4346

4447
/**
4548
* @param \Magento\UrlRewrite\Service\V1\Data\UrlRewriteFactory $urlRewriteFactory
4649
* @param DataObjectHelper $dataObjectHelper
4750
* @param \Magento\Framework\App\ResourceConnection $resource
48-
* @param \Psr\Log\LoggerInterface|null $logger
51+
* @param LoggerInterface|null $logger
4952
*/
5053
public function __construct(
5154
UrlRewriteFactory $urlRewriteFactory,
@@ -56,7 +59,7 @@ public function __construct(
5659
$this->connection = $resource->getConnection();
5760
$this->resource = $resource;
5861
$this->logger = $logger ?: \Magento\Framework\App\ObjectManager::getInstance()
59-
->get(\Psr\Log\LoggerInterface::class);
62+
->get(LoggerInterface::class);
6063

6164
parent::__construct($urlRewriteFactory, $dataObjectHelper);
6265
}
@@ -97,42 +100,18 @@ protected function doFindOneByData(array $data)
97100
$result = null;
98101

99102
$requestPath = $data[UrlRewrite::REQUEST_PATH];
100-
101-
$data[UrlRewrite::REQUEST_PATH] = [
103+
$decodedRequestPath = urldecode($requestPath);
104+
$data[UrlRewrite::REQUEST_PATH] = array_unique([
102105
rtrim($requestPath, '/'),
103106
rtrim($requestPath, '/') . '/',
104-
];
107+
rtrim($decodedRequestPath, '/'),
108+
rtrim($decodedRequestPath, '/') . '/',
109+
]);
105110

106111
$resultsFromDb = $this->connection->fetchAll($this->prepareSelect($data));
107-
108-
if (count($resultsFromDb) === 1) {
109-
$resultFromDb = current($resultsFromDb);
110-
$redirectTypes = [OptionProvider::TEMPORARY, OptionProvider::PERMANENT];
111-
112-
// If request path matches the DB value or it's redirect - we can return result from DB
113-
$canReturnResultFromDb = ($resultFromDb[UrlRewrite::REQUEST_PATH] === $requestPath
114-
|| in_array((int)$resultFromDb[UrlRewrite::REDIRECT_TYPE], $redirectTypes, true));
115-
116-
// Otherwise return 301 redirect to request path from DB results
117-
$result = $canReturnResultFromDb ? $resultFromDb : [
118-
UrlRewrite::ENTITY_TYPE => 'custom',
119-
UrlRewrite::ENTITY_ID => '0',
120-
UrlRewrite::REQUEST_PATH => $requestPath,
121-
UrlRewrite::TARGET_PATH => $resultFromDb[UrlRewrite::REQUEST_PATH],
122-
UrlRewrite::REDIRECT_TYPE => OptionProvider::PERMANENT,
123-
UrlRewrite::STORE_ID => $resultFromDb[UrlRewrite::STORE_ID],
124-
UrlRewrite::DESCRIPTION => null,
125-
UrlRewrite::IS_AUTOGENERATED => '0',
126-
UrlRewrite::METADATA => null,
127-
];
128-
} else {
129-
// If we have 2 results - return the row that matches request path
130-
foreach ($resultsFromDb as $resultFromDb) {
131-
if ($resultFromDb[UrlRewrite::REQUEST_PATH] === $requestPath) {
132-
$result = $resultFromDb;
133-
break;
134-
}
135-
}
112+
if ($resultsFromDb) {
113+
$urlRewrite = $this->extractMostRelevantUrlRewrite($requestPath, $resultsFromDb);
114+
$result = $this->prepareUrlRewrite($requestPath, $urlRewrite);
136115
}
137116

138117
return $result;
@@ -142,8 +121,78 @@ protected function doFindOneByData(array $data)
142121
}
143122

144123
/**
145-
* @param UrlRewrite[] $urls
124+
* Extract most relevant url rewrite from url rewrites list
125+
*
126+
* @param string $requestPath
127+
* @param array $urlRewrites
128+
* @return array|null
129+
*/
130+
private function extractMostRelevantUrlRewrite(string $requestPath, array $urlRewrites)
131+
{
132+
$prioritizedUrlRewrites = [];
133+
foreach ($urlRewrites as $urlRewrite) {
134+
switch (true) {
135+
case $urlRewrite[UrlRewrite::REQUEST_PATH] === $requestPath:
136+
$priority = 1;
137+
break;
138+
case $urlRewrite[UrlRewrite::REQUEST_PATH] === urldecode($requestPath):
139+
$priority = 2;
140+
break;
141+
case rtrim($urlRewrite[UrlRewrite::REQUEST_PATH], '/') === rtrim($requestPath, '/'):
142+
$priority = 3;
143+
break;
144+
case rtrim($urlRewrite[UrlRewrite::REQUEST_PATH], '/') === rtrim(urldecode($requestPath), '/'):
145+
$priority = 4;
146+
break;
147+
default:
148+
$priority = 5;
149+
break;
150+
}
151+
$prioritizedUrlRewrites[$priority] = $urlRewrite;
152+
}
153+
ksort($prioritizedUrlRewrites);
154+
155+
return array_shift($prioritizedUrlRewrites);
156+
}
157+
158+
/**
159+
* Prepare url rewrite
146160
*
161+
* If request path matches the DB value or it's redirect - we can return result from DB
162+
* Otherwise return 301 redirect to request path from DB results
163+
*
164+
* @param string $requestPath
165+
* @param array $urlRewrite
166+
* @return array
167+
*/
168+
private function prepareUrlRewrite(string $requestPath, array $urlRewrite): array
169+
{
170+
$redirectTypes = [OptionProvider::TEMPORARY, OptionProvider::PERMANENT];
171+
$canReturnResultFromDb = (
172+
in_array($urlRewrite[UrlRewrite::REQUEST_PATH], [$requestPath, urldecode($requestPath)], true)
173+
|| in_array((int) $urlRewrite[UrlRewrite::REDIRECT_TYPE], $redirectTypes, true)
174+
);
175+
if (!$canReturnResultFromDb) {
176+
$urlRewrite = [
177+
UrlRewrite::ENTITY_TYPE => 'custom',
178+
UrlRewrite::ENTITY_ID => '0',
179+
UrlRewrite::REQUEST_PATH => $requestPath,
180+
UrlRewrite::TARGET_PATH => $urlRewrite[UrlRewrite::REQUEST_PATH],
181+
UrlRewrite::REDIRECT_TYPE => OptionProvider::PERMANENT,
182+
UrlRewrite::STORE_ID => $urlRewrite[UrlRewrite::STORE_ID],
183+
UrlRewrite::DESCRIPTION => null,
184+
UrlRewrite::IS_AUTOGENERATED => '0',
185+
UrlRewrite::METADATA => null,
186+
];
187+
}
188+
189+
return $urlRewrite;
190+
}
191+
192+
/**
193+
* Delete old url rewrites
194+
*
195+
* @param UrlRewrite[] $urls
147196
* @return void
148197
*/
149198
private function deleteOldUrls(array $urls)

dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212

1313
class ProductTest extends TestCase
1414
{
15+
/**
16+
* @var ProductRepositoryInterface
17+
*/
18+
private $productRepository;
19+
1520
/**
1621
* @var Product
1722
*/
@@ -29,7 +34,8 @@ protected function setUp()
2934
{
3035
$this->objectManager = Bootstrap::getObjectManager();
3136

32-
$this->model = $this->objectManager->get(Product::class);
37+
$this->productRepository = $this->objectManager->create(ProductRepositoryInterface::class);
38+
$this->model = $this->objectManager->create(Product::class);
3339
}
3440

3541
/**
@@ -42,11 +48,29 @@ public function testGetAttributeRawValue()
4248
$sku = 'simple';
4349
$attribute = 'name';
4450

45-
/** @var ProductRepositoryInterface $productRepository */
46-
$productRepository = $this->objectManager->get(ProductRepositoryInterface::class);
47-
$product = $productRepository->get($sku);
48-
51+
$product = $this->productRepository->get($sku);
4952
$actual = $this->model->getAttributeRawValue($product->getId(), $attribute, null);
5053
self::assertEquals($product->getName(), $actual);
5154
}
55+
56+
/**
57+
* @magentoAppArea adminhtml
58+
* @magentoDataFixture Magento/Catalog/_files/product_special_price.php
59+
* @magentoAppIsolation enabled
60+
* @magentoConfigFixture default_store catalog/price/scope 1
61+
*/
62+
public function testUpdateStoreSpecificSpecialPrice()
63+
{
64+
/** @var \Magento\Catalog\Model\Product $product */
65+
$product = $this->productRepository->get('simple', true, 1);
66+
$this->assertEquals(5.99, $product->getSpecialPrice());
67+
68+
$product->setSpecialPrice('');
69+
$this->model->save($product);
70+
$product = $this->productRepository->get('simple', false, 1, true);
71+
$this->assertEmpty($product->getSpecialPrice());
72+
73+
$product = $this->productRepository->get('simple', false, 0, true);
74+
$this->assertEquals(5.99, $product->getSpecialPrice());
75+
}
5276
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\UrlRewrite\Model;
9+
10+
use Magento\TestFramework\Helper\Bootstrap;
11+
use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
12+
13+
/**
14+
* @magentoDataFixture Magento/UrlRewrite/_files/url_rewrites.php
15+
*/
16+
class UrlFinderInterfaceTest extends \PHPUnit\Framework\TestCase
17+
{
18+
/**
19+
* @var UrlFinderInterface
20+
*/
21+
private $urlFinder;
22+
23+
/**
24+
* @inheritdoc
25+
*/
26+
protected function setUp()
27+
{
28+
$this->urlFinder = Bootstrap::getObjectManager()->create(UrlFinderInterface::class);
29+
}
30+
31+
/**
32+
* @dataProvider findOneDataProvider
33+
* @param string $requestPath
34+
* @param string $targetPath
35+
* @param int $redirectType
36+
*/
37+
public function testFindOneByData(string $requestPath, string $targetPath, int $redirectType)
38+
{
39+
$data = [
40+
UrlRewrite::REQUEST_PATH => $requestPath,
41+
];
42+
$urlRewrite = $this->urlFinder->findOneByData($data);
43+
$this->assertEquals($targetPath, $urlRewrite->getTargetPath());
44+
$this->assertEquals($redirectType, $urlRewrite->getRedirectType());
45+
}
46+
47+
/**
48+
* @return array
49+
*/
50+
public function findOneDataProvider(): array
51+
{
52+
return [
53+
['string', 'test_page1', 0],
54+
['string/', 'string', 301],
55+
['string_permanent', 'test_page1', 301],
56+
['string_permanent/', 'test_page1', 301],
57+
['string_temporary', 'test_page1', 302],
58+
['string_temporary/', 'test_page1', 302],
59+
['строка', 'test_page1', 0],
60+
['строка/', 'строка', 301],
61+
[urlencode('строка'), 'test_page2', 0],
62+
[urlencode('строка') . '/', urlencode('строка'), 301],
63+
['другая_строка', 'test_page1', 302],
64+
['другая_строка/', 'test_page1', 302],
65+
[urlencode('другая_строка'), 'test_page1', 302],
66+
[urlencode('другая_строка') . '/', 'test_page1', 302],
67+
['السلسلة', 'test_page1', 0],
68+
[urlencode('السلسلة'), 'test_page1', 0],
69+
];
70+
}
71+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
8+
9+
$rewritesData = [
10+
[
11+
'string', 'test_page1', 0
12+
],
13+
[
14+
'string_permanent', 'test_page1', \Magento\UrlRewrite\Model\OptionProvider::PERMANENT
15+
],
16+
[
17+
'string_temporary', 'test_page1', \Magento\UrlRewrite\Model\OptionProvider::TEMPORARY
18+
],
19+
[
20+
'строка', 'test_page1', 0
21+
],
22+
[
23+
urlencode('строка'), 'test_page2', 0
24+
],
25+
[
26+
'другая_строка', 'test_page1', \Magento\UrlRewrite\Model\OptionProvider::TEMPORARY
27+
],
28+
[
29+
'السلسلة', 'test_page1', 0
30+
],
31+
];
32+
33+
$rewriteResource = $objectManager->create(\Magento\UrlRewrite\Model\ResourceModel\UrlRewrite::class);
34+
foreach ($rewritesData as $rewriteData) {
35+
list ($requestPath, $targetPath, $redirectType) = $rewriteData;
36+
$rewrite = $objectManager->create(\Magento\UrlRewrite\Model\UrlRewrite::class);
37+
$rewrite->setEntityType('custom')
38+
->setRequestPath($requestPath)
39+
->setTargetPath($targetPath)
40+
->setRedirectType($redirectType);
41+
$rewriteResource->save($rewrite);
42+
}

0 commit comments

Comments
 (0)