Skip to content

Commit 5ad40fa

Browse files
authored
Merge pull request #5197 from magento-tsg-csl3/2.4-develop-pr6
[TSG-CSL3] For 2.4 (pr6)
2 parents f9a8884 + 79b35c4 commit 5ad40fa

File tree

19 files changed

+918
-183
lines changed

19 files changed

+918
-183
lines changed

app/code/Magento/Catalog/view/frontend/web/template/product/image_with_borders.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@
66
-->
77
<span class="product-image-container" data-bind="style: {width: width + 'px'}">
88
<span class="product-image-wrapper" data-bind="style: {'padding-bottom': height/width*100 + '%'}">
9-
<img class="product-image-photo" data-bind="attr: {src: src, alt: alt}, style: {width: width + 'px', height: height + 'px'}" />
9+
<img class="product-image-photo" data-bind="attr: {src: src, alt: alt}, style: {width: 'auto', height: 'auto'}" />
1010
</span>
1111
</span>
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
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\CatalogSearch\Model\Search\FilterMapper;
9+
10+
use Magento\Catalog\Model\Product;
11+
use Magento\CatalogSearch\Model\Adapter\Mysql\Filter\AliasResolver;
12+
use Magento\Eav\Model\Config as EavConfig;
13+
use Magento\Framework\DB\Select;
14+
use Magento\Framework\Search\Request\FilterInterface;
15+
16+
/**
17+
* Add stock status filter for each requested filter
18+
*/
19+
class CustomAttributeStockStatusFilter
20+
{
21+
/**
22+
* Suffix to append to filter name in order to generate stock status table alias for JOIN clause
23+
*/
24+
private const STOCK_STATUS_TABLE_ALIAS_SUFFIX = '_stock_index';
25+
/**
26+
* Attribute types to apply
27+
*/
28+
private const TARGET_ATTRIBUTE_TYPES = [
29+
'select',
30+
'multiselect'
31+
];
32+
/**
33+
* @var EavConfig
34+
*/
35+
private $eavConfig;
36+
/**
37+
* @var AliasResolver
38+
*/
39+
private $aliasResolver;
40+
/**
41+
* @var StockStatusQueryBuilder|null
42+
*/
43+
private $stockStatusQueryBuilder;
44+
45+
/**
46+
* @param EavConfig $eavConfig
47+
* @param AliasResolver $aliasResolver
48+
* @param StockStatusQueryBuilder $stockStatusQueryBuilder
49+
*/
50+
public function __construct(
51+
EavConfig $eavConfig,
52+
AliasResolver $aliasResolver,
53+
StockStatusQueryBuilder $stockStatusQueryBuilder
54+
) {
55+
$this->eavConfig = $eavConfig;
56+
$this->aliasResolver = $aliasResolver;
57+
$this->stockStatusQueryBuilder = $stockStatusQueryBuilder;
58+
}
59+
60+
/**
61+
* Apply stock status filter to provided filter
62+
*
63+
* @param Select $select
64+
* @param mixed $values
65+
* @param FilterInterface[] $filters
66+
* @return Select
67+
*/
68+
public function apply(Select $select, $values = null, FilterInterface ...$filters): Select
69+
{
70+
$select = clone $select;
71+
foreach ($filters as $filter) {
72+
if ($this->isApplicable($filter)) {
73+
$mainTableAlias = $this->aliasResolver->getAlias($filter);
74+
$stockTableAlias = $mainTableAlias . self::STOCK_STATUS_TABLE_ALIAS_SUFFIX;
75+
$select = $this->stockStatusQueryBuilder->apply(
76+
$select,
77+
$mainTableAlias,
78+
$stockTableAlias,
79+
'source_id',
80+
$values
81+
);
82+
}
83+
}
84+
return $select;
85+
}
86+
87+
/**
88+
* Check if stock status filter is applicable to provided filter
89+
*
90+
* @param FilterInterface $filter
91+
* @return bool
92+
*/
93+
private function isApplicable(FilterInterface $filter): bool
94+
{
95+
$attribute = $this->eavConfig->getAttribute(Product::ENTITY, $filter->getField());
96+
return $attribute
97+
&& $filter->getType() === FilterInterface::TYPE_TERM
98+
&& in_array($attribute->getFrontendInput(), self::TARGET_ATTRIBUTE_TYPES, true);
99+
}
100+
}

app/code/Magento/CatalogSearch/Model/Search/FilterMapper/FilterMapper.php

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,14 @@
99
use Magento\CatalogSearch\Model\Search\SelectContainer\SelectContainer;
1010
use Magento\CatalogSearch\Model\Adapter\Mysql\Filter\AliasResolver;
1111
use Magento\CatalogInventory\Model\Stock;
12+
use Magento\Framework\App\ObjectManager;
1213

