जवाबों:
यहां वह दृष्टिकोण है जो मैं विशेषता विकल्पों को संभालने के लिए आया हूं। सहायक वर्ग:
<?php
namespace My\Module\Helper;
class Data extends \Magento\Framework\App\Helper\AbstractHelper
{
/**
* @var \Magento\Catalog\Api\ProductAttributeRepositoryInterface
*/
protected $attributeRepository;
/**
* @var array
*/
protected $attributeValues;
/**
* @var \Magento\Eav\Model\Entity\Attribute\Source\TableFactory
*/
protected $tableFactory;
/**
* @var \Magento\Eav\Api\AttributeOptionManagementInterface
*/
protected $attributeOptionManagement;
/**
* @var \Magento\Eav\Api\Data\AttributeOptionLabelInterfaceFactory
*/
protected $optionLabelFactory;
/**
* @var \Magento\Eav\Api\Data\AttributeOptionInterfaceFactory
*/
protected $optionFactory;
/**
* Data constructor.
*
* @param \Magento\Framework\App\Helper\Context $context
* @param \Magento\Catalog\Api\ProductAttributeRepositoryInterface $attributeRepository
* @param \Magento\Eav\Model\Entity\Attribute\Source\TableFactory $tableFactory
* @param \Magento\Eav\Api\AttributeOptionManagementInterface $attributeOptionManagement
* @param \Magento\Eav\Api\Data\AttributeOptionLabelInterfaceFactory $optionLabelFactory
* @param \Magento\Eav\Api\Data\AttributeOptionInterfaceFactory $optionFactory
*/
public function __construct(
\Magento\Framework\App\Helper\Context $context,
\Magento\Catalog\Api\ProductAttributeRepositoryInterface $attributeRepository,
\Magento\Eav\Model\Entity\Attribute\Source\TableFactory $tableFactory,
\Magento\Eav\Api\AttributeOptionManagementInterface $attributeOptionManagement,
\Magento\Eav\Api\Data\AttributeOptionLabelInterfaceFactory $optionLabelFactory,
\Magento\Eav\Api\Data\AttributeOptionInterfaceFactory $optionFactory
) {
parent::__construct($context);
$this->attributeRepository = $attributeRepository;
$this->tableFactory = $tableFactory;
$this->attributeOptionManagement = $attributeOptionManagement;
$this->optionLabelFactory = $optionLabelFactory;
$this->optionFactory = $optionFactory;
}
/**
* Get attribute by code.
*
* @param string $attributeCode
* @return \Magento\Catalog\Api\Data\ProductAttributeInterface
*/
public function getAttribute($attributeCode)
{
return $this->attributeRepository->get($attributeCode);
}
/**
* Find or create a matching attribute option
*
* @param string $attributeCode Attribute the option should exist in
* @param string $label Label to find or add
* @return int
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function createOrGetId($attributeCode, $label)
{
if (strlen($label) < 1) {
throw new \Magento\Framework\Exception\LocalizedException(
__('Label for %1 must not be empty.', $attributeCode)
);
}
// Does it already exist?
$optionId = $this->getOptionId($attributeCode, $label);
if (!$optionId) {
// If no, add it.
/** @var \Magento\Eav\Model\Entity\Attribute\OptionLabel $optionLabel */
$optionLabel = $this->optionLabelFactory->create();
$optionLabel->setStoreId(0);
$optionLabel->setLabel($label);
$option = $this->optionFactory->create();
$option->setLabel($optionLabel);
$option->setStoreLabels([$optionLabel]);
$option->setSortOrder(0);
$option->setIsDefault(false);
$this->attributeOptionManagement->add(
\Magento\Catalog\Model\Product::ENTITY,
$this->getAttribute($attributeCode)->getAttributeId(),
$option
);
// Get the inserted ID. Should be returned from the installer, but it isn't.
$optionId = $this->getOptionId($attributeCode, $label, true);
}
return $optionId;
}
/**
* Find the ID of an option matching $label, if any.
*
* @param string $attributeCode Attribute code
* @param string $label Label to find
* @param bool $force If true, will fetch the options even if they're already cached.
* @return int|false
*/
public function getOptionId($attributeCode, $label, $force = false)
{
/** @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attribute */
$attribute = $this->getAttribute($attributeCode);
// Build option array if necessary
if ($force === true || !isset($this->attributeValues[ $attribute->getAttributeId() ])) {
$this->attributeValues[ $attribute->getAttributeId() ] = [];
// We have to generate a new sourceModel instance each time through to prevent it from
// referencing its _options cache. No other way to get it to pick up newly-added values.
/** @var \Magento\Eav\Model\Entity\Attribute\Source\Table $sourceModel */
$sourceModel = $this->tableFactory->create();
$sourceModel->setAttribute($attribute);
foreach ($sourceModel->getAllOptions() as $option) {
$this->attributeValues[ $attribute->getAttributeId() ][ $option['label'] ] = $option['value'];
}
}
// Return option ID if exists
if (isset($this->attributeValues[ $attribute->getAttributeId() ][ $label ])) {
return $this->attributeValues[ $attribute->getAttributeId() ][ $label ];
}
// Return false if does not exist
return false;
}
}
फिर, एक ही कक्षा में या इसे निर्भरता इंजेक्शन के माध्यम से शामिल करके, आप कॉल करके अपना विकल्प आईडी जोड़ या प्राप्त कर सकते हैं createOrGetId($attributeCode, $label)
।
उदाहरण के लिए, यदि आप इंजेक्षन My\Module\Helper\Data
के रूप में $this->moduleHelper
है, तो आप कॉल कर सकते हैं:
$manufacturerId = $this->moduleHelper->createOrGetId('manufacturer', 'ABC Corp');
यदि 'एबीसी कॉर्प' एक मौजूदा निर्माता है, तो यह आईडी खींच देगा। यदि नहीं, तो इसे जोड़ देगा।
अद्यतन 2016-09-09: रूड एन के अनुसार, मूल समाधान कैटलॉगसेटअप का उपयोग करता था, जिसके परिणामस्वरूप मैगेंटो 2.1 में एक बग शुरू हुआ। यह संशोधित समाधान उस मॉडल को बायपास करता है, जिससे विकल्प और लेबल स्पष्ट रूप से बनते हैं। इसे 2.0+ पर काम करना चाहिए।
Magento\Eav\Model\ResourceModel\Entity\Attribute::_processAttributeOptions
। अपने लिए देखें, यदि आप $option->setValue($label);
अपने कोड से स्टेटमेंट को हटाते हैं, तो यह विकल्प को बचाएगा, तब जब आप इसे प्राप्त करेंगे तो Magento eav_attribute_option
टेबल पर एक ऑटो-इन्क्रीमेंट से मान लौटा देगा ।
Magento 2.1.3 पर परीक्षण किया गया।
मुझे कोई व्यावहारिक तरीका नहीं मिला कि कैसे एक बार में विकल्पों के साथ विशेषता बनाई जा सके। इसलिए शुरू में हमें एक विशेषता बनाने की जरूरत है और फिर इसके लिए विकल्प जोड़ें।
वर्ग \ Magento \ Eav \ Setup \ EavSetupFactory के बाद इंजेक्षन
$setup->startSetup();
/** @var \Magento\Eav\Setup\EavSetup $eavSetup */
$eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);
$eavSetup->addAttribute(
'catalog_product',
$attributeCode,
[
'type' => 'varchar',
'input' => 'select',
'required' => false,
...
],
);
फ़ंक्शन addAttribute
कुछ भी उपयोगी नहीं देता है जो भविष्य में उपयोग किया जा सकता है। इसलिए विशेषता निर्माण के बाद हमें अपने आप से विशेषता वस्तु को प्राप्त करने की आवश्यकता है। !!! महत्वपूर्ण हमें इसकी आवश्यकता है क्योंकि फ़ंक्शन केवल अपेक्षा करता है attribute_id
, लेकिन इसके साथ काम नहीं करना चाहता attribute_code
।
उस स्थिति में हमें attribute_id
इसे बनाने और इसे पास करने की जरूरत है ताकि इसे बनाने के लिए फंक्शन तैयार किया जा सके।
$attributeId = $eavSetup->getAttributeId('catalog_product', 'attribute_code');
फिर हमें जिस तरह से magento की उम्मीद है, उसमें विकल्प सरणी उत्पन्न करने की आवश्यकता है:
$options = [
'values' => [
'sort_order1' => 'title1',
'sort_order2' => 'title2',
'sort_order3' => 'title3',
],
'attribute_id' => 'some_id',
];
उदाहरण के रूप में:
$options = [
'values' => [
'1' => 'Red',
'2' => 'Yellow',
'3' => 'Green',
],
'attribute_id' => '32',
];
और इसे फंक्शन में पास करें:
$eavSetup->addAttributeOption($options);
Magento \ Eav \ Setup \ EavSetupFactory या यहाँ तक कि \ Magento \ कैटलॉग \ Setup \ CategorySetupFactory वर्ग का उपयोग करने से निम्न समस्या हो सकती है: https://github.com/magento/magento2/issues/4896 ।
आपको जिन वर्गों का उपयोग करना चाहिए:
protected $_logger;
protected $_attributeRepository;
protected $_attributeOptionManagement;
protected $_option;
protected $_attributeOptionLabel;
public function __construct(
\Psr\Log\LoggerInterface $logger,
\Magento\Eav\Model\AttributeRepository $attributeRepository,
\Magento\Eav\Api\AttributeOptionManagementInterface $attributeOptionManagement,
\Magento\Eav\Api\Data\AttributeOptionLabelInterface $attributeOptionLabel,
\Magento\Eav\Model\Entity\Attribute\Option $option
){
$this->_logger = $logger;
$this->_attributeRepository = $attributeRepository;
$this->_attributeOptionManagement = $attributeOptionManagement;
$this->_option = $option;
$this->_attributeOptionLabel = $attributeOptionLabel;
}
फिर अपने फंक्शन में कुछ ऐसा करें:
$attribute_id = $this->_attributeRepository->get('catalog_product', 'your_attribute')->getAttributeId();
$options = $this->_attributeOptionManagement->getItems('catalog_product', $attribute_id);
/* if attribute option already exists, remove it */
foreach($options as $option) {
if ($option->getLabel() == $oldname) {
$this->_attributeOptionManagement->delete('catalog_product', $attribute_id, $option->getValue());
}
}
/* new attribute option */
$this->_option->setValue($name);
$this->_attributeOptionLabel->setStoreId(0);
$this->_attributeOptionLabel->setLabel($name);
$this->_option->setLabel($this->_attributeOptionLabel);
$this->_option->setStoreLabels([$this->_attributeOptionLabel]);
$this->_option->setSortOrder(0);
$this->_option->setIsDefault(false);
$this->_attributeOptionManagement->add('catalog_product', $attribute_id, $this->_option);
$attributeOptionLabel
और $option
ORM वर्ग हैं; आपको उन्हें सीधे इंजेक्ट नहीं करना चाहिए। उचित दृष्टिकोण उनके कारखाने वर्ग को इंजेक्ट करना है, फिर आवश्यकतानुसार एक उदाहरण बनाएं। यह भी ध्यान दें कि आप एपीआई डेटा इंटरफेस का लगातार उपयोग नहीं कर रहे हैं।
$option->setValue()
एक आंतरिक मैगनेटो option_id
फ़ील्ड के लिए कॉल नहीं करना चाहते हैं eav_attribute_option
।
Magento 2.3.3 के लिए मैंने पाया कि आप Magento DevTeam दृष्टिकोण ले सकते हैं।
bin/magento setup:db-declaration:generate-patch Vendor_Module PatchName
public function __construct( ModuleDataSetupInterface $moduleDataSetup, Factory $configFactory CategorySetupFactory $categorySetupFactory ) { $this->moduleDataSetup = $moduleDataSetup; $this->configFactory = $configFactory; $this->categorySetupFactory = $categorySetupFactory; }
लागू करें () फ़ंक्शन में विशेषता जोड़ें
public function apply()
{
$categorySetup = $this->categorySetupFactory->create(['setup' => $this->moduleDataSetup]);
$categorySetup->addAttribute(
\Magento\Catalog\Model\Product::ENTITY,
'custom_layout',
[
'type' => 'varchar',
'label' => 'New Layout',
'input' => 'select',
'source' => \Magento\Catalog\Model\Product\Attribute\Source\Layout::class,
'required' => false,
'sort_order' => 50,
'global' => \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_STORE,
'group' => 'Schedule Design Update',
'is_used_in_grid' => true,
'is_visible_in_grid' => false,
'is_filterable_in_grid' => false
]
);
}
यह मानता है कि आपके पास ब्राउज़र का उपयोग करके Magento Backend तक पहुंच है और आप संपादन विशेषता पृष्ठ पर हैं (url ऐसा लगता है जैसे व्यवस्थापक / कैटलॉग / product_attribute / edit / विशेषता_id / XXX / कुंजी ..)
ब्राउजर कंसोल (क्रोम पर CTRL + SHIFT + J) पर जाएं और ऐरे मिम को बदलने के बाद निम्नलिखित कोड पेस्ट करें ।
$jq=new jQuery.noConflict();
var mimim=["xxx","yyy","VALUES TO BE ADDED"];
$jq.each(mimim,function(a,b){
$jq("#add_new_option_button").click();
$jq("#manage-options-panel tbody tr:last-child td:nth-child(3) input").val(b);
});
- मैगेंटो 2.2.2 पर परीक्षण किया गया
विस्तृत लेख - https://tutes.in/how-to-manage-magento-2-product-attribute-values-options-using-console/