Skip to content

Commit b4bbe21

Browse files
author
Oleksii Korshenko
authored
Merge pull request #1791 from magento-engcom/2.2-develop-prs
Public Pull Requests #12495 Fixed invalid parameter type in phpdoc block in Topmenu class by @vovayatsyuk magento-engcom#904 9468: REST API bundle-products/:sku/options/all always return is not authorized by @RomaKis #12443 Fixed missing 'size' and 'type' props on a third-party category images [Backport 2.2] by @vovayatsyuk #12441 Add command "app:config:status" to check if "app:config:import" needed by @jalogut #12057 [Backport] #9961: Unused product attributes display with value N/A or NO on storefront. by @p-bystritsky Fixed Public Issues #9468 REST API bundle-products/:sku/options/all always return is not authorized #6634 Yes/No attribute value is not shown on a product details page #9961 Unused product attributes display with value N/A or NO on storefront
2 parents 24e11b9 + e4a5038 commit b4bbe21

File tree

8 files changed

+310
-11
lines changed

8 files changed

+310
-11
lines changed

app/code/Magento/Catalog/Block/Product/View/Attributes.php

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -81,17 +81,15 @@ public function getAdditionalData(array $excludeAttr = [])
8181
$attributes = $product->getAttributes();
8282
foreach ($attributes as $attribute) {
8383
if ($attribute->getIsVisibleOnFront() && !in_array($attribute->getAttributeCode(), $excludeAttr)) {
84-
if (is_array($value = $attribute->getFrontend()->getValue($product))) {
85-
continue;
86-
}
87-
if (!$product->hasData($attribute->getAttributeCode())) {
88-
$value = __('N/A');
89-
} elseif ((string)$value == '') {
90-
$value = __('No');
84+
$value = $attribute->getFrontend()->getValue($product);
85+
86+
if ($value instanceof Phrase) {
87+
$value = (string)$value;
9188
} elseif ($attribute->getFrontendInput() == 'price' && is_string($value)) {
9289
$value = $this->priceCurrency->convertAndFormat($value);
9390
}
94-
if ($value instanceof Phrase || (is_string($value) && strlen($value))) {
91+
92+
if (is_string($value) && strlen($value)) {
9593
$data[$attribute->getAttributeCode()] = [
9694
'label' => __($attribute->getStoreLabel()),
9795
'value' => $value,

app/code/Magento/Catalog/Model/Category/DataProvider.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -494,8 +494,8 @@ private function convertValues($category, $categoryData)
494494

495495
$categoryData[$attributeCode][0]['name'] = $fileName;
496496
$categoryData[$attributeCode][0]['url'] = $category->getImageUrl($attributeCode);
497-
$categoryData['image'][0]['size'] = isset($stat) ? $stat['size'] : 0;
498-
$categoryData['image'][0]['type'] = $mime;
497+
$categoryData[$attributeCode][0]['size'] = isset($stat) ? $stat['size'] : 0;
498+
$categoryData[$attributeCode][0]['type'] = $mime;
499499
}
500500
}
501501
}
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\Catalog\Test\Unit\Block\Product\View;
8+
9+
use \PHPUnit\Framework\TestCase;
10+
use \Magento\Framework\Phrase;
11+
use \Magento\Eav\Model\Entity\Attribute\AbstractAttribute;
12+
use \Magento\Eav\Model\Entity\Attribute\Frontend\AbstractFrontend;
13+
use \Magento\Catalog\Model\Product;
14+
use \Magento\Framework\View\Element\Template\Context;
15+
use \Magento\Framework\Registry;
16+
use \Magento\Framework\Pricing\PriceCurrencyInterface;
17+
use \Magento\Catalog\Block\Product\View\Attributes as AttributesBlock;
18+
19+
/**
20+
* Test class for \Magento\Catalog\Block\Product\View\Attributes
21+
*
22+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
23+
*/
24+
class AttributesTest extends TestCase
25+
{
26+
/**
27+
* @var \Magento\Framework\Phrase
28+
*/
29+
private $phrase;
30+
31+
/**
32+
* @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Eav\Model\Entity\Attribute\AbstractAttribute
33+
*/
34+
private $attribute;
35+
36+
/**
37+
* @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Eav\Model\Entity\Attribute\Frontend\AbstractFrontend
38+
*/
39+
private $frontendAttribute;
40+
41+
/**
42+
* @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Catalog\Model\Product
43+
*/
44+
private $product;
45+
46+
/**
47+
* @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\View\Element\Template\Context
48+
*/
49+
private $context;
50+
51+
/**
52+
* @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Registry
53+
*/
54+
private $registry;
55+
56+
/**
57+
* @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Pricing\PriceCurrencyInterface
58+
*/
59+
private $priceCurrencyInterface;
60+
61+
/**
62+
* @var \Magento\Catalog\Block\Product\View\Attributes
63+
*/
64+
private $attributesBlock;
65+
66+
protected function setUp()
67+
{
68+
$this->attribute = $this
69+
->getMockBuilder(AbstractAttribute::class)
70+
->disableOriginalConstructor()
71+
->getMock();
72+
$this->attribute
73+
->expects($this->any())
74+
->method('getIsVisibleOnFront')
75+
->willReturn(true);
76+
$this->attribute
77+
->expects($this->any())
78+
->method('getAttributeCode')
79+
->willReturn('phrase');
80+
$this->frontendAttribute = $this
81+
->getMockBuilder(AbstractFrontend::class)
82+
->disableOriginalConstructor()
83+
->getMock();
84+
$this->attribute
85+
->expects($this->any())
86+
->method('getFrontendInput')
87+
->willReturn('phrase');
88+
$this->attribute
89+
->expects($this->any())
90+
->method('getFrontend')
91+
->willReturn($this->frontendAttribute);
92+
$this->product = $this
93+
->getMockBuilder(Product::class)
94+
->disableOriginalConstructor()
95+
->getMock();
96+
$this->product
97+
->expects($this->any())
98+
->method('getAttributes')
99+
->willReturn([$this->attribute]);
100+
$this->product
101+
->expects($this->any())
102+
->method('hasData')
103+
->willReturn(true);
104+
$this->context = $this
105+
->getMockBuilder(Context::class)
106+
->disableOriginalConstructor()
107+
->getMock();
108+
$this->registry = $this
109+
->getMockBuilder(Registry::class)
110+
->disableOriginalConstructor()
111+
->getMock();
112+
$this->registry
113+
->expects($this->any())
114+
->method('registry')
115+
->willReturn($this->product);
116+
$this->priceCurrencyInterface = $this
117+
->getMockBuilder(PriceCurrencyInterface::class)
118+
->disableOriginalConstructor()
119+
->getMock();
120+
$this->attributesBlock = new AttributesBlock(
121+
$this->context,
122+
$this->registry,
123+
$this->priceCurrencyInterface
124+
);
125+
}
126+
127+
/**
128+
* @return void
129+
*/
130+
public function testGetAttributeNoValue()
131+
{
132+
$this->phrase = '';
133+
$this->frontendAttribute
134+
->expects($this->any())
135+
->method('getValue')
136+
->willReturn($this->phrase);
137+
$attributes = $this->attributesBlock->getAdditionalData();
138+
$this->assertTrue(empty($attributes['phrase']));
139+
}
140+
141+
/**
142+
* @return void
143+
*/
144+
public function testGetAttributeHasValue()
145+
{
146+
$this->phrase = __('Yes');
147+
$this->frontendAttribute
148+
->expects($this->any())
149+
->method('getValue')
150+
->willReturn($this->phrase);
151+
$attributes = $this->attributesBlock->getAdditionalData();
152+
$this->assertNotTrue(empty($attributes['phrase']));
153+
$this->assertNotTrue(empty($attributes['phrase']['value']));
154+
$this->assertEquals('Yes', $attributes['phrase']['value']);
155+
}
156+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Deploy\Console\Command\App;
7+
8+
use Magento\Deploy\Model\DeploymentConfig\ChangeDetector;
9+
use Magento\Framework\Console\Cli;
10+
use Symfony\Component\Console\Command\Command;
11+
use Symfony\Component\Console\Input\InputInterface;
12+
use Symfony\Component\Console\Output\OutputInterface;
13+
14+
/**
15+
* Command for checking if Config propagation is up to date
16+
*/
17+
class ConfigStatusCommand extends Command
18+
{
19+
/**
20+
* Code for error when config import is required.
21+
*/
22+
const EXIT_CODE_CONFIG_IMPORT_REQUIRED = 2;
23+
24+
/**
25+
* @var ChangeDetector
26+
*/
27+
private $changeDetector;
28+
29+
/**
30+
* ConfigStatusCommand constructor.
31+
* @param ChangeDetector $changeDetector
32+
*/
33+
public function __construct(ChangeDetector $changeDetector)
34+
{
35+
$this->changeDetector = $changeDetector;
36+
parent::__construct();
37+
}
38+
39+
/**
40+
* {@inheritdoc}
41+
*/
42+
protected function configure()
43+
{
44+
$this->setName('app:config:status')
45+
->setDescription('Checks if config propagation requires update');
46+
parent::configure();
47+
}
48+
49+
/**
50+
* {@inheritdoc}
51+
*/
52+
protected function execute(InputInterface $input, OutputInterface $output)
53+
{
54+
if ($this->changeDetector->hasChanges()) {
55+
$output->writeln(
56+
'<info>Config files have changed. ' .
57+
'Run app:config:import or setup:upgrade command to synchronize configuration.</info>'
58+
);
59+
return self::EXIT_CODE_CONFIG_IMPORT_REQUIRED;
60+
}
61+
$output->writeln('<info>Config files are up to date.</info>');
62+
return Cli::RETURN_SUCCESS;
63+
}
64+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Deploy\Test\Unit\Console\Command\App;
7+
8+
use Magento\Deploy\Console\Command\App\ConfigStatusCommand;
9+
use Magento\Deploy\Model\DeploymentConfig\ChangeDetector;
10+
use Magento\Framework\Console\Cli;
11+
use Symfony\Component\Console\Tester\CommandTester;
12+
13+
/**
14+
* @inheritdoc
15+
*/
16+
class ConfigStatusCommandTest extends \PHPUnit\Framework\TestCase
17+
{
18+
19+
/**
20+
* @var ConfigStatusCommand
21+
*/
22+
private $command;
23+
/**
24+
* @var ChangeDetector
25+
*/
26+
private $changeDetector;
27+
28+
/**
29+
* @inheritdoc
30+
*/
31+
protected function setUp()
32+
{
33+
$this->changeDetector = $this->getMockBuilder(ChangeDetector::class)
34+
->disableOriginalConstructor()
35+
->getMock();
36+
37+
$this->command = new ConfigStatusCommand($this->changeDetector);
38+
}
39+
40+
/**
41+
* @param bool $hasChanges
42+
* @param string $expectedMessage
43+
* @param int $expectedCode
44+
*
45+
* @dataProvider executeDataProvider
46+
*/
47+
public function testExecute(bool $hasChanges, $expectedMessage, $expectedCode)
48+
{
49+
$this->changeDetector->expects($this->once())
50+
->method('hasChanges')
51+
->will($this->returnValue($hasChanges));
52+
53+
$tester = new CommandTester($this->command);
54+
$tester->execute([]);
55+
56+
$this->assertEquals($expectedMessage, $tester->getDisplay());
57+
$this->assertSame($expectedCode, $tester->getStatusCode());
58+
}
59+
60+
public function executeDataProvider()
61+
{
62+
return [
63+
'Config is up to date' => [
64+
false,
65+
'Config files are up to date.' . PHP_EOL,
66+
Cli::RETURN_SUCCESS
67+
],
68+
'Config needs update' => [
69+
true,
70+
'Config files have changed. ' .
71+
'Run app:config:import or setup:upgrade command to synchronize configuration.' . PHP_EOL,
72+
ConfigStatusCommand::EXIT_CODE_CONFIG_IMPORT_REQUIRED,
73+
],
74+
];
75+
}
76+
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
<item name="dumpApplicationCommand" xsi:type="object">\Magento\Deploy\Console\Command\App\ApplicationDumpCommand</item>
3232
<item name="sensitiveConfigSetCommand" xsi:type="object">\Magento\Deploy\Console\Command\App\SensitiveConfigSetCommand</item>
3333
<item name="configImportCommand" xsi:type="object">Magento\Deploy\Console\Command\App\ConfigImportCommand</item>
34+
<item name="configStatusCommand" xsi:type="object">Magento\Deploy\Console\Command\App\ConfigStatusCommand</item>
3435
</argument>
3536
</arguments>
3637
</type>

app/code/Magento/Theme/Block/Html/Topmenu.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ protected function _getMenuItemClasses(\Magento\Framework\Data\Tree\Node $item)
331331
/**
332332
* Add identity
333333
*
334-
* @param array $identity
334+
* @param string|array $identity
335335
* @return void
336336
*/
337337
public function addIdentity($identity)

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@
4141
<item name="/V1/configurable-products/:sku/children::GET" xsi:type="string"/>
4242
<item name="/V1/configurable-products/:sku/options/:id::GET" xsi:type="string"/>
4343
<item name="/V1/configurable-products/:sku/options/all::GET" xsi:type="string"/>
44+
<item name="/V1/bundle-products/:productSku/children::GET" xsi:type="string"/>
45+
<item name="/V1/bundle-products/:sku/options/all::GET" xsi:type="string"/>
46+
<item name="/V1/bundle-products/options/types::GET" xsi:type="string"/>
47+
<item name="/V1/bundle-products/:sku/options/:optionId::GET" xsi:type="string"/>
4448
<item name="/V1/cmsPage/:pageId::GET" xsi:type="string"/>
4549
<item name="/V1/cmsBlock/:blockId::GET" xsi:type="string"/>
4650
<item name="/V1/store/storeViews::GET" xsi:type="string"/>

0 commit comments

Comments
 (0)