Description
There is a potential issue in the EAV setup model where the default attribute group can be deleted. In the event that you try to remove a non-existent attribute group, the system will check if the attribute group exists and if not use the default group ID. When this happens, the default group will be removed and any attributes assigned to that group will no longer be associated.
For entities like the "catalog_product" this becomes problematic and has negative effects when trying to edit the product in admin. I believe this also affects the results that get returned via GraphQL.
Preconditions (*)
- Magento <=2.4.3
- Can be check with sample data, but any data will do.
Steps to reproduce (*)
- In your set up or upgrade script, attempt to remove a non-existent attribute. For simplicity, I will show portions of code that matters:
...
/**
* EAV Setup model
*
* @var \Magento\Eav\Setup\EavSetup
*/
private $eavSetupModel;
/**
* Remove attribute group
*
* @return void
*/
public function removeProductAttributeGroups()
{
$groups = [
'I dont exist'
];
$attributeSetIds = $this->eavSetupModel->getAllAttributeSetIds(
ProductAttributeInterface::ENTITY_TYPE_CODE
);
foreach ($groups as $code) {
foreach ($attributeSetIds as $attributeSetId) {
$this->eavSetupModel->removeAttributeGroup(
ProductAttributeInterface::ENTITY_TYPE_CODE,
$attributeSetId,
$code
);
}
}
}
...
As you can see, the above is a method that could exist in a setup script, in a custom module. At some point during the process, the method removeProductAttributeGroups
will be called which will attempt to remove the listed attribute groups.
The method calls a core function in Magento\Eav\Setup\EavSetup::removeAttributeGroup($entityTypeId, $setId, $id))
:
File: vendor/magento/module-eav/Setup/EavSetup.php
Lines: 711 - 727
/**
* Remove Attribute Group By Id or Name
*
* @param int|string $entityTypeId
* @param int|string $setId
* @param int|string $id
* @return $this
*/
public function removeAttributeGroup($entityTypeId, $setId, $id)
{
$this->setup->deleteTableRow(
'eav_attribute_group',
'attribute_group_id',
$this->getAttributeGroupId($entityTypeId, $setId, $id)
);
return $this;
}
This is a standard delete row method and nothing special there. The interesting bit is this $this->getAttributeGroupId($entityTypeId, $setId, $id)
method:
File: vendor/magento/module-eav/Setup/EavSetup.php
Lines: 686 - 708
/**
* Retrieve Attribute Group Id by Id or Name
*
* @param int|string $entityTypeId
* @param int|string $setId
* @param int|string $groupId
* @return $this
* @throws LocalizedException
*/
public function getAttributeGroupId($entityTypeId, $setId, $groupId)
{
if (!is_numeric($groupId)) {
$groupId = $this->getAttributeGroup($entityTypeId, $setId, $groupId, 'attribute_group_id');
}
if (!is_numeric($groupId)) {
$groupId = $this->getDefaultAttributeGroupId($entityTypeId, $setId);
}
if (!is_numeric($groupId)) {
throw new LocalizedException(__('The attribute group ID is incorrect. Verify the ID and try again.'));
}
return $groupId;
}
Here you will notice that it attempts to fetch the attribute group and if it does not exist it will attempt to fetch the default attribute group which does exist. The outcome is then that the default attribute group is removed.
Expected result (*)
- When attempting to remove an attribute group that does not exist, do not remove anything or throw an exception.
Actual result (*)
- When attempting to remove an attribute group that does not exist, the default attribute group is removed and all attributes assigned to that group are no longer associated.
Please provide Severity assessment for the Issue as Reporter. This information will help during Confirmation and Issue triage processes.
- Severity: S0 - Affects critical data or functionality and leaves users without workaround.
- Severity: S1 - Affects critical data or functionality and forces users to employ a workaround.
- Severity: S2 - Affects non-critical data or functionality and forces users to employ a workaround.
- Severity: S3 - Affects non-critical data or functionality and does not force users to employ a workaround.
- Severity: S4 - Affects aesthetics, professional look and feel, “quality” or “usability”.
The workaround at this point is to do some additional checking to see if the attribute group does indeed exist before attempting to remove it. I feel like this could potentially be in the S3 severity range, but not entirely sure at this point. Custom modules that do employ this method have the potential of removing the default "General" attribute group on products if the attribute group does not exist.
Activity