diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Repository.php b/app/code/Magento/Catalog/Model/Product/Attribute/Repository.php index 270a2f229678b..c19efac12ae0e 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Repository.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Repository.php @@ -118,6 +118,9 @@ public function save(\Magento\Catalog\Api\Data\ProductAttributeInterface $attrib $attribute->setAttributeId($existingModel->getAttributeId()); $attribute->setIsUserDefined($existingModel->getIsUserDefined()); $attribute->setFrontendInput($existingModel->getFrontendInput()); + if ($attribute->getIsUserDefined()) { + $this->processAttributeData($attribute); + } if (is_array($attribute->getFrontendLabels())) { $defaultFrontendLabel = $attribute->getDefaultFrontendLabel(); @@ -156,15 +159,7 @@ public function save(\Magento\Catalog\Api\Data\ProductAttributeInterface $attrib $this->validateCode($attribute->getAttributeCode()); $this->validateFrontendInput($attribute->getFrontendInput()); - $attribute->setBackendType( - $attribute->getBackendTypeByInput($attribute->getFrontendInput()) - ); - $attribute->setSourceModel( - $this->productHelper->getAttributeSourceModelByInputType($attribute->getFrontendInput()) - ); - $attribute->setBackendModel( - $this->productHelper->getAttributeBackendModelByInputType($attribute->getFrontendInput()) - ); + $this->processAttributeData($attribute); $attribute->setEntityTypeId( $this->eavConfig ->getEntityType(\Magento\Catalog\Api\Data\ProductAttributeInterface::ENTITY_TYPE_CODE) @@ -275,4 +270,23 @@ protected function validateFrontendInput($frontendInput) throw InputException::invalidFieldValue('frontend_input', $frontendInput); } } + + /** + * Process attribute data based on attribute frontend input type. + * + * @param \Magento\Catalog\Api\Data\ProductAttributeInterface $attribute + * @return void + */ + private function processAttributeData(\Magento\Catalog\Api\Data\ProductAttributeInterface $attribute) + { + $attribute->setBackendType( + $attribute->getBackendTypeByInput($attribute->getFrontendInput()) + ); + $attribute->setSourceModel( + $this->productHelper->getAttributeSourceModelByInputType($attribute->getFrontendInput()) + ); + $attribute->setBackendModel( + $this->productHelper->getAttributeBackendModelByInputType($attribute->getFrontendInput()) + ); + } } diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeRepositoryTest.php index e48c5ad018db4..00b20ae8eecdb 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeRepositoryTest.php @@ -7,7 +7,6 @@ namespace Magento\Catalog\Api; use Magento\Framework\Webapi\Exception as HTTPExceptionCodes; -use Magento\TestFramework\Helper\Bootstrap; class ProductAttributeRepositoryTest extends \Magento\TestFramework\TestCase\WebapiAbstract { @@ -194,6 +193,36 @@ public function testUpdate() $this->assertEquals("Default Blue Updated", $result['options'][1]['label']); } + /** + * Test source model and backend type can not be changed to custom, as they depends on attribute frontend type. + * + * @magentoApiDataFixture Magento/Catalog/Model/Product/Attribute/_files/create_attribute_service.php + * @return void + */ + public function testUpdateAttributeSourceAndType() + { + $attributeCode = uniqid('label_attr_code'); + $attribute = $this->createAttribute($attributeCode); + $attributeData = [ + 'attribute' => [ + 'attribute_id' => $attribute['attribute_id'], + 'attribute_code' => $attributeCode, + 'entity_type_id' => 4, + 'is_required' => false, + 'frontend_input' => 'select', + 'source_model' => "Some/Custom/Source/Model", + 'backend_type' => 'varchar', + 'frontend_labels' => [ + ['store_id' => 1, 'label' => 'front_lbl_new'], + ], + ], + ]; + + $result = $this->updateAttribute($attributeCode, $attributeData); + $this->assertEquals(\Magento\Eav\Model\Entity\Attribute\Source\Table::class, $result['source_model']); + $this->assertEquals('int', $result['backend_type']); + } + /** * @magentoApiDataFixture Magento/Catalog/Model/Product/Attribute/_files/create_attribute_service.php */