Skip to content

Commit 06fe109

Browse files
committed
MAGETWO-98643: [Magento Cloud] Translated Arabic URL's are returning 404's
1 parent 6cc68c6 commit 06fe109

File tree

4 files changed

+210
-32
lines changed

4 files changed

+210
-32
lines changed

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

Lines changed: 77 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -105,42 +105,18 @@ protected function doFindOneByData(array $data)
105105
$result = null;
106106

107107
$requestPath = $data[UrlRewrite::REQUEST_PATH];
108-
109-
$data[UrlRewrite::REQUEST_PATH] = [
108+
$decodedRequestPath = urldecode($requestPath);
109+
$data[UrlRewrite::REQUEST_PATH] = array_unique([
110110
rtrim($requestPath, '/'),
111111
rtrim($requestPath, '/') . '/',
112-
];
112+
rtrim($decodedRequestPath, '/'),
113+
rtrim($decodedRequestPath, '/') . '/',
114+
]);
113115

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

146122
return $result;
@@ -149,6 +125,75 @@ protected function doFindOneByData(array $data)
149125
return $this->connection->fetchRow($this->prepareSelect($data));
150126
}
151127

128+
/**
129+
* Extract most relevant url rewrite from url rewrites list
130+
*
131+
* @param string $requestPath
132+
* @param array $urlRewrites
133+
* @return array|null
134+
*/
135+
private function extractMostRelevantUrlRewrite(string $requestPath, array $urlRewrites): ?array
136+
{
137+
$prioritizedUrlRewrites = [];
138+
foreach ($urlRewrites as $urlRewrite) {
139+
switch (true) {
140+
case $urlRewrite[UrlRewrite::REQUEST_PATH] === $requestPath:
141+
$priority = 1;
142+
break;
143+
case $urlRewrite[UrlRewrite::REQUEST_PATH] === urldecode($requestPath):
144+
$priority = 2;
145+
break;
146+
case rtrim($urlRewrite[UrlRewrite::REQUEST_PATH], '/') === rtrim($requestPath, '/'):
147+
$priority = 3;
148+
break;
149+
case rtrim($urlRewrite[UrlRewrite::REQUEST_PATH], '/') === rtrim(urldecode($requestPath), '/'):
150+
$priority = 4;
151+
break;
152+
default:
153+
$priority = 5;
154+
break;
155+
}
156+
$prioritizedUrlRewrites[$priority] = $urlRewrite;
157+
}
158+
ksort($prioritizedUrlRewrites);
159+
160+
return array_shift($prioritizedUrlRewrites);
161+
}
162+
163+
/**
164+
* Prepare url rewrite
165+
*
166+
* If request path matches the DB value or it's redirect - we can return result from DB
167+
* Otherwise return 301 redirect to request path from DB results
168+
*
169+
* @param string $requestPath
170+
* @param array $urlRewrite
171+
* @return array
172+
*/
173+
private function prepareUrlRewrite(string $requestPath, array $urlRewrite): array
174+
{
175+
$redirectTypes = [OptionProvider::TEMPORARY, OptionProvider::PERMANENT];
176+
$canReturnResultFromDb = (
177+
in_array($urlRewrite[UrlRewrite::REQUEST_PATH], [$requestPath, urldecode($requestPath)], true)
178+
|| in_array((int) $urlRewrite[UrlRewrite::REDIRECT_TYPE], $redirectTypes, true)
179+
);
180+
if (!$canReturnResultFromDb) {
181+
$urlRewrite = [
182+
UrlRewrite::ENTITY_TYPE => 'custom',
183+
UrlRewrite::ENTITY_ID => '0',
184+
UrlRewrite::REQUEST_PATH => $requestPath,
185+
UrlRewrite::TARGET_PATH => $urlRewrite[UrlRewrite::REQUEST_PATH],
186+
UrlRewrite::REDIRECT_TYPE => OptionProvider::PERMANENT,
187+
UrlRewrite::STORE_ID => $urlRewrite[UrlRewrite::STORE_ID],
188+
UrlRewrite::DESCRIPTION => null,
189+
UrlRewrite::IS_AUTOGENERATED => '0',
190+
UrlRewrite::METADATA => null,
191+
];
192+
}
193+
194+
return $urlRewrite;
195+
}
196+
152197
/**
153198
* Delete old URLs from DB.
154199
*
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+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
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+
$registry = $objectManager->get(\Magento\Framework\Registry::class);
10+
$registry->unregister('isSecureArea');
11+
$registry->register('isSecureArea', true);
12+
13+
$urlRewriteCollection = $objectManager->create(\Magento\UrlRewrite\Model\ResourceModel\UrlRewriteCollection::class);
14+
$collection = $urlRewriteCollection
15+
->addFieldToFilter('target_path', ['test_page1', 'test_page2'])
16+
->load()
17+
->walk('delete');
18+
19+
$registry->unregister('isSecureArea');
20+
$registry->register('isSecureArea', false);

0 commit comments

Comments
 (0)