cancel
Showing results for 
Search instead for 
Did you mean: 

Magento 2.3.4 - Add attribut value programatically

Magento 2.3.4 - Add attribut value programatically

Hello,

 

I have a problem after updating to 2.3.4. I have a code that is adding values to an select type attribute. When I try to add a value that does not exist, the script is stopping without any error. I've search for the error everywhere and I could not find it.

 

try{
    if($_attribute->getFrontendInput() == "select"){   
        $attributeValue = $this->attributesManager->setAttributeValues($_attributCOD, $_attribute, array($_attributValoare));
        $product->setData($_attributCOD,$attributeValue[0]);    
        $this->logger->notice("Adding attribute value [".$attributeValue[0]."] to [".$_attributCOD."] for product [".$_t_sku."]");
    } else {
        $product->setData($_attributCOD,$_attributValoare); 
        $this->logger->notice("Adding attribute value [".$_attributValoare."] to [".$_attributCOD."] for product [".$_t_sku."]");
    }
} catch (\Exception $e) {
    $this->logger->critical($e->getMessage());
}

The function setAttributeValues is doing 

try {
    $this->_option->setValue($numeOptionVal);
    $this->_attributeOptionLabel->setStoreId(0);
    $this->_attributeOptionLabel->setLabel($numeOptionVal);
    $this->_option->setLabel($this->_attributeOptionLabel);
    $this->_option->setStoreLabels([$this->_attributeOptionLabel]);
    $this->_option->setSortOrder(0);
    $this->_option->setIsDefault(false);
    $this->_attributeOptionManagement->add('catalog_product',$attributeID,$this->_option);
} catch (InputException $e) {
    var_dump($e->getMessage());
    $this->logger->error($e->getMessage(), [$e]);
} catch (StateException $e) {
    var_dump($e->getMessage());
    $this->logger->error($e->getMessage(), [$e]);
}

The place in the code where is crashing is on 

 

$this->_attributeOptionManagement->add('catalog_product',$attributeID,$this->_option);

I've looked to debug log and to all the logs, including apache log and nothing. I cannot find any error, but the script is stopping.

 

I've looked deeper into this and I track the problem on 

vendor\magento\module-eav\Model\Entity\Attribute\OptionManagement.php

on function add

$this->setOptionValue($option, $attribute, $optionLabel);

If I look to setOptionValue and is stopping before starting this.

On Magento 2.3.2 this code is working without a problem.

Does anyone has any clue on it?

 

If I replace the file with a previous file version, then is working (is not stopping and is running)

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

namespace Magento\Eav\Model\Entity\Attribute;

use Magento\Framework\Exception\InputException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Exception\StateException;

/**
 * Eav Option Management
 */
class OptionManagement implements \Magento\Eav\Api\AttributeOptionManagementInterface
{
    /**
     * @var \Magento\Eav\Model\AttributeRepository
     */
    protected $attributeRepository;

    /**
     * @var \Magento\Eav\Model\ResourceModel\Entity\Attribute
     */
    protected $resourceModel;

    /**
     * @param \Magento\Eav\Model\AttributeRepository $attributeRepository
     * @param \Magento\Eav\Model\ResourceModel\Entity\Attribute $resourceModel
     * @codeCoverageIgnore
     */
    public function __construct(
        \Magento\Eav\Model\AttributeRepository $attributeRepository,
        \Magento\Eav\Model\ResourceModel\Entity\Attribute $resourceModel
    ) {
        $this->attributeRepository = $attributeRepository;
        $this->resourceModel = $resourceModel;
    }

    /**
     * @inheritdoc
     */
    public function add($entityType, $attributeCode, $option)
    {
        if (empty($attributeCode)) {
            throw new InputException(__('The attribute code is empty. Enter the code and try again.'));
        }
        $attribute = $this->attributeRepository->get($entityType, $attributeCode);
        if (!$attribute->usesSource()) {
            throw new StateException(__('The "%1" attribute doesn\'t work with options.', $attributeCode));
        }
        $optionLabel = $option->getLabel();
        $optionId = $this->getOptionId($option);
        $options = [];
        $options['value'][$optionId][0] = $optionLabel;
        $options['order'][$optionId] = $option->getSortOrder();
        if (is_array($option->getStoreLabels())) {
            foreach ($option->getStoreLabels() as $label) {
                $options['value'][$optionId][$label->getStoreId()] = $label->getLabel();
            }
        }
        if ($option->getIsDefault()) {
            $attribute->setDefault([$optionId]);
        }
        $attribute->setOption($options);
        try {
            $this->resourceModel->save($attribute);
                $this->setOptionValue($option, $attribute, $optionLabel);
        } catch (\Exception $e) {
            throw new StateException(__('The "%1" attribute can\'t be saved.', $attributeCode));
        }
    
        return $this->getOptionId($option);
    }

