Skip to content

Commit 2e39fcb

Browse files
committed
Merge remote-tracking branch 'origin/BUG#AC-1214' into Hammer_QaulityBacklog_GraphQL_24052022
2 parents 8bfeb98 + cedec63 commit 2e39fcb

File tree

3 files changed

+175
-5
lines changed

3 files changed

+175
-5
lines changed

app/code/Magento/Catalog/Model/ResourceModel/Collection/AbstractCollection.php

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
*/
66
namespace Magento\Catalog\Model\ResourceModel\Collection;
77

8+
use Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface;
9+
use Magento\Framework\Exception\LocalizedException;
10+
811
/**
912
* Catalog EAV collection resource abstract model
1013
*
@@ -25,7 +28,7 @@ class AbstractCollection extends \Magento\Eav\Model\Entity\Collection\AbstractCo
2528
protected $_storeId;
2629

2730
/**
28-
* Store manager
31+
* Manager of store
2932
*
3033
* @var \Magento\Store\Model\StoreManagerInterface
3134
*/
@@ -155,6 +158,18 @@ protected function _getLoadAttributesSelect($table, $attributeIds = [])
155158
$entityIdField = $indexList[$connection->getPrimaryKeyName($entityTable)]['COLUMNS_LIST'][0];
156159

157160
if ($storeId) {
161+
162+
foreach ($attributeIds as $id) {
163+
$attribute = $this->_eavConfig->getAttribute(
164+
$this->getEntity()->getType(),
165+
$id
166+
);
167+
168+
if ($attribute->getAttributeCode() === 'price' && (int)$attribute->getIsGlobal() === 1) {
169+
$storeId = $this->getDefaultStoreId();
170+
}
171+
}
172+
158173
$joinCondition = [
159174
't_s.attribute_id = t_d.attribute_id',
160175
"t_s.{$entityIdField} = t_d.{$entityIdField}",

app/code/Magento/Eav/Model/ResourceModel/ReadHandler.php

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Exception;
1010
use Magento\Eav\Model\Config;
1111
use Magento\Eav\Model\Entity\Attribute\AbstractAttribute;
12+
use Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface;
1213
use Magento\Framework\DataObject;
1314
use Magento\Framework\DB\Select;
1415
use Magento\Framework\DB\Sql\UnionExpression;
@@ -18,6 +19,7 @@
1819
use Magento\Framework\Exception\LocalizedException;
1920
use Magento\Framework\Model\Entity\ScopeInterface;
2021
use Magento\Framework\Model\Entity\ScopeResolver;
22+
use Magento\Store\Model\Store;
2123
use Psr\Log\LoggerInterface;
2224

2325
/**
@@ -122,6 +124,8 @@ protected function getContextVariables(ScopeInterface $scope)
122124
* @throws ConfigurationMismatchException
123125
* @throws LocalizedException
124126
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
127+
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
128+
* @SuppressWarnings(PHPMD.NPathComplexity)
125129
*/
126130
public function execute($entityType, $entityData, $arguments = [])
127131
{
@@ -135,12 +139,15 @@ public function execute($entityType, $entityData, $arguments = [])
135139
$attributeTables = [];
136140
$attributesMap = [];
137141
$selects = [];
142+
$attributeScopeGlobal = [];
138143

139144
/** @var AbstractAttribute $attribute */
140145
foreach ($this->getEntityAttributes($entityType, new DataObject($entityData)) as $attribute) {
141146
if (!$attribute->isStatic()) {
142147
$attributeTables[$attribute->getBackend()->getTable()][] = $attribute->getAttributeId();
143148
$attributesMap[$attribute->getAttributeId()] = $attribute->getAttributeCode();
149+
$attributeScopeGlobal[$attribute->getAttributeId()] =
150+
$attribute->getIsGlobal() === ScopedAttributeInterface::SCOPE_GLOBAL ? 1 : 0;
144151
}
145152
}
146153
if (count($attributeTables)) {
@@ -174,7 +181,23 @@ public function execute($entityType, $entityData, $arguments = [])
174181
$attributes = $connection->fetchAll($orderedUnionSelect);
175182
foreach ($attributes as $attributeValue) {
176183
if (isset($attributesMap[$attributeValue['attribute_id']])) {
177-
$entityData[$attributesMap[$attributeValue['attribute_id']]] = $attributeValue['value'];
184+
$isGlobalAttribute = $attributeScopeGlobal[$attributeValue['attribute_id']];
185+
$storeId = $attributeValue['store_id'] ?? null;
186+
187+
// Set global value if attribute scope is set to Global
188+
if ($isGlobalAttribute && (int)$storeId === Store::DEFAULT_STORE_ID) {
189+
$entityData[$attributesMap[$attributeValue['attribute_id']]] = $attributeValue['value'];
190+
continue;
191+
}
192+
193+
if (!$isGlobalAttribute && (int)$storeId === Store::DEFAULT_STORE_ID) {
194+
$entityData[$attributesMap[$attributeValue['attribute_id']]] = $attributeValue['value'];
195+
continue;
196+
}
197+
198+
if (!$isGlobalAttribute && (int)$storeId !== Store::DEFAULT_STORE_ID) {
199+
$entityData[$attributesMap[$attributeValue['attribute_id']]] = $attributeValue['value'];
200+
}
178201
} else {
179202
$this->logger->warning(
180203
"Attempt to load value of nonexistent EAV attribute",

app/code/Magento/Eav/Test/Unit/Model/ResourceModel/ReadHandlerTest.php

Lines changed: 135 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,17 @@
1515
use Magento\Framework\DB\Select;
1616
use Magento\Framework\EntityManager\EntityMetadataInterface;
1717
use Magento\Framework\EntityManager\MetadataPool;
18+
use Magento\Framework\Model\Entity\ScopeInterface;
1819
use Magento\Framework\Model\Entity\ScopeResolver;
1920
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
2021
use PHPUnit\Framework\MockObject\MockObject;
2122
use PHPUnit\Framework\TestCase;
2223

24+
/**
25+
* Eav attributes read handler tests
26+
*
27+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
28+
*/
2329
class ReadHandlerTest extends TestCase
2430
{
2531
/**
@@ -60,8 +66,17 @@ protected function setUp(): void
6066
->willReturn($this->metadataMock);
6167
$this->configMock = $args['config'];
6268
$this->scopeResolverMock = $args['scopeResolver'];
69+
70+
$scopeMock = $this->getMockBuilder(ScopeInterface::class)
71+
->disableOriginalConstructor()
72+
->getMock();
73+
$fallback = clone $scopeMock;
74+
$scopeMock->method('getIdentifier')->willReturn('store_id');
75+
$scopeMock->method('getValue')->willReturn(1);
76+
$scopeMock->method('getFallback')->willReturn($fallback);
77+
6378
$this->scopeResolverMock->method('getEntityContext')
64-
->willReturn([]);
79+
->willReturn([$scopeMock]);
6580

6681
$this->readHandler = $objectManager->getObject(ReadHandler::class, $args);
6782
}
@@ -73,8 +88,12 @@ protected function setUp(): void
7388
* @param bool $isStatic
7489
* @dataProvider executeDataProvider
7590
*/
76-
public function testExecute($eavEntityType, $callNum, array $expected, $isStatic = true)
77-
{
91+
public function testExecute(
92+
$eavEntityType,
93+
$callNum,
94+
array $expected,
95+
$isStatic = true
96+
) {
7897
$entityData = ['linkField' => 'theLinkField'];
7998
$this->metadataMock->method('getEavEntityType')
8099
->willReturn($eavEntityType);
@@ -105,10 +124,90 @@ public function testExecute($eavEntityType, $callNum, array $expected, $isStatic
105124
->willReturn('linkField');
106125

107126
$attributeMock = $this->getMockBuilder(AbstractAttribute::class)
127+
->setMethods(['getAttributeCode', 'isScopeWebsite', 'isStatic', 'getBackend', 'getAttributeId'])
128+
->disableOriginalConstructor()
129+
->getMockForAbstractClass();
130+
$attributeMock->method('isStatic')
131+
->willReturn($isStatic);
132+
$backendMock = $this->getMockBuilder(AbstractBackend::class)
108133
->disableOriginalConstructor()
109134
->getMock();
135+
$backendMock->method('getTable')
136+
->willReturn('backendTable');
137+
$attributeMock->method('getBackend')
138+
->willReturn($backendMock);
139+
$attributeMock->method('getAttributeId')
140+
->willReturn('attributeId');
141+
$attributeMock->method('getAttributeCode')
142+
->willReturn('attributeCode');
143+
$this->configMock->expects($this->exactly($callNum))
144+
->method('getEntityAttributes')
145+
->willReturn([$attributeMock]);
146+
$this->assertEquals($expected, $this->readHandler->execute('entity_type', $entityData));
147+
}
148+
149+
/**
150+
* @param string $eavEntityType
151+
* @param int $callNum
152+
* @param array $expected
153+
* @param bool $isStatic
154+
* @param null|int $isGlobalScope
155+
* @throws \Magento\Framework\Exception\ConfigurationMismatchException
156+
* @throws \Magento\Framework\Exception\LocalizedException
157+
* @dataProvider executeGlobalScopeDataProvider
158+
*/
159+
public function testExecuteGlobalScope(
160+
$eavEntityType,
161+
$callNum,
162+
array $expected,
163+
$isStatic = true,
164+
$isGlobalScope = null
165+
) {
166+
$entityData = ['linkField' => 'theLinkField'];
167+
$this->metadataMock->method('getEavEntityType')
168+
->willReturn($eavEntityType);
169+
$connectionMock = $this->getMockBuilder(AdapterInterface::class)
170+
->disableOriginalConstructor()
171+
->getMockForAbstractClass();
172+
$selectMock = $this->getMockBuilder(Select::class)
173+
->disableOriginalConstructor()
174+
->getMock();
175+
$selectMock->method('from')
176+
->willReturnSelf();
177+
$selectMock->method('where')
178+
->willReturnSelf();
179+
$connectionMock->method('select')
180+
->willReturn($selectMock);
181+
$connectionMock->method('fetchAll')
182+
->willReturn(
183+
[
184+
[
185+
'attribute_id' => 'attributeId',
186+
'value' => 'attributeValue',
187+
'store_id' => 0
188+
]
189+
]
190+
);
191+
$this->metadataMock->method('getEntityConnection')
192+
->willReturn($connectionMock);
193+
$this->metadataMock->method('getLinkField')
194+
->willReturn('linkField');
195+
196+
$attributeMock = $this->getMockBuilder(AbstractAttribute::class)
197+
->setMethods([
198+
'getAttributeCode',
199+
'isScopeWebsite',
200+
'getIsGlobal',
201+
'isStatic',
202+
'getBackend',
203+
'getAttributeId'
204+
])
205+
->disableOriginalConstructor()
206+
->getMockForAbstractClass();
110207
$attributeMock->method('isStatic')
111208
->willReturn($isStatic);
209+
$attributeMock->method('getIsGlobal')
210+
->willReturn($isGlobalScope);
112211
$backendMock = $this->getMockBuilder(AbstractBackend::class)
113212
->disableOriginalConstructor()
114213
->getMock();
@@ -142,6 +241,39 @@ public function executeDataProvider()
142241
'attributeCode' => 'attributeValue'
143242
],
144243
false
244+
]
245+
];
246+
}
247+
248+
/**
249+
* @return array
250+
*/
251+
public function executeGlobalScopeDataProvider()
252+
{
253+
return [
254+
'null entity type' => [null, 0, ['linkField' => 'theLinkField']],
255+
'static attribute' => ['env-entity-type', 1, ['linkField' => 'theLinkField']],
256+
'non-static attribute' => [
257+
'env-entity-type',
258+
1,
259+
[
260+
'linkField' => 'theLinkField',
261+
'attributeCode' => 'attributeValue'
262+
],
263+
false,
264+
null,
265+
1
266+
],
267+
'non-static attribute2' => [
268+
'env-entity-type',
269+
1,
270+
[
271+
'linkField' => 'theLinkField',
272+
'attributeCode' => 'attributeValue'
273+
],
274+
false,
275+
1,
276+
0
145277
],
146278
];
147279
}

0 commit comments

Comments
 (0)