Question

Date: May 30, 2015 (given the changing nature of Magento 2).

Magento 2 introduced a plugin concept, implemented via an interceptor pattern.

What's not clear from the docs is -- which classes and objects in Magento are "intercept-able"? That is, you configure a plugin with XML that looks like the following

<config>
    <type name="{ObservedType}">
        <plugin name="{pluginName}" type="{PluginClassName}" sortOrder="1" disabled="true"/>
    </type>
</config>

but it's not clear which classes are valid as an ObservedType. This older wiki article provides some clues when it says

Please note that the plugin feature does not apply to - Classes created without dependency injection, that is, created with operator new directly, -Final methods, -Final classes

Is any object created via dependency injection available to be intercepted? Does the ObservedType need to be the type hint provided in the a __construct method, or can it (should it?) be something else?

Mainly trying to get my head around what can and can't be done with a Magento 2 interceptor before I start using them.

Was it helpful?

Solution

Every Class of an Magento Module is intercaptable.

As described on the current wiki, it is limited by final methods and classes

Not validated, but Classes of libraries (lib directory) are(/should) not allowed to get intercepted.

The limitation how the object got created is not true anymore I think, at least if the autoloader is correctly configured. And should not matter as they dont get created on the fly, but when the generator got executed. (so it is only a matter of, the magento autoloader should be the first one)

OTHER TIPS

We are working on "@api" annotations to annotate recommended methods that will be more stable across releases. If you worry about upgradability, in additional to what can have a plugin defined, you should also consider what should have a plugin defined. We don't recommend interception of non-@api methods, but sometimes we know that may be the best option. (We leave that to the developer's discretion.)

Officially, you can intercept public methods that are not final. Private methods definitely wont work. From memory, interception currently works by creating a descendant class that inherits the real class (the dependency injection framework creates instances of the generated class when you ask for a new instance of the real class). So anything that will allow a sub-class to be created and the original method overrided will probably work, but public methods are recommended, giving us flexiblity to use some other clever implementation in the future (which would never happen being realistic without good reason).

I know this has an answer already, but it's from 2 years ago. Maybe some things changed in the meantime.

Here is what I found so far.
From the official documentation and from digging into the interception process.

I will answer the other way around.
What CANNOT be intercepted in Magento 2.
From the official doc

  • Objects that are instantiated before Magento\Framework\Interception is bootstrapped (not sure where that point is)
  • Final methods
  • Any method from final classes (because the generated interceptor class has to extend the original class)
  • Any class that contains at least one final public method
  • Non-public methods (it could work for protected methods but this is not "ethical" since it would expose non-public methods to the outside of the class)
  • static methods
  • __construct
  • Virtual types

From digging around

  • methods in classes that are not instantiated via object manager. (Example \Magento\Framework\Phrase)
  • classes implementing \Magento\Framework\ObjectManager\NoninterceptableInterface. (For example \Magento\Framework\App\Cache\Proxy and all the other autogenerated proxies)
Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top