Skip to content

Commit b049c5c

Browse files
author
Yevhen Miroshnychenko
committed
Merge branch '2.2-develop' into MAGETWO-84507
2 parents ebf8674 + 87e41af commit b049c5c

File tree

7 files changed

+184
-94
lines changed

7 files changed

+184
-94
lines changed

app/code/Magento/CatalogUrlRewrite/Observer/CategoryProcessUrlRewriteSavingObserver.php

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
67
namespace Magento\CatalogUrlRewrite\Observer;
78

89
use Magento\Catalog\Model\Category;
@@ -12,6 +13,9 @@
1213
use Magento\CatalogUrlRewrite\Model\Map\DataProductUrlRewriteDatabaseMap;
1314
use Magento\CatalogUrlRewrite\Model\UrlRewriteBunchReplacer;
1415
use Magento\Framework\Event\ObserverInterface;
16+
use Magento\Store\Model\ResourceModel\Group\CollectionFactory;
17+
use Magento\Store\Model\ResourceModel\Group\Collection as StoreGroupCollection;
18+
use Magento\Framework\App\ObjectManager;
1519

1620
/**
1721
* Generates Category Url Rewrites after save and Products Url Rewrites assigned to the category that's being saved
@@ -43,28 +47,37 @@ class CategoryProcessUrlRewriteSavingObserver implements ObserverInterface
4347
*/
4448
private $dataUrlRewriteClassNames;
4549

50+
/**
51+
* @var CollectionFactory
52+
*/
53+
private $storeGroupFactory;
54+
4655
/**
4756
* @param CategoryUrlRewriteGenerator $categoryUrlRewriteGenerator
4857
* @param UrlRewriteHandler $urlRewriteHandler
4958
* @param UrlRewriteBunchReplacer $urlRewriteBunchReplacer
5059
* @param DatabaseMapPool $databaseMapPool
5160
* @param string[] $dataUrlRewriteClassNames
61+
* @param CollectionFactory|null $storeGroupFactory
5262
*/
5363
public function __construct(
5464
CategoryUrlRewriteGenerator $categoryUrlRewriteGenerator,
5565
UrlRewriteHandler $urlRewriteHandler,
5666
UrlRewriteBunchReplacer $urlRewriteBunchReplacer,
5767
DatabaseMapPool $databaseMapPool,
5868
$dataUrlRewriteClassNames = [
59-
DataCategoryUrlRewriteDatabaseMap::class,
60-
DataProductUrlRewriteDatabaseMap::class
61-
]
69+
DataCategoryUrlRewriteDatabaseMap::class,
70+
DataProductUrlRewriteDatabaseMap::class
71+
],
72+
CollectionFactory $storeGroupFactory = null
6273
) {
6374
$this->categoryUrlRewriteGenerator = $categoryUrlRewriteGenerator;
6475
$this->urlRewriteHandler = $urlRewriteHandler;
6576
$this->urlRewriteBunchReplacer = $urlRewriteBunchReplacer;
6677
$this->databaseMapPool = $databaseMapPool;
6778
$this->dataUrlRewriteClassNames = $dataUrlRewriteClassNames;
79+
$this->storeGroupFactory = $storeGroupFactory
80+
?: ObjectManager::getInstance()->get(CollectionFactory::class);
6881
}
6982

