Magento 2 Как добавить пользовательские отношения с продуктами?
Мне нужно добавить еще один атрибут связанных продуктов, чтобы связать несколько других продуктов.
Я нашел решение для Magento 1: http://inchoo.net/magento/how-to-add-custom-product-relations-in-magento/
Однако я хотел бы реализовать это в Magento 2. Любое руководство приветствуется.
1 answers
Версия Magento 2.0.x:
Прежде всего, есть несколько примечаний:
--Заменено событие catalog_product_prepare_save
помощником по инициализации продукта контроллера, который можно настроить с помощью плагинов - Vendor/ProductRelation/Model/Product/Initialization/Helper/ProductLinks.php
.
-- Заменил событие catalog_model_product_duplicate
составной моделью Product\Copier
. Однако мы не используем это событие.
-- Нам нужно переопределить \Magento\Catalog\Model\Product\Link\Proxy
- можно найти его в разделе var/generation
.
Теперь давайте начнем создавать наш модуль:
Сценарий установки
Создать сценарий настройки для добавления нового типа ссылки на продукт:
#app/code/Vendor/ProductRelation/Setup/UpgradeData.php
<?php
namespace Vendor\ProductRelation\Setup;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\UpgradeDataInterface;
class UpgradeData implements UpgradeDataInterface
{
/**
* Upgrades DB for a module
*
* @param ModuleDataSetupInterface $setup
* @param ModuleContextInterface $context
* @return void
*/
public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
{
$setup->startSetup();
//Add store_id to catalog_product_link
$productLinkTable = 'catalog_product_link';
$setup->getConnection()
->addColumn(
$setup->getTable($productLinkTable),
'store_id',
[
'type' => \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
'nullable' => false,
'default' => 0,
'comment' => 'Store Id'
]
);
/**
* Install product link types
*/
$data = [
['link_type_id' => \Vendor\ProductRelation\Model\Catalog\Product\Link::LINK_TYPE_CUSTOMTYPE, 'code' => 'customtype']
];
foreach ($data as $bind) {
$setup->getConnection()
->insertForce($setup->getTable('catalog_product_link_type'), $bind);
}
/**
* install product link attributes
*/
$data = [
[
'link_type_id' => \Vendor\ProductRelation\Model\Catalog\Product\Link::LINK_TYPE_CUSTOMTYPE,
'product_link_attribute_code' => 'position',
'data_type' => 'int',
]
];
$setup->getConnection()
->insertMultiple($setup->getTable('catalog_product_link_attribute'), $data);
$setup->endSetup();
}
}
Интерфейс администратора
Добавить новую вкладку в информацию о продукте
#app/code/Vendor/ProductRelation/view/adminhtml/layout/catalog_product_new.xml
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="product_tabs">
<block class="Vendor\ProductRelation\Block\Adminhtml\Catalog\Product\Edit\Tab" name="product.customtype">
<arguments>
<argument name="label" xsi:type="string" translate="true">Custom Type</argument>
<argument name="url" xsi:type="url" path="catalog/product/customtype">
<param name="_current">1</param>
</argument>
<argument name="class" xsi:type="string">ajax</argument>
<argument name="group_code" xsi:type="string">advanced</argument>
</arguments>
</block>
<action method="addTab">
<argument name="name" xsi:type="string">product-customtype</argument>
<argument name="block" xsi:type="string">product.customtype</argument>
</action>
</referenceBlock>
</body>
</page>
В этом макете нам нужно определить URL-путь path="catalog/product/customtype"
для загрузки сетки. Мы создадим этот контроллер позже. - Vendor/ProductRelation/Controller/Adminhtml/Product/Customtype.php
Блок для отображения вкладки.
<?php
namespace Vendor\ProductRelation\Block\Adminhtml\Catalog\Product\Edit;
class Tab extends \Magento\Backend\Block\Widget\Tab
{
/**
* @param \Magento\Backend\Block\Template\Context $context
* @param array $data
*/
public function __construct(
\Magento\Backend\Block\Template\Context $context,
array $data = []
) {
parent::__construct($context, $data);
}
}
Создание контроллеров:
--Получить сетку пользовательских продуктов и блок сериализатора
#app/code/Vendor/ProductRelation/Controller/Adminhtml/Product/Customtype.php
<?php
namespace Vendor\ProductRelation\Controller\Adminhtml\Product;
class Customtype extends \Magento\Catalog\Controller\Adminhtml\Product
{
/**
* @var \Magento\Framework\View\Result\LayoutFactory
*/
protected $resultLayoutFactory;
public function __construct(
\Magento\Backend\App\Action\Context $context,
\Magento\Catalog\Controller\Adminhtml\Product\Builder $productBuilder,
\Magento\Framework\View\Result\LayoutFactory $resultLayoutFactory
)
{
parent::__construct($context, $productBuilder);
$this->resultLayoutFactory = $resultLayoutFactory;
}
/**
* Get products grid and serializer block
*
* @return \Magento\Framework\View\Result\Layout
*/
public function execute()
{
$this->productBuilder->build($this->getRequest());
$resultLayout = $this->resultLayoutFactory->create();
$resultLayout->getLayout()->getBlock('catalog.product.edit.tab.customtype')
->setProductsCustomtype($this->getRequest()->getPost('products_customtype', null));
return $resultLayout;
}
}
-- Получение пользовательских продуктов сетка
#app/code/Vendor/ProductRelation/Controller/Adminhtml/Product/CustomtypeGrid.php
<?php
namespace Vendor\ProductRelation\Controller\Adminhtml\Product;
class CustomtypeGrid extends Customtype
{
}
Создайте два макета для двух контроллеров выше:
#app/code/Vendor/ProductRelation/view/adminhtml/layout/catalog_product_customtype.xml
<?xml version="1.0"?>
<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/layout_generic.xsd">
<container name="root" label="Root">
<block class="Vendor\ProductRelation\Block\Adminhtml\Catalog\Product\Edit\Tab\Customtype"
name="catalog.product.edit.tab.customtype"/>
<block class="Magento\Backend\Block\Widget\Grid\Serializer" name="customtype_grid_serializer">
<arguments>
<argument name="input_names" xsi:type="string">position</argument>
<argument name="grid_block" xsi:type="string">catalog.product.edit.tab.customtype</argument>
<argument name="callback" xsi:type="string">getSelectedCustomtypeProducts</argument>
<argument name="input_element_name" xsi:type="string">links[customtype]</argument>
<argument name="reload_param_name" xsi:type="string">products_customtype</argument>
</arguments>
</block>
</container>
</layout>
#app/code/Vendor/ProductRelation/view/adminhtml/layout/catalog_product_customtypegrid.xml
<?xml version="1.0"?>
<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/layout_generic.xsd">
<container name="root" label="Root">
<block class="Vendor\ProductRelation\Block\Adminhtml\Catalog\Product\Edit\Tab\Customtype"
name="catalog.product.edit.tab.customtype"/>
</container>
</layout>
Получить блок сетки пользовательских продуктов:
app/code/Vendor/ProductRelation/Block/Adminhtml/Catalog/Product/Edit/Tab/Customtype.php
Если вы продолжите публиковать здесь больше строк кода, эта тема будет слишком длинной. Итак, я сосредоточусь на основных идеях.
Одна из самых важных вещей - это di.xml
#app/code/Vendor/ProductRelation/etc/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">
<preference for="Magento\Catalog\Model\Product"
type="Vendor\ProductRelation\Model\Product"/>
<preference for="Magento\Catalog\Model\Product\Link"
type="Vendor\ProductRelation\Model\Catalog\Product\Link"/>
<preference for="Magento\Catalog\Model\Product\Link\Proxy"
type="Vendor\ProductRelation\Model\Catalog\Product\Link\Proxy"/>
<type name="Magento\Catalog\Model\Product\Initialization\Helper\ProductLinks">
<plugin sortOrder="4" name="afterInitializeLinks"
type="Vendor\ProductRelation\Model\Product\Initialization\Helper\ProductLinks"/>
</type>
</config>
Как мы можем, та же логика в Magento 1, мы переопределим модель продукта и ссылки на продукт. Однако нам также необходимо переопределить продукт Прокси-сервер ссылки и используемый плагин для переопределения метода initializeLinks
.
Есть еще одна заметка. Мы можем повторно использовать маршруты каталога администраторов:
#app/code/Vendor/ProductRelation/etc/adminhtml/routes.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
<router id="admin">
<route id="catalog">
<module name="Vendor_ProductRelation" before="Magento_Catalog" />
</route>
</router>
</config>
Полный исходный код этого расширения доступен на странице репозитория GitHub.
Magento 2.1.x или более поздней версии
Я обновлю позже на этой странице или на Github.