Question

I am using below code to get the option Id with an attribute value/label in a custom extension.

/*
* Get attribute id based on option value
*/
protected function getAttributeOptionId($attributeCode, $label)
{
    $productResource = $this->productFactory->create();
    $attribute = $productResource->getAttribute($attributeCode);
    if ($attribute->usesSource()) {
        return $optionId = $attribute->getSource()->getOptionId($label);
    }
}

This works fine in most cases. When I do a call with params color and red it works just fine.

But there is an issue when i call it with for instance size 20. This only happens when there is attribute label/value with id 20. It just returns the first occurrence it finds (20 as a label or as an id).

I did some research and I found out why this is. Below code is the part which returns the id. The second part in the OR condition $option['value'] == $value causes my issue. It looks for a match in the label OR value (which is the id). It just returns the first one found. I looked in the class there is no alternative method without the OR condtion.

/**
* File: /vendor/magento/module-eav/Model/Entity/Attribute/Source/AbstractSource.php
* @param string $value
* @return null|string
*/
public function getOptionId($value)
{
    foreach ($this->getAllOptions() as $option) {
        if (strcasecmp($option['label'], $value) == 0 || $option['value'] == $value) {
            return $option['value'];
        }
    }
    return null;
}

My question is.

What is the best way to solve this? Is there an alternative way to get an id from a attribute label? Or should I rewrite the method? Or maybe extends the class and use a custom method? In any of these cases I would be glad to see an example or a place to start.

Was it helpful?

Solution

I hope this help for your custom extension helper.

<?php
namespace Package\Module\Helper;

class Data extends \Magento\Framework\App\Helper\AbstractHelper
{

    protected $scopeConfig;
    protected $_objectManager = null;
    protected $_attributes        = [];
    protected $_eavSetup        = null;


    public function __construct(
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
        \Magento\Framework\ObjectManagerInterface $objectmanager
    )
    {
        $this->scopeConfig = $scopeConfig;
        $this->_objectManager = $objectmanager;
    }

    public function getAttribute($_code, $_force = false) 
    {   
        if(!isset($this->_attributes[$_code]) || $_force) {
            $_attribute = $this->_objectManager->get("Magento\Catalog\Model\ResourceModel\Eav\AttributeFactory")->create();
            $this->_attributes[$_code] = $_attribute->loadByCode(\Magento\Catalog\Api\Data\ProductAttributeInterface::ENTITY_TYPE_CODE, $_code);
        }

        return $this->_attributes[$_code];
    }

    public function getEavSetup() {
        if(!$this->_eavSetup) {
            $this->_eavSetup = $this->_objectManager->get('Magento\Eav\Setup\EavSetupFactory')->create([
                'setup' => $this->_objectManager->get('Magento\Framework\Setup\ModuleDataSetupInterface')
            ]);
        }
        return $this->_eavSetup;
    }

    public function getAttributeOptionId($_code, $_value) {
        $attribute = $this->getAttribute($_code);   
        if(!$_value || !$attribute || !$attribute->getId()) {
            return ''; 
        }

        $optionId = '';
        $options = $attribute->getSource()->getAllOptions(false);

        if($options && count($options) > 0) {
            foreach($options as $option){
                if(trim(strtolower($option['label'])) ==  strtolower($_value)){
                    $optionId = $option['value'];
                    break;
                }
            }
        }    

        if(!$optionId) {
            $option = [];
            $option['attribute_id'] = $attribute->getAttributeId();
            $option['value']['option'][0] = $_value; 
            $option['value']['option'][1] = $_value; 
            $option['order']['option'] = ''; 
            $this->getEavSetup()->addAttributeOption($option);

            $attribute = $this->getAttribute($_code, true);
            $options = $attribute->getSource()->getAllOptions(false);

            if($options && count($options) > 0) {
                foreach($options as $option){
                    if(trim(strtolower($option['label'])) ==  strtolower($_value)){
                        $optionId = $option['value'];
                        break;
                    }
                }
            } 
        } 
        return $optionId;
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top