1314
/**
14-
* Class FilterMapper
1515
* This class applies filters to Select based on SelectContainer configuration
1616
*
17-
* @deprecated
17+
* @deprecated MySQL search engine is not recommended.
1818
* @see \Magento\ElasticSearch
19+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
1920
*/
2021
class FilterMapper
2122
{
@@ -43,31 +44,38 @@ class FilterMapper
4344
* @var StockStatusFilter
4445
*/
4546
private $stockStatusFilter;
47+
/**
48+
* @var CustomAttributeStockStatusFilter
49+
*/
50+
private $customAttributeStockStatusFilter;
4651

4752
/**
4853
* @param AliasResolver $aliasResolver
4954
* @param CustomAttributeFilter $customAttributeFilter
5055
* @param FilterStrategyInterface $filterStrategy
5156
* @param VisibilityFilter $visibilityFilter
5257
* @param StockStatusFilter $stockStatusFilter
58+
* @param CustomAttributeStockStatusFilter|null $customAttributeStockStatusFilter
5359
*/
5460
public function __construct(
5561
AliasResolver $aliasResolver,
5662
CustomAttributeFilter $customAttributeFilter,
5763
FilterStrategyInterface $filterStrategy,
5864
VisibilityFilter $visibilityFilter,
59-
StockStatusFilter $stockStatusFilter
65+
StockStatusFilter $stockStatusFilter,
66+
?CustomAttributeStockStatusFilter $customAttributeStockStatusFilter = null
6067
) {
6168
$this->aliasResolver = $aliasResolver;
6269
$this->customAttributeFilter = $customAttributeFilter;
6370
$this->filterStrategy = $filterStrategy;
6471
$this->visibilityFilter = $visibilityFilter;
6572
$this->stockStatusFilter = $stockStatusFilter;
73+
$this->customAttributeStockStatusFilter = $customAttributeStockStatusFilter
74+
?? ObjectManager::getInstance()->get(CustomAttributeStockStatusFilter::class);
6675
}
6776

6877
/**
69-
* Applies filters to Select query in SelectContainer
70-
* based on SelectContainer configuration
78+
* Applies filters to Select query in SelectContainer based on SelectContainer configuration
7179
*
7280
* @param SelectContainer $selectContainer
7381
* @return SelectContainer
@@ -79,22 +87,22 @@ public function applyFilters(SelectContainer $selectContainer)
7987
{
8088
$select = $selectContainer->getSelect();
8189

82-
if ($selectContainer->hasCustomAttributesFilters()) {
83-
$select = $this->customAttributeFilter->apply($select, ...$selectContainer->getCustomAttributesFilters());
84-
}
85-
86-
$filterType = StockStatusFilter::FILTER_JUST_ENTITY;
87-
if ($selectContainer->hasCustomAttributesFilters()) {
88-
$filterType = StockStatusFilter::FILTER_ENTITY_AND_SUB_PRODUCTS;
89-
}
90-
9190
$select = $this->stockStatusFilter->apply(
9291
$select,
9392
Stock::STOCK_IN_STOCK,
94-
$filterType,
93+
StockStatusFilter::FILTER_JUST_ENTITY,
9594
$selectContainer->isShowOutOfStockEnabled()
9695
);
9796

97+
if ($selectContainer->hasCustomAttributesFilters()) {
98+
$select = $this->customAttributeFilter->apply($select, ...$selectContainer->getCustomAttributesFilters());
99+
$select = $this->customAttributeStockStatusFilter->apply(
100+
$select,
101+
$selectContainer->isShowOutOfStockEnabled() ? null : Stock::STOCK_IN_STOCK,
102+
...$selectContainer->getCustomAttributesFilters()
103+
);
104+
}
105+
98106
$appliedFilters = [];
99107

100108
if ($selectContainer->hasVisibilityFilter()) {

app/code/Magento/CatalogSearch/Model/Search/FilterMapper/StockStatusFilter.php

Lines changed: 25 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,17 @@
66

77
namespace Magento\CatalogSearch\Model\Search\FilterMapper;
88

9+
use Magento\Framework\App\ObjectManager;
910
use Magento\Framework\App\ResourceConnection;
1011
use Magento\Framework\DB\Select;
1112
use Magento\Framework\Search\Adapter\Mysql\ConditionManager;
1213
use Magento\CatalogInventory\Api\StockConfigurationInterface;
1314
use Magento\CatalogInventory\Api\StockRegistryInterface;
1415

1516
/**
16-
* Class StockStatusFilter
1717
* Adds filter by stock status to base select
1818
*
19-
* @deprecated
19+
* @deprecated MySQL search engine is not recommended.
2020
* @see \Magento\ElasticSearch
2121
*/
2222
class StockStatusFilter
@@ -56,23 +56,31 @@ class StockStatusFilter
5656
* @var StockRegistryInterface
5757
*/
5858
private $stockRegistry;
59+
/**
60+
* @var StockStatusQueryBuilder
61+
*/
62+
private $stockStatusQueryBuilder;
5963

6064
/**
6165
* @param ResourceConnection $resourceConnection
6266
* @param ConditionManager $conditionManager
6367
* @param StockConfigurationInterface $stockConfiguration
6468
* @param StockRegistryInterface $stockRegistry
69+
* @param StockStatusQueryBuilder|null $stockStatusQueryBuilder
6570
*/
6671
public function __construct(
6772
ResourceConnection $resourceConnection,
6873
ConditionManager $conditionManager,
6974
StockConfigurationInterface $stockConfiguration,
70-
StockRegistryInterface $stockRegistry
75+
StockRegistryInterface $stockRegistry,
76+
?StockStatusQueryBuilder $stockStatusQueryBuilder = null
7177
) {
7278
$this->resourceConnection = $resourceConnection;
7379
$this->conditionManager = $conditionManager;
7480
$this->stockConfiguration = $stockConfiguration;
7581
$this->stockRegistry = $stockRegistry;
82+
$this->stockStatusQueryBuilder = $stockStatusQueryBuilder
83+
?? ObjectManager::getInstance()->get(StockStatusQueryBuilder::class);
7684
}
7785

7886
/**
@@ -94,99 +102,27 @@ public function apply(Select $select, $stockValues, $type, $showOutOfStockFlag)
94102
$select = clone $select;
95103
$mainTableAlias = $this->extractTableAliasFromSelect($select);
96104

97-
$this->addMainStockStatusJoin($select, $stockValues, $mainTableAlias, $showOutOfStockFlag);
105+
$select = $this->stockStatusQueryBuilder->apply(
106+
$select,
107+
$mainTableAlias,
108+
'stock_index',
109+
'entity_id',
110+
$showOutOfStockFlag ? null : $stockValues
111+
);
98112

99113
if ($type === self::FILTER_ENTITY_AND_SUB_PRODUCTS) {
100-
$this->addSubProductsStockStatusJoin($select, $stockValues, $mainTableAlias, $showOutOfStockFlag);
114+
$select = $this->stockStatusQueryBuilder->apply(
115+
$select,
116+
$mainTableAlias,
117+
'sub_products_stock_index',
118+
'source_id',
119+
$showOutOfStockFlag ? null : $stockValues
120+
);
101121
}
102122

103123
return $select;
104124
}
105125

106-
/**
107-
* Adds filter join for products by stock status
108-
* In case when $showOutOfStockFlag is true - joins are still required to filter only enabled products
109-
*
110-
* @param Select $select
111-
* @param array|int $stockValues
112-
* @param string $mainTableAlias
113-
* @param bool $showOutOfStockFlag
114-
* @return void
115-
*/
116-
private function addMainStockStatusJoin(Select $select, $stockValues, $mainTableAlias, $showOutOfStockFlag)
117-
{
118-
$catalogInventoryTable = $this->resourceConnection->getTableName('cataloginventory_stock_status');
119-
$select->joinInner(
120-
['stock_index' => $catalogInventoryTable],
121-
$this->conditionManager->combineQueries(
122-
[
123-
sprintf('stock_index.product_id = %s.entity_id', $mainTableAlias),
124-
$this->conditionManager->generateCondition(
125-
'stock_index.website_id',
126-
'=',
127-
$this->stockConfiguration->getDefaultScopeId()
128-
),
129-
$showOutOfStockFlag
130-
? ''
131-
: $this->conditionManager->generateCondition(
132-
'stock_index.stock_status',
133-
is_array($stockValues) ? 'in' : '=',
134-
$stockValues
135-
),
136-
$this->conditionManager->generateCondition(
137-
'stock_index.stock_id',
138-
'=',
139-
(int) $this->stockRegistry->getStock()->getStockId()
140-
),
141-
],
142-
Select::SQL_AND
143-
),
144-
[]
145-
);
146-
}
147-
148-
/**
149-
* Adds filter join for sub products by stock status
150-
* In case when $showOutOfStockFlag is true - joins are still required to filter only enabled products
151-
*
152-
* @param Select $select
153-
* @param array|int $stockValues
154-
* @param string $mainTableAlias
155-
* @param bool $showOutOfStockFlag
156-
* @return void
157-
*/
158-
private function addSubProductsStockStatusJoin(Select $select, $stockValues, $mainTableAlias, $showOutOfStockFlag)
159-
{
160-
$catalogInventoryTable = $this->resourceConnection->getTableName('cataloginventory_stock_status');
161-
$select->joinInner(
162-
['sub_products_stock_index' => $catalogInventoryTable],
163-
$this->conditionManager->combineQueries(
164-
[
165-
sprintf('sub_products_stock_index.product_id = %s.source_id', $mainTableAlias),
166-
$this->conditionManager->generateCondition(
167-
'sub_products_stock_index.website_id',
168-
'=',
169-
$this->stockConfiguration->getDefaultScopeId()
170-
),
171-
$showOutOfStockFlag
172-
? ''
173-
: $this->conditionManager->generateCondition(
174-
'sub_products_stock_index.stock_status',
175-
is_array($stockValues) ? 'in' : '=',
176-
$stockValues
177-
),
178-
$this->conditionManager->generateCondition(
179-
'sub_products_stock_index.stock_id',
180-
'=',
181-
(int) $this->stockRegistry->getStock()->getStockId()
182-
),
183-
],
184-
Select::SQL_AND
185-
),
186-
[]
187-
);
188-
}
189-
190126
/**
191127
* Extracts alias for table that is used in FROM clause in Select
192128
*

0 commit comments

Comments
 (0)