    /**
     * @inheritdoc
     */
    public function delete($entityType, $attributeCode, $optionId)
    {
        if (empty($attributeCode)) {
            throw new InputException(__('The attribute code is empty. Enter the code and try again.'));
        }

        $attribute = $this->attributeRepository->get($entityType, $attributeCode);
        if (!$attribute->usesSource()) {
            throw new StateException(__('The "%1" attribute has no option.', $attributeCode));
        }
        $this->validateOption($attribute, $optionId);

        $removalMarker = [
            'option' => [
                'value' => [$optionId => []],
                'delete' => [$optionId => '1'],
            ],
        ];
        $attribute->addData($removalMarker);
        try {
            $this->resourceModel->save($attribute);
        } catch (\Exception $e) {
            throw new StateException(__('The "%1" attribute can\'t be saved.', $attributeCode));
        }

        return true;
    }

    /**
     * @inheritdoc
     */
    public function getItems($entityType, $attributeCode)
    {
        if (empty($attributeCode)) {
            throw new InputException(__('The attribute code is empty. Enter the code and try again.'));
        }
        $attribute = $this->attributeRepository->get($entityType, $attributeCode);

        try {
            $options = $attribute->getOptions();
        } catch (\Exception $e) {
            throw new StateException(__('The options for "%1" attribute can\'t be loaded.', $attributeCode));
        }

        return $options;
    }

    /**
     * Validate option
     *
     * @param \Magento\Eav\Api\Data\AttributeInterface $attribute
     * @param int $optionId
     * @throws NoSuchEntityException
     * @return void
     */
    protected function validateOption($attribute, $optionId)
    {
        if ($attribute->getSource()->getOptionText($optionId) === false) {
            throw new NoSuchEntityException(
                __(
                    'The "%1" attribute doesn\'t include an option with "%2" ID.',
                    $attribute->getAttributeCode(),
                    $optionId
                )
            );
        }
    }

    /**
     * Returns option id
     *
     * @param \Magento\Eav\Api\Data\AttributeOptionInterface $option
     * @return string
     */
    private function getOptionId(\Magento\Eav\Api\Data\AttributeOptionInterface $option) : string
    {
        return 'id_' . ($option->getValue() ?: 'new_option');
    }

    /**
     * Set option value
     *
     * @param \Magento\Eav\Api\Data\AttributeOptionInterface $option
     * @param \Magento\Eav\Api\Data\AttributeInterface $attribute
     * @param string $optionLabel
     * @return void
     */
    private function setOptionValue(
        \Magento\Eav\Api\Data\AttributeOptionInterface $option,
        \Magento\Eav\Api\Data\AttributeInterface $attribute,
        string $optionLabel
    ) {
        $optionId = $attribute->getSource()->getOptionId($optionLabel);
        if ($optionId) {
            $option->setValue($attribute->getSource()->getOptionId($optionId));
        } elseif (is_array($option->getStoreLabels())) {
            foreach ($option->getStoreLabels() as $label) {
                if ($optionId = $attribute->getSource()->getOptionId($label->getLabel())) {
                    $option->setValue($attribute->getSource()->getOptionId($optionId));
                    break;
                }
            }
        }
    }
}
2 REPLIES 2

Re: Magento 2.3.4 - Add attribut value programatically

Can someone help with this?

Re: Magento 2.3.4 - Add attribut value programatically

Hi,

 

I had the same issue when upgrading from 2.1. to 2.3.4

In my case the error was:

 

PHP Fatal error: Uncaught TypeError: Argument 3 passed to Magento\\Eav\\Model\\Entity\\Attribute\\OptionManagement::setOptionValue() must be of the type string, object given

 

If you think you are in the same case you can try to change your line:

$this->_option->setLabel($this->_attributeOptionLabel);

 to:

$this->_option->setLabel($this->_attributeOptionLabel->getLabel());