Magento 2: плагины виртуальных типов

8

Я смущен документацией Magento 2 относительно плагинов :

введите описание изображения здесь

Сначала сказано, что:

Плагины нельзя использовать с виртуальными типами

Но тогда сказано, что:

Вы можете указать класс, интерфейс или виртуальный тип в качестве имени типа, которое наблюдает плагин

Я что-то упустил или документация противоречит самой себе? Можем ли мы создавать плагины для виртуальных типов?

Рафаэль в цифровом пианизме
источник
Скажите, пожалуйста, нашли ли вы правильное решение или нет? Вы не пометили ни одного ответа как «правильный».
Сергей Учухлебау
1
@SiarheyUchukhlebau да, я склонен забывать отмечать ответы как правильные. Оба ответа верны. Канди - разработчик Magento 2, так что проверьте его ответ;)
Рафаэль в Digital Pianism
magento.stackexchange.com/questions/111577/… Есть ли способ переопределить этот класс с помощью плагина.
Амит Сингх

Ответы:

4

Плагины будут работать для виртуального типа, но только если вы укажете его для родительских классов или интерфейсов, но вы не сможете указать плагин, специфичный для конкретного виртуального типа.

Канди
источник
Таким образом, мы согласны с тем, что документ неверен, поскольку в нем четко указывается виртуальный тип.
Рафаэль в Цифровом пианизме
3
Если честно, плагины для виртуальных типов работали до бета-версии разработчика, и у нас есть ошибка, чтобы исправить это.
Канди
magento.stackexchange.com/questions/111577/… Есть ли способ переопределить этот класс с помощью плагина.
Амит Сингх
11

Нет, плагины на виртуальных типах не работают.

Доказательство концепции кода:

<?php

namespace Training\Example\Model

class Type
{
    public function bar()
    {
        return __CLASS__;
    }
}

Плагин использует <type>:

<?php

namespace Training\Example\Model;

class TypePlugin
{
    public function afterBar(Type $subject)
    {
        return __CLASS__;
    }
}

Плагин использует <virtualType>:

<?php

namespace Training\Example\Model;

class VirtualTypePlugin
{
    public function afterBar(Type $subject)
    {
        return __CLASS__;
    }
}

Конфигурация DI:

<?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="Foo" type="Training\Example\Model\Type">
        <plugin name="myfoo" type="Training\Example\Model\VirtualTypePlugin"/>
    </virtualType>
    <type name="Foo">
        <plugin name="yourfoo" type="Training\Example\Model\TypePlugin"/>
    </type>
</config>

Тестовое задание:

    <?php

namespace Training\Example\Training\Integration;

use Magento\TestFramework\ObjectManager;
use Training\Example\Model\Type;
use Training\Example\Model\VirtualTypePlugin;

class VirtualTypePluginTest extends \PHPUnit_Framework_TestCase
{
    public function testPluginsOnVirtualTypesWork()
    {
        /** @var Type $instance */
        $instance = ObjectManager::getInstance()->create(Type::class);
        $this->assertSame(VirtualTypePlugin::class, $instance->bar());
    }
}

Результат:

Failed asserting that two strings are identical.
Expected :Training\Example\Model\VirtualTypePlugin
Actual   :Training\Example\Model\Type
Vinai
источник
Я бы предположил, что di.xmlтег объявления будет typeвместо того, virtualTypeчтобы соответствовать документу #totrustornottotrustthedoc
Рафаэль в Digital Pianism
Обновлен ответ, чтобы включить typeи virtualTypeплагин.
Винай
magento.stackexchange.com/questions/111577/… Есть ли способ переопределить этот класс с помощью плагина.
Амит Сингх
Вы можете перехватить конкретный тип, с которым сопоставляется виртуальный тип, или альтернативно перезаписать сопоставление виртуального типа, чтобы сопоставить его с вашим собственным классом, фактически давая вам своего рода переопределение класса.
Vinai