8

I'm confused by Magento 2 documentation regarding plugins:

enter image description here

It is first said that:

Plugins cannot be used with virtual types

But then it is said that:

You can specify a class, interface, or virtual type as a type name which the plugin observes

Am I missing something or is the documentation contradicting itself ? Can we create plugins for virtual types ?

  • Could you, please, tell me whether you’ve found the right solution or not? You haven’t marked any of the replies as “correct”. – Siarhey Uchukhlebau Jul 12 '16 at 9:53
  • 1
    @SiarheyUchukhlebau yeah I tend to forget to mark answers as correct. Both answers are correct. Kandy is a Magento 2 developer so check his answer ;) – Raphael at Digital Pianism Jul 12 '16 at 9:54
  • magento.stackexchange.com/questions/111577/… Is there any way to override this class using plugin. – Amit Singh Jun 16 '17 at 12:00
4

Plugins will work for virtual type but only if you specify it for parent classes or interfaces, but you cannot specify plugin specific for concrete virtual type

10

No, plugins on virtual types do not work.

Proof of concept code:

<?php

namespace Training\Example\Model

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

Plugin using <type>:

<?php

namespace Training\Example\Model;

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

Plugin using <virtualType>:

<?php

namespace Training\Example\Model;

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

DI config:

<?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>

Test:

    <?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());
    }
}

Result:

Failed asserting that two strings are identical.
Expected :Training\Example\Model\VirtualTypePlugin
Actual   :Training\Example\Model\Type
  • I would assume di.xml declaration tag would be type instead of virtualType according to the doc #totrustornottotrustthedoc – Raphael at Digital Pianism Jun 29 '16 at 11:32
  • Updated the answer to include a type and virtualType plugin. – Vinai Jun 29 '16 at 14:12
  • magento.stackexchange.com/questions/111577/… Is there any way to override this class using plugin. – Amit Singh Jun 16 '17 at 12:00
  • You could intercept the concrete type the virtual type maps to, or alternatively overwrite the virtual type mapping to map to your own class, in effect giving you a kind of class override. – Vinai Jun 17 '17 at 12:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.