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;
}
}
}
}
}
Can someone help with this?
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());