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

有帮助吗?

解决方案

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.

其他提示

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);

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
            );
        }

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);

You can use:

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

许可以下: CC-BY-SA归因
scroll top