3

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

 /** @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $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

Sophie Baxter
  • 515
  • 2
  • 11
  • 25

5 Answers5

4

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 \Magento\Eav\Setup\EavSetup $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 \Magento\Framework\App\Http
    implements \Magento\Framework\AppInterface {
    public function launch()
    {
        //Our code goes here:
        $objectManager = \Magento\Framework\App\ObjectManager::getInstance();

        $eavAttribute = $objectManager->create('Magento\Eav\Model\Config');

        /** @var \Magento\Eav\Model\Config $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('Magento\Eav\Setup\EavSetup');

        /** @var \Magento\Eav\Setup\EavSetup $setupObject **/

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

    public function catchException(\Magento\Framework\App\Bootstrap $bootstrap, \Exception $exception)
    {
        return false;
    }

}

Magento 1 version here.

Khoa TruongDinh
  • 32,054
  • 11
  • 88
  • 155
  • Hi, thanks so much for this response, this doesn't seem to be deleting the options though. Can you explain why i need to call addAttributeOption($options), and does this imply the option manipulation this should be done from within the UpgradeData class? Currently i'm using an external source file to add an attribute and it's options, it's within this file that i would like to delete all options that have been created but are no longer in use. – Sophie Baxter Jul 20 '16 at 11:08
  • I update my code, I tested with playground file. – Khoa TruongDinh Jul 21 '16 at 11:18
  • @KhoaTruongDinh, I have to remove these options, from json "OptionValues": [ { "OptionId": "01",
    "OptionName": "Test3" }, { "OptionId": "Null", "OptionName" : "Test" }
    – Jafar Pinjar Jan 23 '19 at 03:08
  • @KhoaTruongDinh, how to delete multiple options at a time ? – Jafar Pinjar Jan 23 '19 at 03:09
  • @jafarpinjar in this code make an array $options in $setupObject->addAttributeOption($options); and dont forget to use di instead object manager, using object manager is bad practice! $options - array of optionIds and values foreach ($options as $optionId => $value) { $options['value'][$optionId] = true; $options['delete'][$optionId] = true; } $setupObject->addAttributeOption($options); – kao Jan 18 '20 at 21:49
3

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

$eavConfig = $object_Manager->get('\Magento\Eav\Model\Config');
$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('\Magento\Eav\Setup\EavSetup');
 $eavSetup->addAttributeOption($options);
Liz Eipe C
  • 1,286
  • 12
  • 17
2

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: Magento\Catalog\Model\ResourceModel\Attribute\Entity\AttributeTest

Method : removeAttributeOption

$eavConfig = $object_Manager->get('\Magento\Eav\Model\Config');
$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);
0

You can use Magento\Eav\Api\AttributeOptionManagementInterface, it has method delete which you can use.

 /**
 * @var \Magento\Eav\Api\AttributeOptionManagementInterface
 */
protected $attributeOptionManagement;
...
$this->attributeOptionManagement->delete(
                'catalog_product',
                $attributeId,
                $attributeOptionId
            );
        }
nicemister
  • 11
  • 1
0

You can use:

\Magento\Eav\Model\Entity\Attribute\OptionManagement::delete($entityType, $attributeCode, $optionId)

Sergey Uskov
  • 416
  • 3
  • 8