วิธีที่ถูกต้อง (เป็นทางการ) ในการเพิ่มตัวเลือกคุณลักษณะของผลิตภัณฑ์ใน M2 คืออะไร เช่นสำหรับmanufacturer
คุณสมบัติของผลิตภัณฑ์ ตัวเลือกที่มีอยู่ชัดเจนจะถูกจับคู่โดยค่าชื่อ "ผู้ดูแลระบบ"
วิธีที่ถูกต้อง (เป็นทางการ) ในการเพิ่มตัวเลือกคุณลักษณะของผลิตภัณฑ์ใน M2 คืออะไร เช่นสำหรับmanufacturer
คุณสมบัติของผลิตภัณฑ์ ตัวเลือกที่มีอยู่ชัดเจนจะถูกจับคู่โดยค่าชื่อ "ผู้ดูแลระบบ"
คำตอบ:
นี่คือวิธีที่ฉันใช้ในการจัดการตัวเลือกคุณลักษณะ ระดับผู้ช่วย:
<?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');
หาก 'ABC Corp' เป็นผู้ผลิตที่มีอยู่ก็จะดึง ID ถ้าไม่มันจะเพิ่ม
ปรับปรุง 2016-09-09:ต่อ Ruud N. โซลูชันดั้งเดิมใช้ CatalogSetup ซึ่งทำให้เกิดข้อผิดพลาดใน Magento 2.1 โซลูชันที่แก้ไขนี้จะข้ามโมเดลนั้นโดยสร้างตัวเลือกและติดป้ายกำกับอย่างชัดเจน ควรใช้กับ 2.0+
Magento\Eav\Model\ResourceModel\Entity\Attribute::_processAttributeOptions
ปัญหาบางอย่างเกิดจากการดำเนินงานของ ดูด้วยตัวคุณเองถ้าคุณลบ$option->setValue($label);
คำสั่งจากรหัสของคุณมันจะบันทึกตัวเลือกจากนั้นเมื่อคุณดึงออกมาวีโอไอพีจะคืนค่าจากการเพิ่มขึ้นอัตโนมัติใน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');
จากนั้นเราต้องสร้างอาร์เรย์ตัวเลือกในแบบที่วีโอไอพีคาดหวัง:
$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);
การใช้วีโอไอพี \ Eav \ Setup \ EavSetupFactory หรือแม้กระทั่ง \ วีโอไอพี \ ระดับแคตตาล็อก \ 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; คุณไม่ควรฉีดยาโดยตรง วิธีที่เหมาะสมคือการฉีดคลาสโรงงานจากนั้นสร้างอินสแตนซ์ตามต้องการ นอกจากนี้โปรดทราบว่าคุณไม่ได้ใช้อินเทอร์เฟซข้อมูล API อย่างสม่ำเสมอ
$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; }
เพิ่มคุณสมบัติในฟังก์ชั่น Apply ()
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 มีลักษณะเหมือน admin / catalog / product_attribute / edit / attribute_id / XXX / key .. )
ไปที่คอนโซลเบราว์เซอร์ (CTRL + SHIFT + J บนโครเมี่ยม) และวางรหัสต่อไปนี้หลังจากเปลี่ยน mimim
$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);
});
- ทดสอบบน Magento 2.2.2
บทความโดยละเอียด - https://tutes.in/how-to-manage-magento-2-product-attribute-values-options-using-console/