-
Notifications
You must be signed in to change notification settings - Fork 9.4k
[Backport] magento/magento2#9961: Unused product attributes display with value N/A or NO on storefront. #12057
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
c2a2450
a5c064a
3473c1c
b3cbda2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -85,13 +85,15 @@ public function getAdditionalData(array $excludeAttr = []) | |
|
||
if (!$product->hasData($attribute->getAttributeCode())) { | ||
$value = __('N/A'); | ||
} elseif ($value instanceof Phrase) { | ||
$value = (string)$value; | ||
} elseif ((string)$value == '') { | ||
$value = __('No'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is weird logic. Why empty string should be transformed to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Most likely this was used to display boolean attributes with Yes/No values. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @orlangur Yes/No values at this point already handled in |
||
} elseif ($attribute->getFrontendInput() == 'price' && is_string($value)) { | ||
$value = $this->priceCurrency->convertAndFormat($value); | ||
} | ||
|
||
if ($value instanceof Phrase || (is_string($value) && strlen($value))) { | ||
if (is_string($value) && strlen($value)) { | ||
$data[$attribute->getAttributeCode()] = [ | ||
'label' => __($attribute->getStoreLabel()), | ||
'value' => $value, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
<?php | ||
/** | ||
* Copyright © Magento, Inc. All rights reserved. | ||
* See COPYING.txt for license details. | ||
*/ | ||
|
||
namespace Magento\Catalog\Test\Unit\Block\Product\View; | ||
|
||
use \PHPUnit\Framework\TestCase; | ||
use \Magento\Framework\Phrase; | ||
use \Magento\Eav\Model\Entity\Attribute\AbstractAttribute; | ||
use \Magento\Eav\Model\Entity\Attribute\Frontend\AbstractFrontend; | ||
use \Magento\Catalog\Model\Product; | ||
use \Magento\Framework\View\Element\Template\Context; | ||
use \Magento\Framework\Registry; | ||
use \Magento\Framework\Pricing\PriceCurrencyInterface; | ||
use \Magento\Catalog\Block\Product\View\Attributes as AttributesBlock; | ||
|
||
/** | ||
* Test class for \Magento\Catalog\Block\Product\View\Attributes | ||
* | ||
* @SuppressWarnings(PHPMD.CouplingBetweenObjects) | ||
*/ | ||
class AttributesTest extends TestCase | ||
{ | ||
/** | ||
* @var \Magento\Framework\Phrase | ||
*/ | ||
private $phrase; | ||
|
||
/** | ||
* @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Eav\Model\Entity\Attribute\AbstractAttribute | ||
*/ | ||
private $attribute; | ||
|
||
/** | ||
* @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Eav\Model\Entity\Attribute\Frontend\AbstractFrontend | ||
*/ | ||
private $frontendAttribute; | ||
|
||
/** | ||
* @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Catalog\Model\Product | ||
*/ | ||
private $product; | ||
|
||
/** | ||
* @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\View\Element\Template\Context | ||
*/ | ||
private $context; | ||
|
||
/** | ||
* @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Registry | ||
*/ | ||
private $registry; | ||
|
||
/** | ||
* @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Pricing\PriceCurrencyInterface | ||
*/ | ||
private $priceCurrencyInterface; | ||
|
||
/** | ||
* @var \Magento\Catalog\Block\Product\View\Attributes | ||
*/ | ||
private $attributesBlock; | ||
|
||
protected function setUp() | ||
{ | ||
// @codingStandardsIgnoreStart | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we get rid of such annotations? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removed them. |
||
$this->phrase = new Phrase(__('')); | ||
// @codingStandardsIgnoreEnd | ||
$this->attribute = $this | ||
->getMockBuilder(AbstractAttribute::class) | ||
->disableOriginalConstructor() | ||
->getMock(); | ||
$this->attribute | ||
->expects($this->any()) | ||
->method('getIsVisibleOnFront') | ||
->willReturn(true); | ||
$this->attribute | ||
->expects($this->any()) | ||
->method('getAttributeCode') | ||
->willReturn('phrase'); | ||
$this->frontendAttribute = $this | ||
->getMockBuilder(AbstractFrontend::class) | ||
->disableOriginalConstructor() | ||
->getMock(); | ||
$this->attribute | ||
->expects($this->any()) | ||
->method('getFrontendInput') | ||
->willReturn('phrase'); | ||
$this->attribute | ||
->expects($this->any()) | ||
->method('getFrontend') | ||
->willReturn($this->frontendAttribute); | ||
$this->product = $this | ||
->getMockBuilder(Product::class) | ||
->disableOriginalConstructor() | ||
->getMock(); | ||
$this->product | ||
->expects($this->any()) | ||
->method('getAttributes') | ||
->willReturn([$this->attribute]); | ||
$this->product | ||
->expects($this->any()) | ||
->method('hasData') | ||
->willReturn(true); | ||
$this->context = $this | ||
->getMockBuilder(Context::class) | ||
->disableOriginalConstructor() | ||
->getMock(); | ||
$this->registry = $this | ||
->getMockBuilder(Registry::class) | ||
->disableOriginalConstructor() | ||
->getMock(); | ||
$this->registry | ||
->expects($this->any()) | ||
->method('registry') | ||
->willReturn($this->product); | ||
$this->priceCurrencyInterface = $this | ||
->getMockBuilder(PriceCurrencyInterface::class) | ||
->disableOriginalConstructor() | ||
->getMock(); | ||
$this->attributesBlock = new AttributesBlock( | ||
$this->context, | ||
$this->registry, | ||
$this->priceCurrencyInterface | ||
); | ||
} | ||
|
||
/** | ||
* @return void | ||
*/ | ||
public function testGetAttributeNoValue() | ||
{ | ||
// @codingStandardsIgnoreStart | ||
$this->phrase = new Phrase(__('')); | ||
// @codingStandardsIgnoreEnd | ||
$this->frontendAttribute | ||
->expects($this->any()) | ||
->method('getValue') | ||
->willReturn($this->phrase); | ||
$attributes = $this->attributesBlock->getAdditionalData(); | ||
$this->assertTrue(empty($attributes['phrase'])); | ||
} | ||
|
||
/** | ||
* @return void | ||
*/ | ||
public function testGetAttributeHasValue() | ||
{ | ||
$this->phrase = new Phrase(__('Yes')); | ||
$this->frontendAttribute | ||
->expects($this->any()) | ||
->method('getValue') | ||
->willReturn($this->phrase); | ||
$attributes = $this->attributesBlock->getAdditionalData(); | ||
$this->assertNotTrue(empty($attributes['phrase'])); | ||
$this->assertNotTrue(empty($attributes['phrase']['value'])); | ||
$this->assertEquals('Yes', $attributes['phrase']['value']); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we also should remove this code as there are a lot of complaints about such behavior. This code was "dead" for a long time so everyone expects that not used attribute is ignored on storefront.
Please remove this
if
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we change system behavior in a way desired by Community without PO approval?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, behavior was changed when
instanceof Phrase
was added toif
below. I can see that__('N/A')
code was dead for a long time (including M1) so expectations in most Magento versions not used attributes are not displayed on a storefornt product page. Support also has multiple tickets to return previous behavior (not show N/A) back.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I wan't aware about M1, and yes, such useful behavior was introduced accidentally in scope of another bugfix.