Wie füge ich ein Feld zu benutzerdefinierten Optionen in Magento 2 hinzu?
Veröffentlicht: 2019-07-16Sie alle wissen, wie bequem es ist, die anpassbaren Optionen der Produkte zu nutzen. Wir haben eine leistungsstarke Advanced Product Options Suite, die die Standardfunktionalität der anpassbaren Optionen drastisch erweitert. Benutzerdefinierte Felder bilden die Grundlage einiger Funktionen der Erweiterung. Diese Felder werden bestimmten Optionstypen hinzugefügt, z. B. einem Kontrollkästchen oder einem Textbereich.
In dem Artikel werde ich mein Bestes tun, um zu erklären, wie Sie die erforderlichen Felder schnell und einfach zur Datenbank und zum Admin-Panel hinzufügen können. Lassen Sie uns einen Einblick haben.
1. Erstellen Sie ein neues Modul
Lassen Sie uns zuerst ein MageWorx_Option-Modul erstellen. Wir werden das alles am Beispiel dieses Moduls erledigen.
Lassen Sie uns das folgende Verzeichnis erstellen: app/code/MageWorx/Option. Um ein Modul zu registrieren, benötigen wir einige Standarddateien:
<?php \Magento\Framework\Component\ComponentRegistrar::register( \Magento\Framework\Component\ComponentRegistrar::MODULE, 'MageWorx_Option', __DIR__ ); composer.json: { "name": "mageworx/module-option", "description": "N/A", "require": { "magento/module-catalog" : ">=101.0.0 <104", "magento/module-ui" : ">=100.1.0 <102" }, "type": "magento2-module", "version": "1.0.0", "license": [ "OSL-3.0", "AFL-3.0" ], "autoload": { "files": [ "registration.php" ], "psr-4": { "MageWorx\\Option\\": "" } } } module.xml: <?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> <module name="MageWorx_Option" setup_version="1.0.0"> <sequence> <module name="Magento_Catalog"/> <module name="Magento_Ui"/> </sequence> </module> </config>
2. Fügen Sie unsere neuen Felder zur Datenbank hinzu
Zum Beispiel möchten wir eine der Optionen im Frontend irgendwie hervorheben. Lassen Sie uns ein Kontrollkästchenfeld für eine Option „Ist Sonderangebot“ und ein Textfeld „Beschreibung“ für die auswählbaren Optionswerte (Dropdown, Kontrollkästchen, Optionsfeld, Mehrfachauswahl) hinzufügen.
Zuerst müssen wir es der Datenbank in den entsprechenden Tabellen hinzufügen. Fügen Sie dazu die folgende Datei hinzu: app/code/MageWorx/Option/Setup/InstallSchema.php.
<?php namespace MageWorx\Option\Setup; use Magento\Framework\Setup\InstallSchemaInterface; use Magento\Framework\Setup\ModuleContextInterface; use Magento\Framework\Setup\SchemaSetupInterface; use Magento\Framework\DB\Ddl\Table; class InstallSchema implements InstallSchemaInterface { public function install(SchemaSetupInterface $setup, ModuleContextInterface $context) { $setup->startSetup(); $setup->getConnection()->addColumn( $setup->getTable('catalog_product_option'), 'is_special_offer', [ 'type' => Table::TYPE_BOOLEAN, 'unsigned' => true, 'nullable' => false, 'default' => '0', 'comment' => 'Special Offer Flag', ] ); $setup->getConnection()->addColumn( $setup->getTable('catalog_product_option_type_value'), 'description', [ 'type' => Table::TYPE_TEXT, 'nullable' => true, 'default' => null, 'comment' => 'Description', ] ); $setup->endSetup(); } }
Das Feld „Ist Sonderangebot“ ist standardmäßig deaktiviert.
Als nächstes können wir das Modul installieren.
Führen Sie dazu die folgenden Befehle in der Konsole aus:
sudo -u www-data php bin/magento module:enable MageWorx_Option sudo -u www-data php bin/magento setup:upgrade
3. Fügen Sie Logik hinzu, um mit dem Backend zu arbeiten
An dieser Stelle fügen wir unserem Modul den Pool-Modifiers-Mechanismus hinzu, den Magento 2 verwendet, um alle notwendigen Funktionen auf einer Produktseite im Admin-Panel zu kombinieren.
Fügen wir dazu die folgende Datei hinzu:
app/code/MageWorx/Option/etc/adminhtml/di.xml
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <virtualType name="Magento\CatalogStaging\Ui\DataProvider\Product\Form\Modifier\Pool" type="Magento\Ui\DataProvider\Modifier\Pool"> <arguments> <argument name="modifiers" xsi:type="array"> <item name="mageworx-option-all" xsi:type="array"> <item name="class" xsi:type="string">MageWorx\Option\Ui\DataProvider\Product\Form\Modifier\All</item> <item name="sortOrder" xsi:type="number">71</item> </item> </argument> </arguments> </virtualType> <virtualType name="Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Pool" type="Magento\Ui\DataProvider\Modifier\Pool"> <arguments> <argument name="modifiers" xsi:type="array"> <item name="mageworx-option-all" xsi:type="array"> <item name="class" xsi:type="string">MageWorx\Option\Ui\DataProvider\Product\Form\Modifier\All</item> <item name="sortOrder" xsi:type="number">71</item> </item> </argument> </arguments> </virtualType> <virtualType name="MageWorx\Option\Ui\DataProvider\Product\Form\Modifier\Pool" type="Magento\Ui\DataProvider\Modifier\Pool"> <arguments> <argument name="modifiers" xsi:type="array"> </argument> </arguments> </virtualType> <type name="MageWorx\Option\Ui\DataProvider\Product\Form\Modifier\All"> <arguments> <argument name="pool" xsi:type="object">MageWorx\Option\Ui\DataProvider\Product\Form\Modifier\Pool</argument> </arguments> </type> <virtualType name="MageWorx\Option\Ui\DataProvider\Product\Form\Modifier\Pool"> <arguments> <argument name="modifiers" xsi:type="array"> <item name="mageworx-option-base" xsi:type="array"> <item name="class" xsi:type="string">MageWorx\Option\Ui\DataProvider\Product\Form\Modifier\Base</item> <item name="sortOrder" xsi:type="number">72</item> </item> </argument> </arguments> </virtualType> </config>
Jetzt ist es an der Zeit, unsere Klasse MageWorx\Option\Ui\DataProvider\Product\Form\Modifier\All zu erstellen, die dem Formular Anpassbare Optionen auf der Produktseite nichts Neues hinzufügt. Mithilfe der Abhängigkeitsinjektion (DI) werden die erforderlichen Felder auf der Produktseite hinzugefügt.
Tatsächlich fügt unsere Advanced Product Options Suite etwa 40 Felder und andere komplexe Strukturen hinzu, die mit Hilfe von mehr als 10 Paketen hinzugefügt werden, die in der Erweiterung enthalten sind. Da wir hier keine so komplexe Struktur benötigen, verwenden wir nur einen Klassenmodifikator ―
MageWorx\Option\Ui\DataProvider\Product\Form\Modifier\Base.
Sie fragen sich vielleicht, warum wir die folgende sort_order = 71 angeben. Dies alles kann durch die Standardfunktionalität von Magento 2 erklärt werden, wo Felder für anpassbare Optionen unter sort_order = 70 hinzugefügt werden.
Sehen Sie sich unten die Klasse MageWorx\Option\Ui\DataProvider\Product\Form\Modifier\All an, die von einem regulären Iterator präsentiert wird:
app/code/MageWorx/Option/Ui/DataProvider/Product/Form/Modifier/All.php
<?php namespace MageWorx\Option\Ui\DataProvider\Product\Form\Modifier; use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier; use Magento\Ui\DataProvider\Modifier\PoolInterface; class All extends AbstractModifier implements \Magento\Ui\DataProvider\Modifier\ModifierInterface { /** * @var PoolInterface */ protected $pool; /** * @var array */ protected $meta = []; /** * @param PoolInterface $pool */ public function __construct( PoolInterface $pool ) { $this->pool = $pool; } /** * {@inheritdoc} */ public function modifyData(array $data) { /** @var \Magento\Ui\DataProvider\Modifier\ModifierInterface $modifier */ foreach ($this->pool->getModifiersInstances() as $modifier) { $data = $modifier->modifyData($data); } return $data; } /** * {@inheritdoc} */ public function modifyMeta(array $meta) { $this->meta = $meta; /** @var \Magento\Ui\DataProvider\Modifier\ModifierInterface $modifier */ foreach ($this->pool->getModifiersInstances() as $modifier) { $this->meta = $modifier->modifyMeta($this->meta); } return $this->meta; } }
Grundsätzlich ist es jetzt an der Zeit, eine Datei zu erstellen, die unsere Felder zum Formular „Anpassbare Optionen“ hinzufügt:
app/code/MageWorx/Option/Ui/DataProvider/Product/Form/Modifier/Base.php
<?php namespace MageWorx\Option\Ui\DataProvider\Product\Form\Modifier; use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier; use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\CustomOptions; use Magento\Ui\Component\Form\Element\Input; use Magento\Ui\Component\Form\Element\Checkbox; use Magento\Ui\Component\Form\Element\DataType\Text; use Magento\Ui\Component\Form\Field; class Base extends AbstractModifier { /** * @var array */ protected $meta = []; /** * {@inheritdoc} */ public function modifyData(array $data) { return $data; } /** * {@inheritdoc} */ public function modifyMeta(array $meta) { $this->meta = $meta; $this->addFields(); return $this->meta; } /** * Adds fields to the meta-data */ protected function addFields() { $groupCustomOptionsName = CustomOptions::GROUP_CUSTOM_OPTIONS_NAME; $optionContainerName = CustomOptions::CONTAINER_OPTION; $commonOptionContainerName = CustomOptions::CONTAINER_COMMON_NAME; // Add fields to the option $this->meta[$groupCustomOptionsName]['children']['options']['children']['record']['children'] [$optionContainerName]['children'][$commonOptionContainerName]['children'] = array_replace_recursive( $this->meta[$groupCustomOptionsName]['children']['options']['children']['record']['children'] [$optionContainerName]['children'][$commonOptionContainerName]['children'], $this->getOptionFieldsConfig() ); // Add fields to the values $this->meta[$groupCustomOptionsName]['children']['options']['children']['record']['children'] [$optionContainerName]['children']['values']['children']['record']['children'] = array_replace_recursive( $this->meta[$groupCustomOptionsName]['children']['options']['children']['record']['children'] [$optionContainerName]['children']['values']['children']['record']['children'], $this->getValueFieldsConfig() ); } /** * The custom option fields config * * @return array */ protected function getOptionFieldsConfig() { $fields['is_special_offer'] = $this->getSpecialOfferFieldConfig(); return $fields; } /** * The custom option fields config * * @return array */ protected function getValueFieldsConfig() { $fields['description'] = $this->getDescriptionFieldConfig(); return $fields; } /** * Get special offer field config * * @return array */ protected function getSpecialOfferFieldConfig() { return [ 'arguments' => [ 'data' => [ 'config' => [ 'label' => __('Is Special Offer'), 'componentType' => Field::NAME, 'formElement' => Checkbox::NAME, 'dataScope' => 'is_special_offer', 'dataType' => Text::NAME, 'sortOrder' => 65, 'valueMap' => [ 'true' => '1', 'false' => '0' ], ], ], ], ]; } /** * Get description field config * * @return array */ protected function getDescriptionFieldConfig() { return [ 'arguments' => [ 'data' => [ 'config' => [ 'label' => __('Description'), 'componentType' => Field::NAME, 'formElement' => Input::NAME, 'dataType' => Text::NAME, 'dataScope' => 'description', 'sortOrder' => 41 ], ], ], ]; } }
Was wir hier tun müssen, ist rekursiv eine notwendige Konfiguration für die Felder „Ist Sonderangebot“ und „Beschreibung“ an der richtigen Stelle hinzuzufügen. Achten Sie auf die letzten beiden Methoden, die die Konfiguration der hinzugefügten Felder tatsächlich realisieren. Für „Ist ein Sonderangebot verwenden wir das Kontrollkästchen und für „Beschreibung“ – Texteingabe.
Da sich unsere Felder in der Datenbank in den Feldern „catalog_product_option“ und „catalog_product_option_type_value“ befinden, fügt Magento 2 sie selbst zum Formular hinzu, vorausgesetzt, wir geben „dataScope“ korrekt an.
Es ist wichtig, eine andere „sortOrder“ zu verwenden, um zu vermeiden, dass die Standardfelder für anpassbare Optionen ersetzt werden. Nachdem Sie mit verschiedenen 'sortOrder'-Varianten herumgespielt haben, können Sie die Felder in der für Sie am besten geeigneten Reihenfolge anordnen.
Außerdem können Sie mit der Feldkonfiguration verschiedene Inline-Validierungen hinzufügen. In unserer Erweiterung "Erweiterte Produktoptionen" ist das Feld "Kosten" beispielsweise wie folgt implementiert:
'label' => __('Cost'), 'componentType' => Field::NAME, 'formElement' => Input::NAME, 'dataScope' => 'cost', 'dataType' => Number::NAME, 'validation' => [ 'validate-number' => true, 'validate-zero-or-greater' => true, ]
Dann Cache leeren:
sudo -u www-data php bin/magento cache:clean
Jetzt müssen wir nur noch ein Produkt öffnen, an dem wir interessiert sind, die erforderlichen Felder ausfüllen und speichern. Das Endergebnis wird in etwa so aussehen:
Einpacken
Magento 2 bietet einen äußerst komfortablen Mechanismus zur Erweiterung anpassbarer Optionen mit praktisch unbegrenzter Funktionalität. Das verwenden wir gerne in unserer Erweiterung und empfehlen Sie auf jeden Fall weiter.