I ended up declaring a plugin on a virtual type and it worked.
Yes, I know, this should not work. As Daniel explains this didn't work for me because the block declared in the catalogsearch_result_index.xml
layout file is a virtual type of Magento\Catalog\Block\Product\ListProduct
.
But to my surprise it works if I add a plugin to the virtual type.
<type name="Magento\Catalog\Block\Product\ListProduct">
<plugin name="name-here" type="[Vendor]\[Module]\Plugin\Block\Product\ListProductPlugin" />
</type>
<virtualType name="Magento\CatalogSearch\Block\SearchResult\ListProduct">
<plugin name="other-name-here" type="[Vendor]\[Module]\Plugin\Block\Product\ListProductPlugin" />
</virtualType>
I'm still puzzled to why this works.
Edit:
I think I got it.
This works because I have plugins on both regular class and virtual type.
It will not work if I remove the plugin declaration on the actual class.
Here are some more details.
The plugin will work as long as the interceptor class is used instead of the original class.
So here is the piece of code that decides to use the interceptor or not:
Magento\Framework\Interception\ObjectManager\Config\Developer::getInstanceType
public function getInstanceType($instanceName)
{
$type = parent::getInstanceType($instanceName);
if ($this->interceptionConfig && $this->interceptionConfig->hasPlugins($instanceName)
&& $this->interceptableValidator->validate($instanceName)
) {
return $type . '\\Interceptor';
}
return $type;
}
In this particular case, $instanceName
is the virtual type name and $type
is the actual class name. And the code above checks if there are any plugins declared on the virtual type name. If there is one it uses the interceptor for the real class.
SO basically declaring an interceptor on a virtual type does not necessarily means it works, it means the interceptor class will be used where the virtual type is declared. But the plugins declared on the virtual types will not be called...ever. Only the plugins on the actual class will be called.