7083
/**
@@ -82,6 +95,10 @@ public function execute(\Magento\Framework\Event\Observer $observer)
8295
return;
8396
}
8497

98+
if (!$category->hasData('store_id')) {
99+
$this->setCategoryStoreId($category);
100+
}
101+
85102
$mapsGenerated = false;
86103
if ($category->dataHasChangedFor('url_key')
87104
|| $category->dataHasChangedFor('is_anchor')
@@ -102,6 +119,29 @@ public function execute(\Magento\Framework\Event\Observer $observer)
102119
}
103120
}
104121

122+
/**
123+
* in case store_id is not set for category then we can assume that it was passed through product import.
124+
* store group must have only one root category, so receiving category's path and checking if one of it parts
125+
* is the root category for store group, we can set default_store_id value from it to category.
126+
* it prevents urls duplication for different stores
127+
* ("Default Category/category/sub" and "Default Category2/category/sub")
128+
*
129+
* @param Category $category
130+
* @return void
131+
*/
132+
private function setCategoryStoreId($category)
133+
{
134+
/** @var StoreGroupCollection $storeGroupCollection */
135+
$storeGroupCollection = $this->storeGroupFactory->create();
136+
137+
foreach ($storeGroupCollection as $storeGroup) {
138+
/** @var \Magento\Store\Model\Group $storeGroup */
139+
if (in_array($storeGroup->getRootCategoryId(), explode('/', $category->getPath()))) {
140+
$category->setStoreId($storeGroup->getDefaultStoreId());
141+
}
142+
}
143+
}
144+
105145
/**
106146
* Resets used data maps to free up memory and temporary tables
107147
*

app/code/Magento/Cron/Observer/ProcessCronQueueObserver.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,8 +290,15 @@ protected function _runJob($scheduledTime, $currentTime, $jobConfig, $schedule,
290290

291291
try {
292292
call_user_func_array($callback, [$schedule]);
293-
} catch (\Exception $e) {
293+
} catch (\Throwable $e) {
294294
$schedule->setStatus(Schedule::STATUS_ERROR);
295+
if (!$e instanceof \Exception) {
296+
$e = new \RuntimeException(
297+
'Error when running a cron job',
298+
0,
299+
$e
300+
);
301+
}
295302
throw $e;
296303
}
297304

app/code/Magento/Cron/Test/Unit/Model/CronJobException.php

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,27 @@
1212

1313
class CronJobException
1414
{
15+
/**
16+
* @var \Throwable|null
17+
*/
18+
private $exception;
19+
20+
/**
21+
* @param \Throwable|null $exception
22+
*/
23+
public function __construct(\Throwable $exception = null)
24+
{
25+
$this->exception = $exception;
26+
}
27+
28+
/**
29+
* @throws \Throwable
30+
*/
1531
public function execute()
1632
{
17-
throw new \Exception('Test exception');
33+
if (!$this->exception) {
34+
$this->exception = new \Exception('Test exception');
35+
}
36+
throw $this->exception;
1837
}
1938
}

