Cum să adăugați un câmp la opțiunile personalizate în Magento 2?
Publicat: 2019-07-16Știți cu toții cât de convenabil este să utilizați opțiunile personalizabile ale produselor. Avem o suită puternică de opțiuni avansate de produs, care extinde drastic funcționalitatea standard a opțiunilor personalizabile. Câmpurile personalizate sunt baza unora dintre funcționalitățile extensiei. Aceste câmpuri sunt adăugate la anumite tipuri de opțiuni, cum ar fi o casetă de selectare sau o zonă de text.
În articol, voi face tot posibilul să explic cum puteți adăuga câmpurile necesare la baza de date și la panoul de administrare rapid și ușor. Să avem o perspectivă.
1. Creați un modul nou
Mai întâi, să creăm un modul MageWorx_Option. Vom termina totul folosind acest modul ca exemplu.
Să creăm următorul director: app/code/MageWorx/Option. Pentru a înregistra un modul, vom avea nevoie de câteva fișiere standard:
<?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. Adăugați noile noastre câmpuri la baza de date
De exemplu, dorim să evidențiem una dintre opțiunile de pe front-end cumva. Să adăugăm un câmp de casetă de selectare pentru o opțiune „Este o ofertă specială” și un câmp de text „Descriere” pentru valorile opțiunilor care pot fi selectate (menu derulant, casetă de selectare, buton radio, selecție multiplă).
Mai întâi, va trebui să-l adăugăm la baza de date în tabelele corespunzătoare. Pentru asta, adăugați următorul fișier: 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(); } }
Câmpul „Este o ofertă specială” va fi dezactivat în mod implicit.
Apoi, putem instala modulul.
Pentru a face acest lucru, rulați următoarele comenzi în consolă:
sudo -u www-data php bin/magento module:enable MageWorx_Option sudo -u www-data php bin/magento setup:upgrade
3. Adăugați o logică pentru a lucra cu backend-ul
În acest moment, să adăugăm mecanismul de modificare a piscinei la modulul nostru, pe care Magento 2 îl folosește pentru a combina toate caracteristicile necesare pe pagina unui produs din panoul de administrare.
Pentru asta, să adăugăm următorul fișier:
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>
Acum, este timpul să creăm clasa noastră MageWorx\Option\Ui\DataProvider\Product\Form\Modifier\All, care nu adaugă nimic nou în formularul Opțiuni personalizabile de pe pagina produsului. Folosind injecția de dependență (DI), va adăuga câmpurile necesare pe pagina produsului.
De fapt, Suita noastră Advanced Product Options adaugă aproximativ 40 de câmpuri și alte structuri complexe, care sunt adăugate cu ajutorul a peste 10 pachete care sunt incluse în extensie. Deoarece nu avem nevoie de o astfel de structură complexă aici, vom folosi un singur modificator de clasă -
MageWorx\Option\Ui\DataProvider\Product\Form\Modifier\Base.
S-ar putea să vă întrebați de ce specificăm următorul sort_order = 71. Toate acestea pot fi explicate prin funcționalitatea standard Magento 2, în care câmpurile pentru Opțiuni personalizabile sunt adăugate sub sort_order = 70.
Mai jos, aruncați o privire la clasa MageWorx\Option\Ui\DataProvider\Product\Form\Modifier\All, care este prezentată de un iterator obișnuit:
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; } }
Practic, acum este momentul să creăm un fișier, care va adăuga câmpurile noastre la formularul Opțiuni personalizabile:
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 ], ], ], ]; } }
Ceea ce trebuie să facem aici este să adăugăm recursiv o configurație necesară pentru câmpurile „Este o ofertă specială” și „Descriere” la locul potrivit. Atenție la ultimele două metode care realizează de fapt configurația câmpurilor adăugate. Pentru „Este o ofertă specială folosim caseta de selectare”, iar pentru „Descriere” – introducerea textului.
Întrucât câmpurile noastre din baza de date sunt situate în câmpurile „catalog_product_option” și „catalog_product_option_type_value”, Magento 2 le va adăuga în formular, cu condiția ca „dataScope” să fie specificat corect.
Este important să folosiți „sortOrder” diferit pentru a evita înlocuirea câmpurilor standard de opțiuni personalizabile. După ce te joci cu diverse variante de „sortOrder”, poți aranja câmpurile în ordinea care ți se potrivește cel mai mult.
În plus, configurația câmpurilor vă permite să adăugați diverse validări inline. De exemplu, în extensia noastră Advanced Product Options, câmpul „Cost” este implementat după cum urmează:
'label' => __('Cost'), 'componentType' => Field::NAME, 'formElement' => Input::NAME, 'dataScope' => 'cost', 'dataType' => Number::NAME, 'validation' => [ 'validate-number' => true, 'validate-zero-or-greater' => true, ]
Apoi, goliți memoria cache:
sudo -u www-data php bin/magento cache:clean
Singurul lucru rămas este să deschidem un produs care ne interesează, să completați câmpurile necesare și să îl salvați. Rezultatul final va arăta cam așa:
Învelire
Magento 2 oferă un mecanism extrem de convenabil de extindere a opțiunilor personalizabile cu funcționalități practic nelimitate. Acesta este ceea ce folosim cu nerăbdare în extensia noastră și cu siguranță vă recomandăm.