Skip to content

Commit 9f57148

Browse files
MC-16650: Product Attribute Type Price Not Displaying
- use a different request generator for price, fix tests, and code
1 parent d9c3e7b commit 9f57148

File tree

8 files changed

+150
-46
lines changed

8 files changed

+150
-46
lines changed

app/code/Magento/Catalog/Model/Layer/FilterList.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77

88
namespace Magento\Catalog\Model\Layer;
99

10-
use Magento\Catalog\Model\Product\Attribute\Backend\Price;
11-
1210
/**
1311
* Layer navigation filters
1412
*/
@@ -112,7 +110,7 @@ protected function getAttributeFilterClass(\Magento\Catalog\Model\ResourceModel\
112110
{
113111
$filterClassName = $this->filterTypes[self::ATTRIBUTE_FILTER];
114112

115-
if ($attribute->getBackendModel() === Price::class) {
113+
if ($attribute->getFrontendInput() === 'price') {
116114
$filterClassName = $this->filterTypes[self::PRICE_FILTER];
117115
} elseif ($attribute->getBackendType() === 'decimal') {
118116
$filterClassName = $this->filterTypes[self::DECIMAL_FILTER];

app/code/Magento/Catalog/Test/Unit/Model/Layer/FilterListTest.php

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
namespace Magento\Catalog\Test\Unit\Model\Layer;
99

1010
use \Magento\Catalog\Model\Layer\FilterList;
11-
use Magento\Catalog\Model\Product\Attribute\Backend\Price;
1211

1312
class FilterListTest extends \PHPUnit\Framework\TestCase
1413
{
@@ -97,8 +96,8 @@ public function getFiltersDataProvider()
9796
{
9897
return [
9998
[
100-
'method' => 'getBackendModel',
101-
'value' => Price::class,
99+
'method' => 'getFrontendInput',
100+
'value' => 'price',
102101
'expectedClass' => 'PriceFilterClass',
103102
],
104103
[
@@ -107,8 +106,8 @@ public function getFiltersDataProvider()
107106
'expectedClass' => 'DecimalFilterClass',
108107
],
109108
[
110-
'method' => 'getBackendModel',
111-
'value' => null,
109+
'method' => 'getFrontendInput',
110+
'value' => 'text',
112111
'expectedClass' => 'AttributeFilterClass',
113112
]
114113
];

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

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,17 @@ public function apply(\Magento\Framework\App\RequestInterface $request)
7272

7373
list($from, $to) = explode('-', $filter);
7474

75+
// When the range is 10-20 we only need to get products that are in the 10-19.99 range.
76+
$toValue = $to;
77+
if (!empty($toValue) && $from !== $toValue) {
78+
$toValue -= 0.001;
79+
}
80+
7581
$this->getLayer()
7682
->getProductCollection()
7783
->addFieldToFilter(
7884
$this->getAttributeModel()->getAttributeCode(),
79-
['from' => $from, 'to' => $this->getToRangeValue($from, $to)]
85+
['from' => $from, 'to' => $toValue]
8086
);
8187

8288
$this->getLayer()->getState()->addFilter(
@@ -149,23 +155,4 @@ protected function renderRangeLabel($fromPrice, $toPrice)
149155
return __('%1 - %2', $formattedFromPrice, $this->priceCurrency->format($toPrice));
150156
}
151157
}
152-
153-
/**
154-
* Get the to range value
155-
*
156-
* When the range is 10-20 we only need to get products that are in the 10-19.99 range.
157-
* 20 should be in the next range group.
158-
*
159-
* @param float|string $from
160-
* @param float|string $to
161-
* @return float|string
162-
*/
163-
private function getToRangeValue($from, $to)
164-
{
165-
if (!empty($to) && $from !== $to) {
166-
$to -= 0.001;
167-
}
168-
169-
return $to;
170-
}
171158
}

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
declare(strict_types=1);
7+
68
namespace Magento\CatalogSearch\Model\Search;
79

810
use Magento\Catalog\Api\Data\EavAttributeInterface;
@@ -78,6 +80,7 @@ private function generateRequest($attributeType, $container, $useFulltext)
7880
{
7981
$request = [];
8082
foreach ($this->getSearchableAttributes() as $attribute) {
83+
/** @var $attribute Attribute */
8184
if ($attribute->getData($attributeType)) {
8285
if (!in_array($attribute->getAttributeCode(), ['price', 'category_ids'], true)) {
8386
$queryName = $attribute->getAttributeCode() . '_query';
@@ -97,12 +100,14 @@ private function generateRequest($attributeType, $container, $useFulltext)
97100
],
98101
];
99102
$bucketName = $attribute->getAttributeCode() . self::BUCKET_SUFFIX;
100-
$generator = $this->generatorResolver->getGeneratorForType($attribute->getBackendType());
103+
$generatorType = $attribute->getFrontendInput() === 'price'
104+
? $attribute->getFrontendInput()
105+
: $attribute->getBackendType();
106+
$generator = $this->generatorResolver->getGeneratorForType($generatorType);
101107
$request['filters'][$filterName] = $generator->getFilterData($attribute, $filterName);
102108
$request['aggregations'][$bucketName] = $generator->getAggregationData($attribute, $bucketName);
103109
}
104110
}
105-
/** @var $attribute Attribute */
106111
if (!$attribute->getIsSearchable() || in_array($attribute->getAttributeCode(), ['price', 'sku'], true)) {
107112
// Some fields have their own specific handlers
108113
continue;
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
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\RequestGenerator;
9+
10+
use Magento\Catalog\Model\ResourceModel\Eav\Attribute;
11+
use Magento\Framework\Search\Request\BucketInterface;
12+
use Magento\Framework\Search\Request\FilterInterface;
13+
14+
/**
15+
* Catalog search range request generator.
16+
*/
17+
class Price implements GeneratorInterface
18+
{
19+
/**
20+
* @inheritdoc
21+
*/
22+
public function getFilterData(Attribute $attribute, $filterName)
23+
{
24+
return [
25+
'type' => FilterInterface::TYPE_RANGE,
26+
'name' => $filterName,
27+
'field' => $attribute->getAttributeCode(),
28+
'from' => '$' . $attribute->getAttributeCode() . '.from$',
29+
'to' => '$' . $attribute->getAttributeCode() . '.to$',
30+
];
31+
}
32+
33+
/**
34+
* @inheritdoc
35+
*/
36+
public function getAggregationData(Attribute $attribute, $bucketName)
37+
{
38+
return [
39+
'type' => BucketInterface::TYPE_DYNAMIC,
40+
'name' => $bucketName,
41+
'field' => $attribute->getAttributeCode(),
42+
'method' => '$price_dynamic_algorithm$',
43+
'metric' => [['type' => 'count']],
44+
];
45+
}
46+
}

app/code/Magento/CatalogSearch/Test/Unit/Model/Search/RequestGenerator/DecimalTest.php

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
use Magento\CatalogSearch\Model\Search\RequestGenerator\Decimal;
1212
use Magento\Framework\Search\Request\BucketInterface;
1313
use Magento\Framework\Search\Request\FilterInterface;
14-
use Magento\Framework\App\Config\ScopeConfigInterface;
1514

1615
/**
1716
* Test catalog search range request generator.
@@ -24,23 +23,14 @@ class DecimalTest extends \PHPUnit\Framework\TestCase
2423
/** @var Attribute|\PHPUnit_Framework_MockObject_MockObject */
2524
private $attribute;
2625

27-
/** @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject */
28-
private $scopeConfigMock;
29-
3026
protected function setUp()
3127
{
3228
$this->attribute = $this->getMockBuilder(Attribute::class)
3329
->disableOriginalConstructor()
3430
->setMethods(['getAttributeCode'])
3531
->getMockForAbstractClass();
36-
$this->scopeConfigMock = $this->getMockBuilder(ScopeConfigInterface::class)
37-
->setMethods(['getValue'])
38-
->getMockForAbstractClass();
3932
$objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
40-
$this->decimal = $objectManager->getObject(
41-
Decimal::class,
42-
['scopeConfig' => $this->scopeConfigMock]
43-
);
33+
$this->decimal = $objectManager->getObject(Decimal::class);
4434
}
4535

4636
public function testGetFilterData()
@@ -65,20 +55,16 @@ public function testGetAggregationData()
6555
{
6656
$bucketName = 'test_bucket_name';
6757
$attributeCode = 'test_attribute_code';
68-
$method = 'manual';
6958
$expected = [
7059
'type' => BucketInterface::TYPE_DYNAMIC,
7160
'name' => $bucketName,
7261
'field' => $attributeCode,
73-
'method' => $method,
62+
'method' => 'manual',
7463
'metric' => [['type' => 'count']],
7564
];
7665
$this->attribute->expects($this->atLeastOnce())
7766
->method('getAttributeCode')
7867
->willReturn($attributeCode);
79-
$this->scopeConfigMock->expects($this->once())
80-
->method('getValue')
81-
->willReturn($method);
8268
$actual = $this->decimal->getAggregationData($this->attribute, $bucketName);
8369
$this->assertEquals($expected, $actual);
8470
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
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\Test\Unit\Model\Search\RequestGenerator;
9+
10+
use Magento\Catalog\Model\ResourceModel\Eav\Attribute;
11+
use Magento\CatalogSearch\Model\Search\RequestGenerator\Price;
12+
use Magento\Framework\Search\Request\BucketInterface;
13+
use Magento\Framework\Search\Request\FilterInterface;
14+
use Magento\Framework\App\Config\ScopeConfigInterface;
15+
16+
/**
17+
* Test catalog search range request generator.
18+
*/
19+
class PriceTest extends \PHPUnit\Framework\TestCase
20+
{
21+
/** @var Price */
22+
private $price;
23+
24+
/** @var Attribute|\PHPUnit_Framework_MockObject_MockObject */
25+
private $attribute;
26+
27+
/** @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject */
28+
private $scopeConfigMock;
29+
30+
protected function setUp()
31+
{
32+
$this->attribute = $this->getMockBuilder(Attribute::class)
33+
->disableOriginalConstructor()
34+
->setMethods(['getAttributeCode'])
35+
->getMockForAbstractClass();
36+
$this->scopeConfigMock = $this->getMockBuilder(ScopeConfigInterface::class)
37+
->setMethods(['getValue'])
38+
->getMockForAbstractClass();
39+
$objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
40+
$this->price = $objectManager->getObject(
41+
Price::class,
42+
['scopeConfig' => $this->scopeConfigMock]
43+
);
44+
}
45+
46+
public function testGetFilterData()
47+
{
48+
$filterName = 'test_filter_name';
49+
$attributeCode = 'test_attribute_code';
50+
$expected = [
51+
'type' => FilterInterface::TYPE_RANGE,
52+
'name' => $filterName,
53+
'field' => $attributeCode,
54+
'from' => '$' . $attributeCode . '.from$',
55+
'to' => '$' . $attributeCode . '.to$',
56+
];
57+
$this->attribute->expects($this->atLeastOnce())
58+
->method('getAttributeCode')
59+
->willReturn($attributeCode);
60+
$actual = $this->price->getFilterData($this->attribute, $filterName);
61+
$this->assertEquals($expected, $actual);
62+
}
63+
64+
public function testGetAggregationData()
65+
{
66+
$bucketName = 'test_bucket_name';
67+
$attributeCode = 'test_attribute_code';
68+
$method = 'price_dynamic_algorithm';
69+
$expected = [
70+
'type' => BucketInterface::TYPE_DYNAMIC,
71+
'name' => $bucketName,
72+
'field' => $attributeCode,
73+
'method' => '$'. $method . '$',
74+
'metric' => [['type' => 'count']],
75+
];
76+
$this->attribute->expects($this->atLeastOnce())
77+
->method('getAttributeCode')
78+
->willReturn($attributeCode);
79+
$actual = $this->price->getAggregationData($this->attribute, $bucketName);
80+
$this->assertEquals($expected, $actual);
81+
}
82+
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,7 @@
279279
<argument name="defaultGenerator" xsi:type="object">\Magento\CatalogSearch\Model\Search\RequestGenerator\General</argument>
280280
<argument name="generators" xsi:type="array">
281281
<item name="decimal" xsi:type="object">Magento\CatalogSearch\Model\Search\RequestGenerator\Decimal</item>
282+
<item name="price" xsi:type="object">Magento\CatalogSearch\Model\Search\RequestGenerator\Price</item>
282283
</argument>
283284
</arguments>
284285
</type>

0 commit comments

Comments
 (0)