app/code/Magento/Cron/Test/Unit/Observer/ProcessCronQueueObserverTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,7 @@ public function testDispatchExceptionInCallback(
468468
*/
469469
public function dispatchExceptionInCallbackDataProvider()
470470
{
471+
$throwable = new \TypeError();
471472
return [
472473
'non-callable callback' => [
473474
'Not_Existed_Class',
@@ -483,6 +484,19 @@ public function dispatchExceptionInCallbackDataProvider()
483484
2,
484485
new \Exception(__('Test exception'))
485486
],
487+
'throwable in execution' => [
488+
'CronJobException',
489+
new \Magento\Cron\Test\Unit\Model\CronJobException(
490+
$throwable
491+
),
492+
'Error when running a cron job',
493+
2,
494+
new \RuntimeException(
495+
'Error when running a cron job',
496+
0,
497+
$throwable
498+
)
499+
],
486500
];
487501
}
488502

app/code/Magento/Deploy/Process/Queue.php

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,20 +182,39 @@ public function process()
182182
* @param array $packages
183183
* @param array $packageJob
184184
* @return void
185+
*
186+
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
185187
*/
186188
private function assertAndExecute($name, array & $packages, array $packageJob)
187189
{
188190
/** @var Package $package */
189191
$package = $packageJob['package'];
192+
$dependenciesNotFinished = false;
190193
if ($package->getParent() && $package->getParent() !== $package) {
191194
foreach ($packageJob['dependencies'] as $dependencyName => $dependency) {
192195
if (!$this->isDeployed($dependency)) {
193-
$this->assertAndExecute($dependencyName, $packages, $packages[$dependencyName]);
196+
//If it's not present in $packages then it's already
197+
//in progress so just waiting...
198+
if (!array_key_exists($dependencyName, $packages)) {
199+
$dependenciesNotFinished = true;
200+
} else {
201+
$this->assertAndExecute(
202+
$dependencyName,
203+
$packages,
204+
$packages[$dependencyName]
205+
);
206+
}
194207
}
195208
}
196209
}
197-
if (!$this->isDeployed($package)
198-
&& ($this->maxProcesses < 2 || (count($this->inProgress) < $this->maxProcesses))) {
210+
211+
if (!$dependenciesNotFinished
212+
&& !$this->isDeployed($package)
213+
&& (
214+
$this->maxProcesses < 2
215+
|| (count($this->inProgress) < $this->maxProcesses)
216+
)
217+
) {
199218
unset($packages[$name]);
200219
$this->execute($package);
201220
}

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

Lines changed: 54 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
use Magento\Framework\Api\DataObjectHelper;
99
use Magento\Framework\App\ResourceConnection;
10+
use Magento\Framework\DB\Select;
1011
use Magento\UrlRewrite\Model\OptionProvider;
1112
use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
1213
use Magento\UrlRewrite\Service\V1\Data\UrlRewriteFactory;
@@ -141,17 +142,60 @@ protected function doFindOneByData(array $data)
141142
}
142143

143144
/**
144-
* {@inheritdoc}
145+
* @param UrlRewrite[] $urls
146+
*
147+
* @return void
145148
*/
146-
protected function doReplace(array $urls)
149+
private function deleteOldUrls(array $urls)
147150
{
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-
}
151+
$oldUrlsSelect = $this->connection->select();
152+
$oldUrlsSelect->from(
153+
$this->resource->getTableName(self::TABLE_NAME)
154+
);
155+
/** @var UrlRewrite $url */
156+
foreach ($urls as $url) {
157+
$oldUrlsSelect->orWhere(
158+
$this->connection->quoteIdentifier(
159+
UrlRewrite::ENTITY_TYPE
160+
) . ' = ?',
161+
$url->getEntityType()
162+
);
163+
$oldUrlsSelect->where(
164+
$this->connection->quoteIdentifier(
165+
UrlRewrite::ENTITY_ID
166+
) . ' = ?',
167+
$url->getEntityId()
168+
);
169+
$oldUrlsSelect->where(
170+
$this->connection->quoteIdentifier(
171+
UrlRewrite::STORE_ID
172+
) . ' = ?',
173+
$url->getStoreId()
174+
);
175+
}
176+
177+
// prevent query locking in a case when nothing to delete
178+
$checkOldUrlsSelect = clone $oldUrlsSelect;
179+
$checkOldUrlsSelect->reset(Select::COLUMNS);
180+
$checkOldUrlsSelect->columns('count(*)');
181+
$hasOldUrls = (bool)$this->connection->fetchOne($checkOldUrlsSelect);
182+
183+
if ($hasOldUrls) {
184+
$this->connection->query(
185+
$oldUrlsSelect->deleteFromSelect(
186+
$this->resource->getTableName(self::TABLE_NAME)
187+
)
188+
);
154189
}
190+
}
191+
192+
/**
193+
* @inheritDoc
194+
*/
195+
protected function doReplace(array $urls)
196+
{
197+
$this->deleteOldUrls($urls);
198+
155199
$data = [];
156200
foreach ($urls as $url) {
157201
$data[] = $url->toArray();
@@ -165,7 +209,7 @@ protected function doReplace(array $urls)
165209
$urlFound = $this->doFindOneByData(
166210
[
167211
UrlRewriteData::REQUEST_PATH => $url->getRequestPath(),
168-
UrlRewriteData::STORE_ID => $url->getStoreId()
212+
UrlRewriteData::STORE_ID => $url->getStoreId(),
169213
]
170214
);
171215
if (isset($urlFound[UrlRewriteData::URL_REWRITE_ID])) {
@@ -217,6 +261,7 @@ protected function insertMultiple($data)
217261
*
218262
* @param UrlRewrite[] $urls
219263
* @return array
264+
* @deprecated Not used anymore.
220265
*/
221266
protected function createFilterDataBasedOnUrls($urls)
222267
{

0 commit comments

Comments
 (0)