Come aggiungere un campo alle opzioni personalizzate in Magento 2?
Pubblicato: 2019-07-16Sapete tutti quanto sia conveniente utilizzare le opzioni personalizzabili dei prodotti. Abbiamo una potente suite di opzioni di prodotto avanzate che espande drasticamente la funzionalità standard delle opzioni personalizzabili. I campi personalizzati sono la base di alcune delle funzionalità dell'estensione. Questi campi vengono aggiunti a tipi di opzioni specifici, come una casella di controllo o un'area di testo.
Nell'articolo, farò del mio meglio per spiegare come aggiungere i campi necessari al database e al pannello di amministrazione in modo semplice e veloce. Diamo un'idea.
1. Crea un nuovo modulo
Per prima cosa, creiamo un modulo MageWorx_Option. Faremo tutto usando questo modulo come esempio.
Creiamo la seguente directory: app/code/MageWorx/Option. Per registrare un modulo, avremo bisogno di alcuni file 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. Aggiungi i nostri nuovi campi al database
Ad esempio, desideriamo evidenziare in qualche modo una delle opzioni sul front-end. Aggiungiamo un campo checkbox per un'opzione "È un'offerta speciale" e un campo di testo "Descrizione" per i valori delle opzioni selezionabili (menu a discesa, checkbox, pulsante di opzione, selezione multipla).
Innanzitutto, dovremo aggiungerlo al database nelle tabelle corrispondenti. Per questo, aggiungi il seguente file: 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(); } }
Il campo "È un'offerta speciale" sarà disabilitato per impostazione predefinita.
Successivamente, possiamo installare il modulo.
Per farlo, esegui i seguenti comandi nella console:
sudo -u www-data php bin/magento module:enable MageWorx_Option sudo -u www-data php bin/magento setup:upgrade
3. Aggiungi la logica per lavorare con il back-end
A questo punto, aggiungiamo il meccanismo dei modificatori di pool al nostro modulo, che Magento 2 utilizza per combinare tutte le funzionalità necessarie su una pagina di prodotto nel pannello di amministrazione.
Per questo, aggiungiamo il seguente file:
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>
Ora è il momento di creare la nostra classe MageWorx\Option\Ui\DataProvider\Product\Form\Modifier\All, che di per sé non aggiunge nulla di nuovo al modulo Opzioni personalizzabili nella pagina del prodotto. Utilizzando l' iniezione di dipendenza (DI), aggiungerà i campi necessari nella pagina del prodotto.
In effetti, la nostra suite di opzioni di prodotto avanzate aggiunge circa 40 campi e altre strutture complesse, che vengono aggiunte con l'aiuto di più di 10 pacchetti inclusi nell'estensione. Poiché qui non abbiamo bisogno di una struttura così complessa, useremo un solo modificatore di classe ―
MageWorx\Option\Ui\DataProvider\Product\Form\Modifier\Base.

Potresti chiederti perché specifichiamo il seguente sort_order = 71. Tutto questo può essere spiegato dalla funzionalità standard di Magento 2, dove i campi per le opzioni personalizzabili vengono aggiunti sotto sort_order = 70.
Di seguito, dai un'occhiata alla classe MageWorx\Option\Ui\DataProvider\Product\Form\Modifier\All, presentata da un normale iteratore:
app/codice/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; } }
Fondamentalmente, ora è il momento di creare un file, che aggiungerà i nostri campi al modulo Opzioni personalizzabili:
app/codice/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 ], ], ], ]; } }
Quello che dobbiamo fare qui è aggiungere ricorsivamente una configurazione necessaria per i campi "Offerta speciale" e "Descrizione" nel posto giusto. Presta attenzione agli ultimi due metodi che effettivamente realizzano la configurazione dei campi aggiunti. Per "È un'offerta speciale usiamo la casella di controllo e per "Descrizione" ― input di testo.
Poiché i nostri campi nel database si trovano nei campi 'catalog_product_option' e 'catalog_product_option_type_value', Magento 2 stesso li aggiungerà al modulo a condizione di specificare correttamente 'dataScope' .
È importante utilizzare 'sortOrder' diversi per evitare di sostituire i campi Opzioni personalizzabili standard. Dopo aver giocato con varie varianti di 'sortOrder', puoi disporre i campi nell'ordine che preferisci.
Inoltre, la configurazione dei campi ti consente di aggiungere varie convalide in linea. Ad esempio, nella nostra estensione Opzioni prodotto avanzate, il campo "Costo" è implementato come segue:
'label' => __('Cost'), 'componentType' => Field::NAME, 'formElement' => Input::NAME, 'dataScope' => 'cost', 'dataType' => Number::NAME, 'validation' => [ 'validate-number' => true, 'validate-zero-or-greater' => true, ]
Quindi, svuota la cache:
sudo -u www-data php bin/magento cache:clean
Non resta che aprire un prodotto che ci interessa, compilare i campi necessari e salvarlo. Il risultato finale sarà qualcosa del genere:

Incartare
Magento 2 offre un meccanismo estremamente conveniente per espandere le opzioni personalizzabili con funzionalità praticamente illimitate. Questo è ciò che utilizziamo con entusiasmo nella nostra estensione e sicuramente ti consigliamo.