Magento 2 Как добавить пользовательские отношения с продуктами?


Мне нужно добавить еще один атрибут связанных продуктов, чтобы связать несколько других продуктов.

Я нашел решение для Magento 1: http://inchoo.net/magento/how-to-add-custom-product-relations-in-magento/

Однако я хотел бы реализовать это в Magento 2. Любое руководство приветствуется.

Author: Khoa TruongDinh, 2016-09-21

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.

 6
Author: Khoa TruongDinh, 2016-09-22 13:31:42