Skip to content

Commit 2488501

Browse files
committed
Merge remote-tracking branch 'origin/MAGETWO-90331' into 2.3-develop-pr16
2 parents 8b87fa9 + feed4a9 commit 2488501

File tree

2 files changed

+100
-100
lines changed

2 files changed

+100
-100
lines changed

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

Lines changed: 76 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,24 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
67
namespace Magento\UrlRewrite\Model\Storage;
78

89
use Magento\Framework\Api\DataObjectHelper;
910
use Magento\Framework\App\ResourceConnection;
11+
use Magento\Framework\DB\Select;
1012
use Magento\UrlRewrite\Model\OptionProvider;
1113
use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
1214
use Magento\UrlRewrite\Service\V1\Data\UrlRewriteFactory;
1315
use Psr\Log\LoggerInterface;
14-
use Magento\UrlRewrite\Service\V1\Data\UrlRewrite as UrlRewriteData;
16+
use Magento\Framework\App\ObjectManager;
17+
use Magento\Framework\DB\Adapter\AdapterInterface;
1518

19+
/**
20+
* Url rewrites DB storage.
21+
*
22+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
23+
*/
1624
class DbStorage extends AbstractStorage
1725
{
1826
/**
@@ -26,7 +34,7 @@ class DbStorage extends AbstractStorage
2634
const ERROR_CODE_DUPLICATE_ENTRY = 1062;
2735

2836
/**
29-
* @var \Magento\Framework\DB\Adapter\AdapterInterface
37+
* @var AdapterInterface
3038
*/
3139
protected $connection;
3240

@@ -36,15 +44,15 @@ class DbStorage extends AbstractStorage
3644
protected $resource;
3745

3846
/**
39-
* @var \Psr\Log\LoggerInterface
47+
* @var LoggerInterface
4048
*/
4149
private $logger;
4250

4351
/**
44-
* @param \Magento\UrlRewrite\Service\V1\Data\UrlRewriteFactory $urlRewriteFactory
52+
* @param UrlRewriteFactory $urlRewriteFactory
4553
* @param DataObjectHelper $dataObjectHelper
46-
* @param \Magento\Framework\App\ResourceConnection $resource
47-
* @param \Psr\Log\LoggerInterface|null $logger
54+
* @param ResourceConnection $resource
55+
* @param LoggerInterface|null $logger
4856
*/
4957
public function __construct(
5058
UrlRewriteFactory $urlRewriteFactory,
@@ -54,8 +62,8 @@ public function __construct(
5462
) {
5563
$this->connection = $resource->getConnection();
5664
$this->resource = $resource;
57-
$this->logger = $logger ?: \Magento\Framework\App\ObjectManager::getInstance()
58-
->get(\Psr\Log\LoggerInterface::class);
65+
$this->logger = $logger ?: ObjectManager::getInstance()
66+
->get(LoggerInterface::class);
5967

6068
parent::__construct($urlRewriteFactory, $dataObjectHelper);
6169
}
@@ -64,7 +72,7 @@ public function __construct(
6472
* Prepare select statement for specific filter
6573
*
6674
* @param array $data
67-
* @return \Magento\Framework\DB\Select
75+
* @return Select
6876
*/
6977
protected function prepareSelect(array $data)
7078
{
@@ -74,6 +82,7 @@ protected function prepareSelect(array $data)
7482
foreach ($data as $column => $value) {
7583
$select->where($this->connection->quoteIdentifier($column) . ' IN (?)', $value);
7684
}
85+
7786
return $select;
7887
}
7988

@@ -141,17 +150,61 @@ protected function doFindOneByData(array $data)
141150
}
142151

143152
/**
144-
* {@inheritdoc}
153+
* Delete old URLs from DB.
154+
*
155+
* @param UrlRewrite[] $urls
156+
* @return void
145157
*/
146-
protected function doReplace(array $urls)
158+
private function deleteOldUrls(array $urls): void
147159
{
148-
foreach ($this->createFilterDataBasedOnUrls($urls) as $type => $urlData) {
149-
$urlData[UrlRewrite::ENTITY_TYPE] = $type;
150-
// prevent query locking in a case when nothing to delete
151-
if ($this->connection->fetchRow($this->prepareSelect($urlData))) {
152-
$this->deleteByData($urlData);
153-
}
160+
$oldUrlsSelect = $this->connection->select();
161+
$oldUrlsSelect->from(
162+
$this->resource->getTableName(self::TABLE_NAME)
163+
);
164+
/** @var UrlRewrite $url */
165+
foreach ($urls as $url) {
166+
$oldUrlsSelect->orWhere(
167+
$this->connection->quoteIdentifier(
168+
UrlRewrite::ENTITY_TYPE
169+
) . ' = ?',
170+
$url->getEntityType()
171+
);
172+
$oldUrlsSelect->where(
173+
$this->connection->quoteIdentifier(
174+
UrlRewrite::ENTITY_ID
175+
) . ' = ?',
176+
$url->getEntityId()
177+
);
178+
$oldUrlsSelect->where(
179+
$this->connection->quoteIdentifier(
180+
UrlRewrite::STORE_ID
181+
) . ' = ?',
182+
$url->getStoreId()
183+
);
154184
}
185+
186+
// prevent query locking in a case when nothing to delete
187+
$checkOldUrlsSelect = clone $oldUrlsSelect;
188+
$checkOldUrlsSelect->reset(Select::COLUMNS);
189+
$checkOldUrlsSelect->columns('count(*)');
190+
$hasOldUrls = (bool)$this->connection->fetchOne($checkOldUrlsSelect);
191+
192+
if ($hasOldUrls) {
193+
$this->connection->query(
194+
$oldUrlsSelect->deleteFromSelect(
195+
$this->resource->getTableName(self::TABLE_NAME)
196+
)
197+
);
198+
}
199+
}
200+
201+
/**
202+
* @inheritDoc
203+
*/
204+
protected function doReplace(array $urls)
205+
{
206+
$this->deleteOldUrls($urls);
207+
155208
$data = [];
156209
foreach ($urls as $url) {
157210
$data[] = $url->toArray();
@@ -164,12 +217,12 @@ protected function doReplace(array $urls)
164217
foreach ($urls as $url) {
165218
$urlFound = $this->doFindOneByData(
166219
[
167-
UrlRewriteData::REQUEST_PATH => $url->getRequestPath(),
168-
UrlRewriteData::STORE_ID => $url->getStoreId()
220+
UrlRewrite::REQUEST_PATH => $url->getRequestPath(),
221+
UrlRewrite::STORE_ID => $url->getStoreId(),
169222
]
170223
);
171-
if (isset($urlFound[UrlRewriteData::URL_REWRITE_ID])) {
172-
$urlConflicted[$urlFound[UrlRewriteData::URL_REWRITE_ID]] = $url->toArray();
224+
if (isset($urlFound[UrlRewrite::URL_REWRITE_ID])) {
225+
$urlConflicted[$urlFound[UrlRewrite::URL_REWRITE_ID]] = $url->toArray();
173226
}
174227
}
175228
if ($urlConflicted) {
@@ -217,6 +270,7 @@ protected function insertMultiple($data)
217270
*
218271
* @param UrlRewrite[] $urls
219272
* @return array
273+
* @deprecated Not used anymore.
220274
*/
221275
protected function createFilterDataBasedOnUrls($urls)
222276
{
@@ -230,6 +284,7 @@ protected function createFilterDataBasedOnUrls($urls)
230284
}
231285
}
232286
}
287+
233288
return $data;
234289
}
235290

app/code/Magento/UrlRewrite/Test/Unit/Model/Storage/DbStorageTest.php

Lines changed: 24 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
namespace Magento\UrlRewrite\Test\Unit\Model\Storage;
88

9+
use Magento\Framework\DB\Select;
910
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
1011
use Magento\UrlRewrite\Model\Storage\DbStorage;
1112
use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
@@ -49,10 +50,9 @@ protected function setUp()
4950
->disableOriginalConstructor()->getMock();
5051
$this->dataObjectHelper = $this->createMock(\Magento\Framework\Api\DataObjectHelper::class);
5152
$this->connectionMock = $this->createMock(\Magento\Framework\DB\Adapter\AdapterInterface::class);
52-
$this->select = $this->createPartialMock(
53-
\Magento\Framework\DB\Select::class,
54-
['from', 'where', 'deleteFromSelect']
55-
);
53+
$this->select = $this->getMockBuilder(Select::class)
54+
->disableOriginalConstructor()
55+
->getMock();
5656
$this->resource = $this->createMock(\Magento\Framework\App\ResourceConnection::class);
5757

5858
$this->resource->expects($this->any())
@@ -447,87 +447,32 @@ public function testReplace()
447447
// delete
448448

449449
$urlFirst->expects($this->any())
450-
->method('getByKey')
451-
->will($this->returnValueMap([
452-
[UrlRewrite::ENTITY_TYPE, 'product'],
453-
[UrlRewrite::ENTITY_ID, 'entity_1'],
454-
[UrlRewrite::STORE_ID, 'store_id_1'],
455-
]));
456-
$urlFirst->expects($this->any())->method('getEntityType')->willReturn('product');
450+
->method('getEntityType')
451+
->willReturn('product');
452+
$urlFirst->expects($this->any())
453+
->method('getEntityId')
454+
->willReturn('entity_1');
455+
$urlFirst->expects($this->any())
456+
->method('getStoreId')
457+
->willReturn('store_id_1');
458+
459+
$urlSecond->expects($this->any())
460+
->method('getEntityType')
461+
->willReturn('category');
462+
$urlSecond->expects($this->any())
463+
->method('getEntityId')
464+
->willReturn('entity_2');
457465
$urlSecond->expects($this->any())
458-
->method('getByKey')
459-
->will($this->returnValueMap([
460-
[UrlRewrite::ENTITY_TYPE, 'category'],
461-
[UrlRewrite::ENTITY_ID, 'entity_2'],
462-
[UrlRewrite::STORE_ID, 'store_id_2'],
463-
]));
464-
$urlSecond->expects($this->any())->method('getEntityType')->willReturn('category');
466+
->method('getStoreId')
467+
->willReturn('store_id_2');
465468

466469
$this->connectionMock->expects($this->any())
467470
->method('quoteIdentifier')
468471
->will($this->returnArgument(0));
469472

470-
$this->select->expects($this->at(1))
471-
->method('where')
472-
->with('entity_id IN (?)', ['entity_1']);
473-
474-
$this->select->expects($this->at(2))
475-
->method('where')
476-
->with('store_id IN (?)', ['store_id_1']);
477-
478-
$this->select->expects($this->at(3))
479-
->method('where')
480-
->with('entity_type IN (?)', 'product');
481-
482-
$this->select->expects($this->at(5))
483-
->method('where')
484-
->with('entity_id IN (?)', ['entity_1']);
485-
486-
$this->select->expects($this->at(6))
487-
->method('where')
488-
->with('store_id IN (?)', ['store_id_1']);
489-
490-
$this->select->expects($this->at(7))
491-
->method('where')
492-
->with('entity_type IN (?)', 'product');
493-
494-
$this->connectionMock->expects($this->any())
495-
->method('fetchRow')
496-
->willReturn(['some-data']);
497-
498-
$this->select->expects($this->at(8))
499-
->method('deleteFromSelect')
500-
->with('table_name')
501-
->will($this->returnValue('sql delete query'));
502-
503-
$this->select->expects($this->at(10))
504-
->method('where')
505-
->with('entity_id IN (?)', ['entity_2']);
506-
507-
$this->select->expects($this->at(11))
508-
->method('where')
509-
->with('store_id IN (?)', ['store_id_2']);
510-
511-
$this->select->expects($this->at(12))
512-
->method('where')
513-
->with('entity_type IN (?)', 'category');
514-
515-
$this->select->expects($this->at(14))
516-
->method('where')
517-
->with('entity_id IN (?)', ['entity_2']);
518-
519-
$this->select->expects($this->at(15))
520-
->method('where')
521-
->with('store_id IN (?)', ['store_id_2']);
522-
523-
$this->select->expects($this->at(16))
524-
->method('where')
525-
->with('entity_type IN (?)', 'category');
526-
527-
$this->select->expects($this->at(17))
528-
->method('deleteFromSelect')
529-
->with('table_name')
530-
->will($this->returnValue('sql delete query'));
473+
$this->select->expects($this->any())
474+
->method($this->anything())
475+
->willReturnSelf();
531476

532477
$this->resource->expects($this->any())
533478
->method('getTableName')

0 commit comments

Comments
 (0)