しかし、正しい解決策はUIフォームの使用基準から逸脱せず、そのネイティブ要素とコンポーネントを利用することではないため、これは完全に正しくはありません。この場合、すべてが自動的に処理されるため、そのようなことを心配する必要はありません。
コンテンツを追加します。追加するためのUIフォームのメタデータと仮想タイプ。
ファイルを作成しますapp/code/Vendor/Product/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\Catalog\Ui\DataProvider\Product\Form\Modifier\Pool">
<arguments>
<argument name="modifiers" xsi:type="array">
<item name="custom-fieldset" xsi:type="array">
<item name="class" xsi:type="string">Vendor\Product\Ui\DataProvider\Product\Form\Modifier\CustomFieldset</item>
<item name="sortOrder" xsi:type="number">10</item>
</item>
</argument>
</arguments>
</virtualType>
</config>
次に、app/code/Vendor/Product/Ui/DataProvider/Product/Form/Modifier/CustomFieldset.php
製品編集ページのカスタムフィールドセットを含むモディファイアファイル()を作成し、フィールドに入力します。
<?php
namespace Vendor\Product\Ui\DataProvider\Product\Form\Modifier;
use Magento\Catalog\Model\Locator\LocatorInterface;
use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier;
use Magento\Framework\Stdlib\ArrayManager;
use Magento\Framework\UrlInterface;
use Magento\Ui\Component\Container;
use Magento\Ui\Component\Form\Fieldset;
use Magento\Ui\Component\Form\Element\DataType\Number;
use Magento\Ui\Component\Form\Element\DataType\Text;
use Magento\Ui\Component\Form\Element\Input;
use Magento\Ui\Component\Form\Element\Select;
use Magento\Ui\Component\Form\Element\MultiSelect;
use Magento\Ui\Component\Form\Field;
class CustomFieldset extends AbstractModifier
{
// Components indexes
const CUSTOM_FIELDSET_INDEX = 'custom_fieldset';
const CUSTOM_FIELDSET_CONTENT = 'custom_fieldset_content';
const CONTAINER_HEADER_NAME = 'custom_fieldset_content_header';
// Fields names
const FIELD_NAME_TEXT = 'example_text_field';
const FIELD_NAME_SELECT = 'example_select_field';
const FIELD_NAME_MULTISELECT = 'example_multiselect_field';
/**
* @var \Magento\Catalog\Model\Locator\LocatorInterface
*/
protected $locator;
/**
* @var ArrayManager
*/
protected $arrayManager;
/**
* @var UrlInterface
*/
protected $urlBuilder;
/**
* @var array
*/
protected $meta = [];
/**
* @param LocatorInterface $locator
* @param ArrayManager $arrayManager
* @param UrlInterface $urlBuilder
*/
public function __construct(
LocatorInterface $locator,
ArrayManager $arrayManager,
UrlInterface $urlBuilder
) {
$this->locator = $locator;
$this->arrayManager = $arrayManager;
$this->urlBuilder = $urlBuilder;
}
/**
* Data modifier, does nothing in our example.
*
* @param array $data
* @return array
*/
public function modifyData(array $data)
{
return $data;
}
/**
* Meta-data modifier: adds ours fieldset
*
* @param array $meta
* @return array
*/
public function modifyMeta(array $meta)
{
$this->meta = $meta;
$this->addCustomFieldset();
return $this->meta;
}
/**
* Merge existing meta-data with our meta-data (do not overwrite it!)
*
* @return void
*/
protected function addCustomFieldset()
{
$this->meta = array_merge_recursive(
$this->meta,
[
static::CUSTOM_FIELDSET_INDEX => $this->getFieldsetConfig(),
]
);
}
/**
* Declare ours fieldset config
*
* @return array
*/
protected function getFieldsetConfig()
{
return [
'arguments' => [
'data' => [
'config' => [
'label' => __('Fieldset Title'),
'componentType' => Fieldset::NAME,
'dataScope' => static::DATA_SCOPE_PRODUCT, // save data in the product data
'provider' => static::DATA_SCOPE_PRODUCT . '_data_source',
'ns' => static::FORM_NAME,
'collapsible' => true,
'sortOrder' => 10,
'opened' => true,
],
],
],
'children' => [
static::CONTAINER_HEADER_NAME => $this->getHeaderContainerConfig(10),
static::FIELD_NAME_TEXT => $this->getTextFieldConfig(20),
static::FIELD_NAME_SELECT => $this->getSelectFieldConfig(30),
static::FIELD_NAME_MULTISELECT => $this->getMultiSelectFieldConfig(40),
],
];
}
/**
* Get config for header container
*
* @param int $sortOrder
* @return array
*/
protected function getHeaderContainerConfig($sortOrder)
{
return [
'arguments' => [
'data' => [
'config' => [
'label' => null,
'formElement' => Container::NAME,
'componentType' => Container::NAME,
'template' => 'ui/form/components/complex',
'sortOrder' => $sortOrder,
'content' => __('You can write any text here'),
],
],
],
'children' => [],
];
}
/**
* Example text field config
*
* @param $sortOrder
* @return array
*/
protected function getTextFieldConfig($sortOrder)
{
return [
'arguments' => [
'data' => [
'config' => [
'label' => __('Example Text Field'),
'formElement' => Field::NAME,
'componentType' => Input::NAME,
'dataScope' => static::FIELD_NAME_TEXT,
'dataType' => Number::NAME,
'sortOrder' => $sortOrder,
],
],
],
];
}
/**
* Example select field config
*
* @param $sortOrder
* @return array
*/
protected function getSelectFieldConfig($sortOrder)
{
return [
'arguments' => [
'data' => [
'config' => [
'label' => __('Options Select'),
'componentType' => Field::NAME,
'formElement' => Select::NAME,
'dataScope' => static::FIELD_NAME_SELECT,
'dataType' => Text::NAME,
'sortOrder' => $sortOrder,
'options' => $this->_getOptions(),
'visible' => true,
'disabled' => false,
],
],
],
];
}
/**
* Example multi-select field config
*
* @param $sortOrder
* @return array
*/
protected function getMultiSelectFieldConfig($sortOrder)
{
return [
'arguments' => [
'data' => [
'config' => [
'label' => __('Options Multiselect'),
'componentType' => Field::NAME,
'formElement' => MultiSelect::NAME,
'dataScope' => static::FIELD_NAME_MULTISELECT,
'dataType' => Text::NAME,
'sortOrder' => $sortOrder,
'options' => $this->_getOptions(),
'visible' => true,
'disabled' => false,
],
],
],
];
}
/**
* Get example options as an option array:
* [
* label => string,
* value => option_id
* ]
*
* @return array
*/
protected function _getOptions()
{
$options = [
1 => [
'label' => __('Option 1'),
'value' => 1
],
2 => [
'label' => __('Option 2'),
'value' => 2
],
3 => [
'label' => __('Option 3'),
'value' => 3
],
];
return $options;
}
}
データの保存はvendor/magento/module-catalog/Controller/Adminhtml/Product/Save.php
、メインの実行メソッドの製品コントローラーファイル内で行われます
。すべてが正しい方法で行われた場合、データはこのメソッドの入力データに正しく表示されます。
製品に最初からこれらの属性がない場合は、手動で保存する必要があります。オブザーバーでこれを行うことができます。
まず、app/code/Vendor/Product/etc/adminhtml/events.xml
ファイルで宣言し
ます(フォームがフロントエンドに存在しないため、adminhtmlスコープを使用しています)。
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name="catalog_product_save_after">
<observer name="save_example_data" instance="Vendor\Product\Observer\ProductSaveAfter" />
</event>
</config>
次に、インスタンス属性でポイントしたオブザーバーのクラスを作成します– app/code/Vendor/Product/Observer/ProductSaveAfter.php
:
<?php
namespace Vendor\Product\Observer;
use \Magento\Framework\Event\ObserverInterface;
use \Magento\Framework\Event\Observer as EventObserver;
use Vendor\Product\Ui\DataProvider\Product\Form\Modifier\CustomFieldset;
class ProductSaveAfter implements ObserverInterface
{
/**
* @param EventObserver $observer
*/
public function execute(\Magento\Framework\Event\Observer $observer)
{
/** @var \Magento\Catalog\Model\Product $product */
$product = $observer->getEvent()->getProduct();
if (!$product) {
return;
}
$exampleTextField = $product->getData(CustomFieldset::FIELD_NAME_TEXT);
$exampleSelectField = $product->getData(CustomFieldset::FIELD_NAME_SELECT);
$exampleMultiSelectField = $product->getData(CustomFieldset::FIELD_NAME_MULTISELECT);
// Manipulate data here
}
}
オブザーバーのデータ:
これで、オブザーバーから独自のモデルを呼び出してデータを保存したり、必要に応じて変更したりできます。
注意してください!モデルの保存が製品の保存と関連している場合、再帰につながる可能性があります。