Skip to content

Commit 211dd25

Browse files
authored
Merge pull request magento#4173 from magento-performance/MC-4244-PR
[performance] MC-4244: Skip URL rewrites multiplication
2 parents faf4db0 + f9329d8 commit 211dd25

File tree

41 files changed

+1624
-215
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1624
-215
lines changed

app/code/Magento/Catalog/Model/ResourceModel/Product.php

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
use Magento\Framework\App\ObjectManager;
1010
use Magento\Catalog\Model\Indexer\Category\Product\TableMaintainer;
1111
use Magento\Eav\Model\Entity\Attribute\UniqueValidationInterface;
12+
use Magento\Framework\EntityManager\EntityManager;
13+
use Magento\Framework\Model\AbstractModel;
1214

1315
/**
1416
* Product entity resource model
@@ -44,7 +46,7 @@ class Product extends AbstractResource
4446
/**
4547
* Category collection factory
4648
*
47-
* @var \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory
49+
* @var Category\CollectionFactory
4850
*/
4951
protected $_categoryCollectionFactory;
5052

@@ -64,7 +66,7 @@ class Product extends AbstractResource
6466
protected $typeFactory;
6567

6668
/**
67-
* @var \Magento\Framework\EntityManager\EntityManager
69+
* @var EntityManager
6870
* @since 101.0.0
6971
*/
7072
protected $entityManager;
@@ -81,7 +83,7 @@ class Product extends AbstractResource
8183
protected $availableCategoryIdsCache = [];
8284

8385
/**
84-
* @var \Magento\Catalog\Model\ResourceModel\Product\CategoryLink
86+
* @var Product\CategoryLink
8587
*/
8688
private $productCategoryLink;
8789

