Skip to content

Commit bd322e0

Browse files
committed
Merge branch 'MC-42545' of https://github.com/magento-l3/magento2ce into PR-2021-08-18
2 parents 54aefb0 + 847ca8e commit bd322e0

File tree

11 files changed

+148
-36
lines changed

11 files changed

+148
-36
lines changed

app/code/Magento/CatalogGraphQl/etc/search_request.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@
5454
<metrics>
5555
<metric type="count"/>
5656
</metrics>
57+
<parameters>
58+
<parameter name="include" value="$category_ids_to_aggregate$"/>
59+
</parameters>
5760
</bucket>
5861
</aggregations>
5962
<from>0</from>

app/code/Magento/CatalogSearch/Model/Layer/Filter/Category.php

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,18 +65,31 @@ public function __construct(
6565
public function apply(\Magento\Framework\App\RequestInterface $request)
6666
{
6767
$categoryId = $request->getParam($this->_requestVar) ?: $request->getParam('id');
68-
if (empty($categoryId)) {
69-
return $this;
70-
}
68+
if (!empty($categoryId)) {
69+
$this->dataProvider->setCategoryId($categoryId);
7170

72-
$this->dataProvider->setCategoryId($categoryId);
71+
$category = $this->dataProvider->getCategory();
7372

74-
$category = $this->dataProvider->getCategory();
73+
$this->getLayer()->getProductCollection()->addCategoryFilter($category);
7574

76-
$this->getLayer()->getProductCollection()->addCategoryFilter($category);
75+
if ($request->getParam('id') != $category->getId() && $this->dataProvider->isValid()) {
76+
$this->getLayer()->getState()->addFilter($this->_createItem($category->getName(), $categoryId));
77+
}
78+
}
7779

78-
if ($request->getParam('id') != $category->getId() && $this->dataProvider->isValid()) {
79-
$this->getLayer()->getState()->addFilter($this->_createItem($category->getName(), $categoryId));
80+
$category = $this->dataProvider->getCategory();
81+
if ($category) {
82+
$childrenCategoryIds = [];
83+
foreach ($category->getChildrenCategories() as $category) {
84+
$childrenCategoryIds[] = $category->getId();
85+
}
86+
if ($childrenCategoryIds) {
87+
$this->getLayer()->getProductCollection()
88+
->addFieldToFilter(
89+
'category_ids_to_aggregate',
90+
$childrenCategoryIds
91+
);
92+
}
8093
}
8194
return $this;
8295
}

app/code/Magento/CatalogSearch/Test/Unit/Model/Layer/Filter/CategoryTest.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,10 @@ public function testApplyWithEmptyRequest($requestValue, $idValue)
163163

164164
$this->target->setRequestVar($requestField);
165165

166+
$this->category->expects($this->once())
167+
->method('getChildrenCategories')
168+
->willReturn([]);
169+
166170
$this->request->expects($this->at(0))
167171
->method('getParam')
168172
->with($requestField)
@@ -225,6 +229,10 @@ function ($field) use ($requestVar, $categoryId) {
225229
->method('getId')
226230
->willReturn($categoryId);
227231

232+
$this->category->expects($this->once())
233+
->method('getChildrenCategories')
234+
->willReturn([]);
235+
228236
$this->fulltextCollection->expects($this->once())
229237
->method('addCategoryFilter')
230238
->with($this->category)->willReturnSelf();

app/code/Magento/CatalogSearch/etc/search_request.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@
5252
<metrics>
5353
<metric type="count"/>
5454
</metrics>
55+
<parameters>
56+
<parameter name="include" value="$category_ids_to_aggregate$"/>
57+
</parameters>
5558
</bucket>
5659
</aggregations>
5760
<from>0</from>
@@ -125,6 +128,9 @@
125128
<metrics>
126129
<metric type="count"/>
127130
</metrics>
131+
<parameters>
132+
<parameter name="include" value="$category_ids_to_aggregate$"/>
133+
</parameters>
128134
</bucket>
129135
</aggregations>
130136
<from>0</from>

app/code/Magento/Elasticsearch/SearchAdapter/Query/Builder/Aggregation.php

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,13 @@ protected function buildBucket(
7373
switch ($bucket->getType()) {
7474
case BucketInterface::TYPE_TERM:
7575
$searchQuery['body']['aggregations'][$bucket->getName()]= [
76-
'terms' => [
77-
'field' => $field,
78-
'size' => self::$maxTermBacketSize,
79-
],
76+
'terms' => array_merge(
77+
$bucket->getParameters(),
78+
[
79+
'field' => $field,
80+
'size' => self::$maxTermBacketSize,
81+
]
82+
),
8083
];
8184
break;
8285
case BucketInterface::TYPE_DYNAMIC:

app/code/Magento/Elasticsearch/Test/Unit/SearchAdapter/Query/Builder/AggregationTest.php

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

1010
use Magento\Elasticsearch\Model\Adapter\FieldMapperInterface;
1111
use Magento\Elasticsearch\SearchAdapter\Query\Builder\Aggregation;
12+
use Magento\Framework\Search\Request\Aggregation\TermBucket;
1213
use Magento\Framework\Search\Request\BucketInterface;
1314
use Magento\Framework\Search\RequestInterface;
1415
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
@@ -146,28 +147,22 @@ public function testBuildTerm()
146147
'type' => 'product',
147148
'body' => [],
148149
];
149-
$bucketName = 'price_bucket';
150+
$bucketName = 'category_bucket';
151+
152+
$requestBucketInterface = new TermBucket(
153+
$bucketName,
154+
'category_ids',
155+
[]
156+
);
150157

151158
$this->requestInterface
152159
->method('getAggregation')
153-
->willReturn([$this->requestBucketInterface]);
160+
->willReturn([$requestBucketInterface]);
154161

155162
$this->fieldMapper
156163
->method('getFieldName')
157164
->willReturn('price');
158165

159-
$this->requestBucketInterface
160-
->method('getField')
161-
->willReturn('price');
162-
163-
$this->requestBucketInterface
164-
->method('getType')
165-
->willReturn(BucketInterface::TYPE_TERM);
166-
167-
$this->requestBucketInterface
168-
->method('getName')
169-
->willReturn($bucketName);
170-
171166
$result = $this->model->build($this->requestInterface, $query);
172167

173168
$this->assertNotNull($result);

dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Layer/Filter/CategoryTest.php

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,10 @@ public function testApplyNothing()
6666
\Magento\Framework\View\Element\Text::class
6767
)
6868
);
69-
/** @var $objectManager \Magento\TestFramework\ObjectManager */
70-
$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
71-
$this->assertNull(
72-
$objectManager->get(\Magento\Framework\Registry::class)->registry(self::CURRENT_CATEGORY_FILTER)
73-
);
69+
/** @var $category \Magento\Catalog\Model\Category */
70+
$category = $objectManager->get(\Magento\Framework\Registry::class)->registry(self::CURRENT_CATEGORY_FILTER);
71+
$this->assertInstanceOf(\Magento\Catalog\Model\Category::class, $category);
72+
$this->assertEquals($this->_category->getId(), $category->getId());
7473
}
7574

7675
public function testApply()
@@ -135,4 +134,35 @@ public function testGetItems()
135134
$this->assertEquals(13, $item->getValue());
136135
$this->assertEquals(2, $item->getCount());
137136
}
137+
138+
/**
139+
* Check that only children category of current category are aggregated
140+
*
141+
* @magentoDbIsolation disabled
142+
*/
143+
public function testCategoryAggregation(): void
144+
{
145+
$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
146+
$request = $objectManager->get(\Magento\TestFramework\Request::class);
147+
$request->setParam('cat', 3);
148+
$this->_model->apply($request);
149+
150+
/** @var $category \Magento\Catalog\Model\Category */
151+
$category = $objectManager->get(\Magento\Framework\Registry::class)->registry(self::CURRENT_CATEGORY_FILTER);
152+
$this->assertInstanceOf(\Magento\Catalog\Model\Category::class, $category);
153+
$this->assertEquals(3, $category->getId());
154+
$metrics = $this->_model->getLayer()->getProductCollection()->getFacetedData('category');
155+
$this->assertIsArray($metrics);
156+
$actual = [];
157+
foreach ($metrics as $categoryId => $metric) {
158+
$actual[$categoryId] = $metric['count'];
159+
}
160+
$this->assertEquals(
161+
[
162+
4 => 2,
163+
13 => 2
164+
],
165+
$actual
166+
);
167+
}
138168
}

