Jak dodać pole do niestandardowych opcji w Magento 2?
Opublikowany: 2019-07-16Wszyscy wiecie, jak wygodne jest korzystanie z konfigurowalnych opcji produktów. Dysponujemy potężnym pakietem Advanced Product Options Suite, który radykalnie rozszerza standardową funkcjonalność opcji dostosowywanych. Pola niestandardowe są podstawą niektórych funkcji rozszerzenia. Pola te są dodawane do określonych typów opcji, takich jak pole wyboru lub obszar tekstowy.
W artykule postaram się wyjaśnić, jak szybko i łatwo dodać potrzebne pola do bazy danych i panelu administracyjnego. Miejmy wgląd.
1. Utwórz nowy moduł
Najpierw utwórzmy moduł MageWorx_Option. Zrobimy to wszystko na przykładzie tego modułu.
Stwórzmy następujący katalog: app/code/MageWorx/Option. Aby zarejestrować moduł, będziemy potrzebować kilku standardowych plików:
<?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. Dodaj nasze nowe pola do bazy danych
Na przykład, chcemy jakoś podświetlić jedną z opcji na interfejsie. Dodajmy pole wyboru dla opcji „To oferta specjalna” oraz pole tekstowe „Opis” dla wartości opcji do wyboru (lista rozwijana, pole wyboru, przycisk opcji, wybór wielokrotny).
Najpierw musimy dodać go do bazy danych w odpowiednich tabelach. W tym celu dodaj następujący plik: 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(); } }
Pole „To oferta specjalna” będzie domyślnie wyłączone.
Następnie możemy zainstalować moduł.
W tym celu uruchom w konsoli następujące polecenia:
sudo -u www-data php bin/magento module:enable MageWorx_Option sudo -u www-data php bin/magento setup:upgrade
3. Dodaj logikę do pracy z backendem
W tym miejscu dodajmy do naszego modułu mechanizm modyfikatorów puli, za pomocą którego Magento 2 łączy wszystkie niezbędne funkcje na stronie produktu w panelu administracyjnym.
W tym celu dodajmy następujący plik:
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>
Teraz nadszedł czas, aby utworzyć naszą klasę MageWorx\Option\Ui\DataProvider\Product\Form\Modifier\All, która sama nie dodaje niczego nowego do formularza Opcje dostosowywania na stronie produktu. Za pomocą wstrzykiwania zależności (DI) doda niezbędne pola na stronie produktu.
W rzeczywistości nasz pakiet Advanced Product Options Suite dodaje około 40 pól i innych złożonych struktur, które są dodawane za pomocą ponad 10 pakietów zawartych w rozszerzeniu. Ponieważ nie potrzebujemy tutaj tak złożonej struktury, użyjemy tylko jednego modyfikatora klasy ―
MageWorx\Option\Ui\DataProvider\Product\Form\Modifier\Base.
Możesz się zastanawiać, dlaczego podajemy następujące sort_order = 71. To wszystko można wytłumaczyć standardową funkcjonalnością Magento 2, gdzie pola dla opcji dostosowywanych są dodawane pod sort_order = 70.
Poniżej przyjrzyjmy się klasie MageWorx\Option\Ui\DataProvider\Product\Form\Modifier\All, która jest prezentowana przez zwykły iterator:
app/kod/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; } }
W zasadzie nadszedł czas na stworzenie pliku, który doda nasze pola do formularza Opcje dostosowywania:
app/kod/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 ], ], ], ]; } }
To, co musimy tutaj zrobić, to rekursywnie dodać niezbędną konfigurację dla pól „To oferta specjalna” i „Opis” we właściwym miejscu. Zwróć uwagę na dwie ostatnie metody, które faktycznie realizują konfigurację dodanych pól. W przypadku „Jest to oferta specjalna” zaznaczamy pole wyboru, a w przypadku „Opisu” wpisujemy tekst.
Ponieważ nasze pola w bazie znajdują się w polach 'catalog_product_option' i 'catalog_product_option_type_value', Magento 2 doda je do formularza pod warunkiem, że poprawnie określimy 'dataScope' .
Ważne jest, aby używać różnych 'sortOrder', aby uniknąć zastępowania standardowych pól opcji dostosowywanych. Po zabawie z różnymi wariantami 'sortOrder' możesz ułożyć pola w kolejności, która najbardziej Ci odpowiada.
Poza tym konfiguracja pól pozwala na dodawanie różnych walidacji inline. Na przykład w naszym rozszerzeniu Zaawansowane opcje produktu pole „Koszt” jest zaimplementowane w następujący sposób:
'label' => __('Cost'), 'componentType' => Field::NAME, 'formElement' => Input::NAME, 'dataScope' => 'cost', 'dataType' => Number::NAME, 'validation' => [ 'validate-number' => true, 'validate-zero-or-greater' => true, ]
Następnie wyczyść pamięć podręczną:
sudo -u www-data php bin/magento cache: czyste
Pozostaje już tylko otworzyć interesujący nas produkt, wypełnić niezbędne pola i go zapisać. Ostateczny wynik będzie wyglądał mniej więcej tak:
Zakończyć
Magento 2 oferuje niezwykle wygodny mechanizm rozszerzania konfigurowalnych opcji o praktycznie nieograniczoną funkcjonalność. Właśnie to chętnie wykorzystujemy w naszym rozszerzeniu i na pewno Wam polecamy.