@@ -110,7 +112,7 @@ public function __construct(
110112
\Magento\Eav\Model\Entity\Context $context,
111113
\Magento\Store\Model\StoreManagerInterface $storeManager,
112114
\Magento\Catalog\Model\Factory $modelFactory,
113-
\Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $categoryCollectionFactory,
115+
Category\CollectionFactory $categoryCollectionFactory,
114116
Category $catalogCategory,
115117
\Magento\Framework\Event\ManagerInterface $eventManager,
116118
\Magento\Eav\Model\Entity\Attribute\SetFactory $setFactory,
@@ -236,7 +238,7 @@ public function getWebsiteIdsByProductIds($productIds)
236238
/**
237239
* Retrieve product category identifiers
238240
*
239-
* @param \Magento\Catalog\Model\Product $product
241+
* @param \Magento\Catalog\Model\Product $product
240242
* @return array
241243
*/
242244
public function getCategoryIds($product)
@@ -248,7 +250,7 @@ public function getCategoryIds($product)
248250
/**
249251
* Get product identifier by sku
250252
*
251-
* @param string $sku
253+
* @param string $sku
252254
* @return int|false
253255
*/
254256
public function getIdBySku($sku)
@@ -348,11 +350,11 @@ protected function _saveCategories(\Magento\Framework\DataObject $object)
348350
* Get collection of product categories
349351
*
350352
* @param \Magento\Catalog\Model\Product $product
351-
* @return \Magento\Catalog\Model\ResourceModel\Category\Collection
353+
* @return Category\Collection
352354
*/
353355
public function getCategoryCollection($product)
354356
{
355-
/** @var \Magento\Catalog\Model\ResourceModel\Category\Collection $collection */
357+
/** @var Category\Collection $collection */
356358
$collection = $this->_categoryCollectionFactory->create();
357359
$collection->joinField(
358360
'product_id',
@@ -428,18 +430,26 @@ public function getDefaultAttributeSourceModel()
428430
/**
429431
* Check availability display product in category
430432
*
431-
* @param \Magento\Catalog\Model\Product $product
433+
* @param \Magento\Catalog\Model\Product|int $product
432434
* @param int $categoryId
433435
* @return string
434436
*/
435437
public function canBeShowInCategory($product, $categoryId)
436438
{
439+
if ($product instanceof \Magento\Catalog\Model\Product) {
440+
$productId = $product->getEntityId();
441+
$storeId = $product->getStoreId();
442+
} else {
443+
$productId = $product;
444+
$storeId = $this->_storeManager->getStore()->getId();
445+
}
446+
437447
$select = $this->getConnection()->select()->from(
438-
$this->tableMaintainer->getMainTable($product->getStoreId()),
448+
$this->tableMaintainer->getMainTable($storeId),
439449
'product_id'
440450
)->where(
441451
'product_id = ?',
442-
(int)$product->getEntityId()
452+
(int)$productId
443453
)->where(
444454
'category_id = ?',
445455
(int)$categoryId
@@ -614,7 +624,7 @@ public function validate($object)
614624
/**
615625
* Reset firstly loaded attributes
616626
*
617-
* @param \Magento\Framework\Model\AbstractModel $object
627+
* @param AbstractModel $object
618628
* @param integer $entityId
619629
* @param array|null $attributes
620630
* @return $this
@@ -667,12 +677,12 @@ protected function evaluateDelete($object, $id, $connection)
667677
/**
668678
* Save entity's attributes into the object's resource
669679
*
670-
* @param \Magento\Framework\Model\AbstractModel $object
680+
* @param AbstractModel $object
671681
* @return $this
672682
* @throws \Exception
673683
* @since 101.0.0
674684
*/
675-
public function save(\Magento\Framework\Model\AbstractModel $object)
685+
public function save(AbstractModel $object)
676686
{
677687
$this->getEntityManager()->save($object);
678688
return $this;
@@ -681,13 +691,13 @@ public function save(\Magento\Framework\Model\AbstractModel $object)
681691
/**
682692
* Retrieve entity manager object
683693
*
684-
* @return \Magento\Framework\EntityManager\EntityManager
694+
* @return EntityManager
685695
*/
686696
private function getEntityManager()
687697
{
688698
if (null === $this->entityManager) {
689-
$this->entityManager = \Magento\Framework\App\ObjectManager::getInstance()
690-
->get(\Magento\Framework\EntityManager\EntityManager::class);
699+
$this->entityManager = ObjectManager::getInstance()
700+
->get(EntityManager::class);
691701
}
692702
return $this->entityManager;
693703
}
@@ -707,13 +717,13 @@ private function getProductWebsiteLink()
707717
* Retrieve CategoryLink object
708718
*
709719
* @deprecated 101.1.0
710-
* @return \Magento\Catalog\Model\ResourceModel\Product\CategoryLink
720+
* @return Product\CategoryLink
711721
*/
712722
private function getProductCategoryLink()
713723
{
714724
if (null === $this->productCategoryLink) {
715-
$this->productCategoryLink = \Magento\Framework\App\ObjectManager::getInstance()
716-
->get(\Magento\Catalog\Model\ResourceModel\Product\CategoryLink::class);
725+
$this->productCategoryLink = ObjectManager::getInstance()
726+
->get(Product\CategoryLink::class);
717727
}
718728
return $this->productCategoryLink;
719729
}

app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php

Lines changed: 32 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use Magento\Catalog\Model\Product\Gallery\ReadHandler as GalleryReadHandler;
1414
use Magento\Catalog\Model\ResourceModel\Product\Collection\ProductLimitationFactory;
1515
use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator;
16+
use Magento\CatalogUrlRewrite\Model\Storage\DbStorage;
1617
use Magento\Customer\Api\GroupManagementInterface;
1718
use Magento\Customer\Model\Indexer\CustomerGroupDimensionProvider;
1819
use Magento\Framework\App\ObjectManager;
@@ -296,6 +297,11 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Collection\Abstrac
296297
*/
297298
private $emptyItem;
298299

300+
/**
301+
* @var DbStorage
302+
*/
303+
private $urlFinder;
304+
299305
/**
300306
* Collection constructor
301307
*
@@ -388,6 +394,19 @@ public function __construct(
388394
?: ObjectManager::getInstance()->get(DimensionFactory::class);
389395
}
390396

397+
/**
398+
* Retrieve urlFinder
399+
*
400+
* @return GalleryReadHandler
401+
*/
402+
private function getUrlFinder()
403+
{
404+
if ($this->urlFinder === null) {
405+
$this->urlFinder = ObjectManager::getInstance()->get(DbStorage::class);
406+
}
407+
return $this->urlFinder;
408+
}
409+
391410
/**
392411
* Get cloned Select after dispatching 'catalog_prepare_price_select' event
393412
*
@@ -1417,44 +1436,21 @@ protected function _addUrlRewrite()
14171436
foreach ($this->getItems() as $item) {
14181437
$productIds[] = $item->getEntityId();
14191438
}
1420-
if (!$productIds) {
1421-
return;
1422-
}
1423-
1424-
$select = $this->getConnection()
1425-
->select()
1426-
->from(['u' => $this->getTable('url_rewrite')], ['u.entity_id', 'u.request_path'])
1427-
->where('u.store_id = ?', $this->_storeManager->getStore($this->getStoreId())->getId())
1428-
->where('u.is_autogenerated = 1')
1429-
->where('u.entity_type = ?', ProductUrlRewriteGenerator::ENTITY_TYPE)
1430-
->where('u.entity_id IN(?)', $productIds);
14311439

1440+
$filter = [
1441+
'entity_type' => 'product',
1442+
'entity_id' => $productIds,
1443+
'store_id' => $this->getStoreId(),
1444+
'is_autogenerated' => 1
1445+
];
14321446
if ($this->_urlRewriteCategory) {
1433-
$select->joinInner(
1434-
['cu' => $this->getTable('catalog_url_rewrite_product_category')],
1435-
'u.url_rewrite_id=cu.url_rewrite_id'
1436-
)->where('cu.category_id IN (?)', $this->_urlRewriteCategory);
1437-
} else {
1438-
$select->joinLeft(
1439-
['cu' => $this->getTable('catalog_url_rewrite_product_category')],
1440-
'u.url_rewrite_id=cu.url_rewrite_id'
1441-
)->where('cu.url_rewrite_id IS NULL');
1442-
}
1443-
1444-
// more priority is data with category id
1445-
$urlRewrites = [];
1446-
1447-
foreach ($this->getConnection()->fetchAll($select) as $row) {
1448-
if (!isset($urlRewrites[$row['entity_id']])) {
1449-
$urlRewrites[$row['entity_id']] = $row['request_path'];
1450-
}
1447+
$filter['metadata']['category_id'] = $this->_urlRewriteCategory;
14511448
}
14521449

1453-
foreach ($this->getItems() as $item) {
1454-
if (isset($urlRewrites[$item->getEntityId()])) {
1455-
$item->setData('request_path', $urlRewrites[$item->getEntityId()]);
1456-
} else {
1457-
$item->setData('request_path', false);
1450+
$rewrites = $this->getUrlFinder()->findAllByData($filter);
1451+
foreach ($rewrites as $rewrite) {
1452+
if ($item = $this->getItemById($rewrite->getEntityId())) {
1453+
$item->setData('request_path', $rewrite->getRequestPath());
14581454
}
14591455
}
14601456
}
@@ -1976,8 +1972,7 @@ protected function _productLimitationPrice($joinLeft = false)
19761972
}
19771973
// Set additional field filters
19781974
foreach ($this->_priceDataFieldFilters as $filterData) {
1979-
// phpcs:ignore Magento2.Functions.DiscouragedFunction
1980-
$select->where(call_user_func_array('sprintf', $filterData));
1975+
$select->where(sprintf(...$filterData));
19811976
}
19821977
} else {
19831978
$fromPart['price_index']['joinCondition'] = $joinCond;
@@ -2282,8 +2277,7 @@ private function getBackend()
22822277
public function addPriceDataFieldFilter($comparisonFormat, $fields)
22832278
{
22842279
if (!preg_match('/^%s( (<|>|=|<=|>=|<>) %s)*$/', $comparisonFormat)) {
2285-
// phpcs:ignore Magento2.Exceptions.DirectThrow
2286-
throw new \Exception('Invalid comparison format.');
2280+
throw new \InvalidArgumentException('Invalid comparison format.');
22872281
}
22882282

22892283
if (!is_array($fields)) {

app/code/Magento/Catalog/etc/adminhtml/system.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,14 +114,14 @@
114114
</group>
115115
<group id="seo" translate="label" type="text" sortOrder="500" showInDefault="1" showInWebsite="1" showInStore="1">
116116
<label>Search Engine Optimization</label>
117-
<field id="title_separator" translate="label" type="text" sortOrder="6" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1">
117+
<field id="title_separator" translate="label" type="text" sortOrder="7" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1">
118118
<label>Page Title Separator</label>
119119
</field>
120-
<field id="category_canonical_tag" translate="label" type="select" sortOrder="7" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1">
120+
<field id="category_canonical_tag" translate="label" type="select" sortOrder="8" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1">
121121
<label>Use Canonical Link Meta Tag For Categories</label>
122122
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
123123
</field>
124-
<field id="product_canonical_tag" translate="label" type="select" sortOrder="8" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1">
124+
<field id="product_canonical_tag" translate="label" type="select" sortOrder="9" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1">
125125
<label>Use Canonical Link Meta Tag For Products</label>
126126
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
127127
</field>

app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Storage.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
1212
use Magento\CatalogUrlRewrite\Model\ResourceModel\Category\Product;
1313

14+
/**
15+
* Storage Plugin
16+
*/
1417
class Storage
1518
{
1619
/**
@@ -36,6 +39,8 @@ public function __construct(
3639
}
3740

3841
/**
42+
* Save product/category urlRewrite association
43+
*
3944
* @param \Magento\UrlRewrite\Model\StorageInterface $object
4045
* @param \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[] $result
4146
* @param \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[] $urls
@@ -53,13 +58,15 @@ public function afterReplace(StorageInterface $object, array $result, array $url
5358
'product_id' => $record->getEntityId(),
5459
];
5560
}
56-
if ($toSave) {
61+
if (count($toSave) > 0) {
5762
$this->productResource->saveMultiple($toSave);
5863
}
5964
return $result;
6065
}
6166

6267
/**
68+
* Remove product/category urlRewrite association
69+
*
6370
* @param \Magento\UrlRewrite\Model\StorageInterface $object
6471
* @param array $data
6572
* @return void
@@ -71,6 +78,8 @@ public function beforeDeleteByData(StorageInterface $object, array $data)
7178
}
7279

7380
/**
81+
* Filter urls
82+
*
7483
* @param \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[] $urls
7584
* @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[]
7685
*/
@@ -96,6 +105,8 @@ protected function filterUrls(array $urls)
96105
}
97106

98107
/**
108+
* Check if url is correct
109+
*
99110
* @param UrlRewrite $url
100111
* @return bool
101112
*/

app/code/Magento/CatalogUrlRewrite/Model/Product/AnchorUrlRewriteGenerator.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,12 @@
1313
use Magento\Framework\Exception\NoSuchEntityException;
1414
use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
1515
use Magento\UrlRewrite\Service\V1\Data\UrlRewriteFactory;
16+
use Magento\Framework\App\Config\ScopeConfigInterface;
17+
use Magento\Framework\App\ObjectManager;
1618

19+
/**
20+
* Generate url rewrites for anchor categories
21+
*/
1722
class AnchorUrlRewriteGenerator
1823
{
1924
/**
@@ -52,7 +57,7 @@ public function __construct(
5257
* @param int $storeId
5358
* @param Product $product
5459
* @param ObjectRegistry $productCategories
55-
* @return UrlRewrite[]
60+
* @return UrlRewrite[]|array
5661
*/
5762
public function generate($storeId, Product $product, ObjectRegistry $productCategories)
5863
{

0 commit comments

Comments
 (0)