lib/internal/Magento/Framework/Search/Request/Aggregation/TermBucket.php

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,28 @@ class TermBucket implements BucketInterface
2727
*/
2828
protected $metrics;
2929

30+
/**
31+
* @var array
32+
*/
33+
private $parameters;
34+
3035
/**
3136
* @param string $name
3237
* @param string $field
3338
* @param array $metrics
39+
* @param array $parameters
3440
* @codeCoverageIgnore
3541
*/
36-
public function __construct($name, $field, array $metrics)
37-
{
42+
public function __construct(
43+
$name,
44+
$field,
45+
array $metrics,
46+
array $parameters = []
47+
) {
3848
$this->name = $name;
3949
$this->field = $field;
4050
$this->metrics = $metrics;
51+
$this->parameters = $parameters;
4152
}
4253

4354
/**
@@ -74,4 +85,12 @@ public function getMetrics()
7485
{
7586
return $this->metrics;
7687
}
88+
89+
/**
90+
* @return array
91+
*/
92+
public function getParameters(): array
93+
{
94+
return $this->parameters;
95+
}
7796
}

lib/internal/Magento/Framework/Search/Request/Cleaner.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,16 @@ private function cleanAggregations()
140140
if (array_key_exists('aggregations', $this->requestData) && is_array($this->requestData['aggregations'])) {
141141
foreach ($this->requestData['aggregations'] as $aggregationName => $aggregationValue) {
142142
switch ($aggregationValue['type']) {
143-
case 'dynamicBucket':
143+
case BucketInterface::TYPE_TERM:
144+
foreach ($aggregationValue['parameter'] ?? [] as $key => $parameter) {
145+
if (is_string($parameter['value'])
146+
&& preg_match('/^\$(.+)\$$/si', $parameter['value'])
147+
) {
148+
unset($this->requestData['aggregations'][$aggregationName]['parameter'][$key]);
149+
}
150+
}
151+
break;
152+
case BucketInterface::TYPE_DYNAMIC:
144153
if (is_string($aggregationValue['method'])
145154
&& preg_match('/^\$(.+)\$$/si', $aggregationValue['method'])
146155
) {

lib/internal/Magento/Framework/Search/Request/Mapper.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,12 @@ public function getBuckets()
334334
case BucketInterface::TYPE_TERM:
335335
$bucket = $this->objectManager->create(
336336
\Magento\Framework\Search\Request\Aggregation\TermBucket::class,
337-
$arguments
337+
array_merge(
338+
$arguments,
339+
[
340+
'parameters' => array_column($bucketData['parameter'] ?? [], 'value', 'name'),
341+
],
342+
)
338343
);
339344
break;
340345
case BucketInterface::TYPE_RANGE:

lib/internal/Magento/Framework/Search/etc/requests.xsd

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,15 @@
193193
<xs:complexType name="termBucket">
194194
<xs:complexContent>
195195
<xs:extension base="bucket">
196-
</xs:extension>
196+
<xs:sequence>
197+
<xs:element type="bucketParameters" name="parameters" minOccurs="0" maxOccurs="1" >
198+
<xs:key name="bucketParameterName">
199+
<xs:selector xpath="parameter" />
200+
<xs:field xpath="@name" />
201+
</xs:key>
202+
</xs:element>
203+
</xs:sequence>
204+
</xs:extension>
197205
</xs:complexContent>
198206
</xs:complexType>
199207

@@ -220,6 +228,11 @@
220228
<xs:element type="metric" name="metric" maxOccurs="unbounded" minOccurs="0" />
221229
</xs:sequence>
222230
</xs:complexType>
231+
<xs:complexType name="bucketParameters">
232+
<xs:sequence>
233+
<xs:element type="bucketParameter" name="parameter" maxOccurs="unbounded" minOccurs="0" />
234+
</xs:sequence>
235+
</xs:complexType>
223236

224237
<xs:complexType name="match">
225238
<xs:simpleContent>
@@ -271,6 +284,14 @@
271284
</xs:extension>
272285
</xs:simpleContent>
273286
</xs:complexType>
287+
<xs:complexType name="bucketParameter">
288+
<xs:simpleContent>
289+
<xs:extension base="xs:string">
290+
<xs:attribute type="xs:string" name="name" use="required" />
291+
<xs:attribute type="xs:string" name="value" use="required" />
292+
</xs:extension>
293+
</xs:simpleContent>
294+
</xs:complexType>
274295

275296
<xs:complexType name="ranges">
276297
<xs:sequence>

0 commit comments

Comments
 (0)