3

In my test extension I try create plugin for Magento\Directory\Helper\Data::isRegionRequired method. My frontend/di.xml contain:

<type name="Magento\Directory\Helper\Data">
    <plugin name="Sample_Test::isRegionRequired" type="Sample\Test\Plugin\Country\DirectoryHelperAfter" sortOrder="1" disabled="false"/>
</type>

And class Sample\Test\Plugin\Country\DirectoryHelperAfter contain

public function afterIsRegionRequired($subject, $result)
{
    exit('test');
    $myResult = true;
    return $myResult;
}

On the front I get next error on generating my plugin (before call plugin method):

Source class "\DirectoryHelperData" for "DirectoryHelperDataProxy" generation does not exist.

In /app/code/Magento/Directory/etc/di.xml I found:

<virtualType name="DirectoryHelperDataProxy" type="Magento\Directory\Helper\Data\Proxy">
    <arguments>
        <argument name="instanceName" xsi:type="string">Magento\Directory\Helper\Data</argument>
    </arguments>
</virtualType>
<type name="Magento\Directory\Model\ResourceModel\Country\Collection" shared="false">
    <arguments>
        <argument name="helperData" xsi:type="object">DirectoryHelperDataProxy</argument>
    </arguments>
</type>

My question is "How I can use plugin for class if it used in proxy"?

3

From https://devdocs.magento.com/guides/v2.0/extension-dev-guide/plugins.html:

Limitations

Plugins cannot be used with any of the following:

  • Final methods
  • Final classes
  • Any class that contains at least one final public method
  • Non-public methods
  • Class methods (such as static methods)
  • __construct
  • Virtual types

As this is Virtual type, you can't use plugin for Magento\Directory\Helper\Data I have encountered the same problem, the best solution I have found is to use preference.

<preference for="Magento\Directory\Helper\Data" type="Sample\Test\Helper\Data" />

It works as override of methods.

  • Thank for the answer. It is safe to rewrite a class for which there is the virtual type?.. – sergei.sss Jul 1 '16 at 5:44
  • @sergei.sss Yes, It is a good solution if you can't use a plugin. – Yura Zabolotny Jul 1 '16 at 12:44
0

How I can use plugin for class if it used in proxy ?

The plugin (before, after and around ) will work same even the class is used by proxy.

Let us have a quick working example.. taken

di.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
    <type name="Pulsestorm\TutorialProxy1\Model\Example">
        <arguments>
            <argument name="slow" xsi:type="object">Pulsestorm\TutorialProxy1\Model\SlowLoading\Proxy</argument>
        </arguments>
    </type>
    <type name="Pulsestorm\TutorialProxy1\Model\SlowLoading">
        <plugin name="pulsestorm_tutorial_plugin_model_example_plugin"
                type="Pulsestorm\TutorialProxy1\Model\Example\SlowLoading\Plugin"
                sortOrder="10"
                disabled="false"/>
    </type> 
</config>

The above di.xml, as we know we are using proxy class for Pulsestorm\TutorialProxy1\Model\SlowLoading and same class is used by plugin. so inside my Pulsestorm\TutorialProxy1\Model\Example\SlowLoading\Plugin

namespace Pulsestorm\TutorialProxy1\Model\Example\SlowLoading;

class Plugin
{
    public function afterHello()
    {
        echo "ABCD EFGH";

    }  


}

This afterHello method is working fine even the class is using proxy ....:)

  • Thank. In Alan's example we see: Pulsestorm\TutorialProxy1\Model\SlowLoading\Proxy use for plugin as Pulsestorm\TutorialProxy1\Model\SlowLoading (without Proxy). But magento describe proxy as "DirectoryHelperDataProxy". If I use "DirectoryHelperData" the error disappears, but the code execution doesn't reach my plugin. – sergei.sss Apr 20 '16 at 12:41

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.