Skip to content

Commit 32118bc

Browse files
author
Stanislav Idolov
committed
MAGETWO-71136: Cannot save attribute in product page admin with a related conf product that has different attribute set sharing a multiselect attribute
1 parent 8d7aab7 commit 32118bc

File tree

5 files changed

+58
-9
lines changed

5 files changed

+58
-9
lines changed

app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/AbstractTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,13 @@ public function testWalkAttributes()
4747

4848
$code = 'test_attr';
4949
$set = 10;
50+
$storeId = 100;
5051

5152
$object = $this->getMock('Magento\Catalog\Model\Product', ['__wakeup'], [], '', false);
5253

5354
$object->setData('test_attr', 'test_attr');
5455
$object->setData('attribute_set_id', $set);
56+
$object->setData('store_id', $storeId);
5557

5658
$entityType = new \Magento\Framework\DataObject();
5759
$entityType->setEntityTypeCode('test');

app/code/Magento/Eav/Model/Entity/AbstractEntity.php

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Magento\Eav\Model\Entity\Attribute\Source\AbstractSource;
1515
use Magento\Framework\App\Config\Element;
1616
use Magento\Framework\App\ResourceConnection\Config;
17+
use Magento\Framework\DataObject;
1718
use Magento\Framework\Exception\LocalizedException;
1819
use Magento\Framework\Model\AbstractModel;
1920
use Magento\Framework\Model\ResourceModel\Db\ObjectRelationProcessor;
@@ -204,6 +205,13 @@ abstract class AbstractEntity extends AbstractResource implements EntityInterfac
204205
*/
205206
protected $objectRelationProcessor;
206207

208+
/**
209+
* Attributes stored by scope (store id and attribute set id).
210+
*
211+
* @var array
212+
*/
213+
private $attributesByScope;
214+
207215
/**
208216
* @param Context $context
209217
* @param array $data
@@ -451,15 +459,20 @@ public function getAttribute($attribute)
451459
* Adding attribute to entity
452460
*
453461
* @param AbstractAttribute $attribute
462+
* @param string|null $suffix
454463
* @return $this
455464
*/
456-
public function addAttribute(AbstractAttribute $attribute)
465+
public function addAttribute(AbstractAttribute $attribute, $suffix = null)
457466
{
458467
$attribute->setEntity($this);
459468
$attributeCode = $attribute->getAttributeCode();
460469

461470
$this->_attributesByCode[$attributeCode] = $attribute;
462471

472+
if ($suffix !== null) {
473+
$this->attributesByScope[$suffix][$attributeCode] = $attribute;
474+
}
475+
463476
if ($attribute->isStatic()) {
464477
$this->_staticAttributes[$attributeCode] = $attribute;
465478
} else {
@@ -572,6 +585,31 @@ protected function _isApplicableAttribute($object, $attribute)
572585
return true;
573586
}
574587

588+
/**
589+
* Get attributes by scope
590+
*
591+
* @return array
592+
*/
593+
private function getAttributesByScope($suffix)
594+
{
595+
return (isset($this->attributesByScope[$suffix]) && !empty($this->attributesByScope[$suffix]))
596+
? $this->attributesByScope[$suffix]
597+
: $this->getAttributesByCode();
598+
}
599+
600+
/**
601+
* Get attributes cache suffix.
602+
*
603+
* @param DataObject $object
604+
* @return string
605+
*/
606+
private function getAttributesCacheSuffix(DataObject $object)
607+
{
608+
$attributeSetId = $object->getAttributeSetId() ?: 0;
609+
$storeId = $object->getStoreId() ?: 0;
610+
return $storeId . '-' . $attributeSetId;
611+
}
612+
575613
/**
576614
* Walk through the attributes and run method with optional arguments
577615
*
@@ -607,7 +645,8 @@ public function walkAttributes($partMethod, array $args = [], $collectExceptionM
607645
break;
608646
}
609647
$results = [];
610-
foreach ($this->getAttributesByCode() as $attrCode => $attribute) {
648+
$suffix = $this->getAttributesCacheSuffix($args[0]);
649+
foreach ($this->getAttributesByScope($suffix) as $attrCode => $attribute) {
611650
if (isset($args[0]) && is_object($args[0]) && !$this->_isApplicableAttribute($args[0], $attribute)) {
612651
continue;
613652
}

app/code/Magento/Eav/Model/Entity/AttributeLoader.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public function loadAllAttributes(AbstractEntity $resource, DataObject $object =
7070
$attributes = $this->cache->getAttributes($typeCode, $suffix);
7171
if ($attributes) {
7272
foreach ($attributes as $attribute) {
73-
$resource->addAttribute($attribute);
73+
$resource->addAttribute($attribute, $suffix);
7474
}
7575
return $resource;
7676
}

app/code/Magento/Eav/Test/Unit/Model/Entity/AbstractEntityTest.php

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -317,8 +317,6 @@ public function testSave($attributeCode, $attributeSetId, $productData, $product
317317
->getMock();
318318
$model->expects($this->any())->method('_getValue')->will($this->returnValue($eavConfig));
319319
$model->expects($this->any())->method('getConnection')->will($this->returnValue($this->_getConnectionMock()));
320-
321-
322320
$eavConfig->expects($this->any())->method('getAttribute')->will(
323321
$this->returnCallback(
324322
function ($entityType, $attributeCode) use ($attributes) {
@@ -337,19 +335,29 @@ public function productAttributesDataProvider()
337335
[
338336
'test_attr',
339337
$attributeSetId,
340-
['test_attr' => 'test_attr', 'attribute_set_id' => $attributeSetId, 'entity_id' => null],
338+
[
339+
'test_attr' => 'test_attr',
340+
'attribute_set_id' => $attributeSetId,
341+
'entity_id' => null,
342+
'store_id' => 1
343+
],
341344
null,
342345
],
343346
[
344347
'test_attr',
345348
$attributeSetId,
346-
['test_attr' => 'test_attr', 'attribute_set_id' => $attributeSetId, 'entity_id' => 12345],
349+
[
350+
'test_attr' => 'test_attr',
351+
'attribute_set_id' => $attributeSetId,
352+
'entity_id' => 12345,
353+
'store_id' => 1
354+
],
347355
['test_attr' => 'test_attr']
348356
],
349357
[
350358
'test_attr',
351359
$attributeSetId,
352-
['test_attr' => '99.99', 'attribute_set_id' => $attributeSetId, 'entity_id' => 12345],
360+
['test_attr' => '99.99', 'attribute_set_id' => $attributeSetId, 'entity_id' => 12345, 'store_id' => 1],
353361
['test_attr' => '99.9900']
354362
]
355363
];

dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/CategoryTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ public function testSaveActionCategoryWithDangerRequest()
339339
);
340340
$this->dispatch('backend/catalog/category/save');
341341
$this->assertSessionMessages(
342-
$this->equalTo(['The value of attribute "is_active" must be set']),
342+
$this->equalTo(['The value of attribute "name" must be set']),
343343
\Magento\Framework\Message\MessageInterface::TYPE_ERROR
344344
);
345345
}

0 commit comments

Comments
 (0)