Was ist der richtige (offizielle) Weg, um die Produktattributoption in M2 programmgesteuert hinzuzufügen? ZB für manufacturer
Produktattribut. Offensichtlich würde die vorhandene Option mit dem Titelwert "Admin" übereinstimmen.
Hier ist der Ansatz, den ich für den Umgang mit Attributoptionen entwickelt habe. Hilfsklasse:
<?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;
}
}
Anschließend können Sie Ihre Options-ID entweder in derselben Klasse oder über die Abhängigkeitsinjektion hinzufügen oder durch Aufrufen abrufen createOrGetId($attributeCode, $label)
.
Wenn Sie beispielsweise My\Module\Helper\Data
als injizieren $this->moduleHelper
, können Sie Folgendes aufrufen:
$manufacturerId = $this->moduleHelper->createOrGetId('manufacturer', 'ABC Corp');
Wenn 'ABC Corp' ein bestehender Hersteller ist, wird die ID gezogen. Wenn nicht, wird es hinzugefügt.
AKTUALISIERT 2016-09-09: Per Ruud N., die ursprüngliche Lösung verwendete CatalogSetup, was zu einem Fehler führte, der in Magento 2.1 begann. Diese überarbeitete Lösung umgeht dieses Modell und erstellt die Option und die Bezeichnung explizit. Es sollte auf 2.0+ funktionieren.
Magento\Eav\Model\ResourceModel\Entity\Attribute::_processAttributeOptions
. Sehen Sie selbst, wenn Sie die$option->setValue($label);
Anweisung aus Ihrem Code entfernen , wird die Option gespeichert, und wenn Sie sie abrufen, gibt Magento den Wert von einem automatischen Inkrement in dereav_attribute_option
Tabelle zurück.Getestet mit Magento 2.1.3.
Ich habe keine praktikable Möglichkeit gefunden, ein Attribut mit Optionen auf einmal zu erstellen. Zunächst müssen wir ein Attribut erstellen und dann Optionen hinzufügen.
Injizieren Sie die folgende Klasse \ Magento \ Eav \ Setup \ EavSetupFactory
Neues Attribut erstellen:
Fügen Sie benutzerdefinierte Optionen hinzu.
Die Funktion
addAttribute
gibt nichts Nützliches zurück, das in Zukunft verwendet werden kann. Nach der Attributerstellung müssen wir das Attributobjekt also selbst abrufen. !!! Wichtig Wir brauchen es, weil die Funktion nur erwartetattribute_id
, aber nicht damit arbeiten willattribute_code
.In diesem Fall müssen wir sie abrufen
attribute_id
und an die Attributerstellungsfunktion übergeben.Dann müssen wir das options array so generieren, wie es von magento erwartet wird:
Zum Beispiel:
Und übergeben Sie es an Funktion:
quelle
Die Verwendung der Klasse Magento \ Eav \ Setup \ EavSetupFactory oder sogar der Klasse \ Magento \ Catalog \ Setup \ CategorySetupFactory kann zu folgendem Problem führen: https://github.com/magento/magento2/issues/4896 .
Die Klassen, die Sie verwenden sollten:
Dann machen Sie in Ihrer Funktion so etwas:
quelle
$attributeOptionLabel
und$option
ORM-Klassen sind; Sie sollten sie nicht direkt injizieren. Der richtige Ansatz besteht darin, die Factory-Klasse zu injizieren und dann nach Bedarf eine Instanz zu erstellen. Beachten Sie auch, dass Sie die API-Datenschnittstellen nicht konsistent verwenden.$option->setValue()
da dies für ein internes Magento-option_id
Feld in dereav_attribute_option
Tabelle gilt.Für Magento 2.3.3 habe ich festgestellt, dass Sie den Magento DevTeam-Ansatz verwenden können.
Attribut in Funktion apply () hinzufügen
quelle
Dies ist keine Antwort. Nur eine Problemumgehung.
Es wird davon ausgegangen, dass Sie über einen Browser auf Magento Backend zugreifen können und sich auf der Seite zum Bearbeiten von Attributen befinden (die URL sieht aus wie admin / catalog / product_attribute / edit / attribute_id / XXX / key.)
Wechseln Sie zur Browserkonsole (STRG + UMSCHALT + J in Chrome) und fügen Sie den folgenden Code ein, nachdem Sie den Array-Mimim geändert haben .
- getestet auf Magento 2.2.2
Ausführlicher Artikel - https://tutes.in/how-to-manage-magento-2-product-attribute-values-options-using-console/
quelle