Programatically delete custom attribute options

The question:

I’m trying to delete all custom attribute options not contained within a specific options array as follows:

 /** @var MagentoCatalogModelResourceModelEavAttribute $attribute */
        $attribute = $this->getAttribute($attributeCode);

        $sourceModel = $this->tableFactory->create();
        $sourceModel->setAttribute($attribute);

        $options = $sourceModel->getAllOptions();
        foreach ($options as $option) {
            if(!in_array($option, $usedOptions)) {
                $option->delete();
            }
        }

How would i achieve this? $option->delete() throws an error – Call to a member function delete() on array

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

If we take a look:

vendor/magento/module-eav/Setup/EavSetup.php

public function addAttributeOption($option)
{
        $optionTable = $this->setup->getTable('eav_attribute_option');
        $optionValueTable = $this->setup->getTable('eav_attribute_option_value');

        if (isset($option['value'])) {
            foreach ($option['value'] as $optionId => $values) {
                $intOptionId = (int)$optionId;
                if (!empty($option['delete'][$optionId])) {
                    if ($intOptionId) {
                        $condition = ['option_id =?' => $intOptionId];
                        $this->setup->getConnection()->delete($optionTable, $condition);
                    }
                    continue;
                }

                 ......

                $condition = ['option_id =?' => $intOptionId];
                $this->setup->getConnection()->delete($optionValueTable, $condition);
                foreach ($values as $storeId => $value) {
                    $data = ['option_id' => $intOptionId, 'store_id' => $storeId, 'value' => $value];
                    $this->setup->getConnection()->insert($optionValueTable, $data);
                }
            }
        }
        ......
}

We can see how to use addAttributeOption() method to delete custom options. Our code should be:

    ......
    $options = $sourceModel->getAllOptions();

    foreach ($options as $optionId => $value) {

        //We can use if condition
        $options['value'][$optionId] = true;  
        $options['delete'][$optionId] = true;

    }

    /** @var MagentoEavSetupEavSetup $setup;
    $setup->addAttributeOption($options)

How to get attribute options value: Magento 2 – How to get attribute options value of eav entity?

UPDATE:
Testing with playground: How can I bootstrap Magento 2 in a test.php script?

<?php
class TestApp
    extends MagentoFrameworkAppHttp
    implements MagentoFrameworkAppInterface {
    public function launch()
    {
        //Our code goes here:
        $objectManager = MagentoFrameworkAppObjectManager::getInstance();

        $eavAttribute = $objectManager->create('MagentoEavModelConfig');

        /** @var MagentoEavModelConfig $attribute */
        $attribute = $eavAttribute->getAttribute('catalog_product', 'color');

        $options = $attribute->getSource()->getAllOptions();

       //foreach ($options as $optionId => $value) {
            //We can use if condition
            //For example
            $options['value'][4] = true;
            $options['delete'][4] = true;
      //}

        $setupObject = $objectManager->create('MagentoEavSetupEavSetup');

        /** @var MagentoEavSetupEavSetup $setupObject **/

        $setupObject->addAttributeOption($options);
        //the method must end with this line
        return $this->_response;
    }

    public function catchException(MagentoFrameworkAppBootstrap $bootstrap, Exception $exception)
    {
        return false;
    }

}

Magento 1 version here.

Method 2

Please use the following code :
http://www.pearlbells.co.uk/delete-attribute-options-magento-2/

$eavConfig = $object_Manager->get('MagentoEavModelConfig');
$attribute = $eavConfig->getAttribute('catalog_product', 'color');
$id = $attribute->getAttributeId();
$options = $attribute->getSource()->getAllOptions();

foreach ($options as $option) {
echo 'Delete label : '.$option['label'].PHP_EOL;  
$options['delete'][$option['value']] = true; 
$options['value'][$option['value']] = true;
}

$eavSetup = $object_Manager->get('MagentoEavSetupEavSetup');
 $eavSetup->addAttributeOption($options);

Method 3

I tried $eavSetup->addAttributeOption ,But it’s not working for text swatch type attributes. So got a way which is working for all type of attributes.

Reference Class: MagentoCatalogModelResourceModelAttributeEntityAttributeTest

Method : removeAttributeOption

$eavConfig = $object_Manager->get('MagentoEavModelConfig');
$attribute = $eavConfig->getAttribute('catalog_product', 'color');
// $optionId = option id which you want to delete 
$removalMarker = [
    'option' => [
        'value' => [$optionId => []],
        'delete' => [$optionId => '1'],
    ],
];
$attribute->addData($removalMarker);
$attribute->save($attribute);

Method 4

You can use MagentoEavApiAttributeOptionManagementInterface, it has method delete which you can use.

 /**
 * @var MagentoEavApiAttributeOptionManagementInterface
 */
protected $attributeOptionManagement;
...
$this->attributeOptionManagement->delete(
                'catalog_product',
                $attributeId,
                $attributeOptionId
            );
        }

Method 5

You can use:

MagentoEavModelEntityAttributeOptionManagement::delete($entityType, $attributeCode, $optionId)


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment