Magento 2 Get Attribute option Id issue with core method
-
08-02-2021 - |
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.
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;
}
}