15

I was wondering why it's not possible to create plugins for protected methods. There's this piece of code in the Magento\Framework\Interception\Code\Generator\Interceptor:

protected function _getClassMethods()
{
    $methods = [$this->_getDefaultConstructorDefinition()];

    $reflectionClass = new \ReflectionClass($this->getSourceClassName());
    $publicMethods = $reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC);
    foreach ($publicMethods as $method) {
        if ($this->isInterceptedMethod($method)) {
            $methods[] = $this->_getMethodInfo($method);
        }
    }
    return $methods;
}

It checks if method is public before allowing it to be intercepted. It can be easily changed by creating a preference in the di.xml of own module, of course, like this:

<?xml version="1.0"?>
<config>
    <preference for="Magento\Framework\Interception\Code\Generator\Interceptor" type="MyVendor\MyModule\Model\MyInterceptorModel" />
</config>

and rewriting the _getClassMethods with the \ReflectionMethod::IS_PUBLIC changed to \ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_PROTECTED inside of the method.

But I wonder why it's not possible to intercept protected methods in the original method definition? Does it have a major impact on the performance, or there's some other reason for that, like allowing 3rd party modules to make Magento logic too "messy"?

3 Answers 3

28

According to Magento docs it is not "possible" to use a plugin on a protected method.

(http://devdocs.magento.com/guides/v2.0/extension-dev-guide/plugins.html)

You cannot apply plugins to:

  • 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

But your point is correct, according to ___callPlugins definition in Magento\Framework\Interception\Interceptor, I do not see any problem using protected methods.

My first guess is that they limited it to avoid an high code complexity since Magento should rewrite any protected method and call ___callPlugins for each of them... it will terribly slowdown IMHO.

But I think the real reason is for a logical consinstency: plugins should be used to change the class methods output/input, not to rewrite internal behaviour, so they should only access public methods.

To rewrite an internal behaviour you have to use a preference. It makes sense.

1
  • 2
    Good answer. I was wondering this myself also but from an OOP / SOLID point of view it makes sense to only allow public methods to be intercepted. Jun 20, 2017 at 15:23
15

If I remember correctly from a presentation of Anton Krill, he said that technically protected methods can be intercepted, but it defeats the purpose of having them "protected".
The interceptor class that is autogenerated extends the original class so it has access to the protected methods.
But... Protected methods should not be available outside the class.
So it's more of a decision than a limitation.

-4

It is OOPS security feature not magento specific.

Public methods, labeled by public are available to every class. Protected methods, labeled by protected are available to subclasses and friendly classes, which are classes in the same package. Friendly methods, labeled by nothing (i.e. default) are available to friendly classes. Private methods are available only to the class itself.

Reasons:

1) Protected Methods can't access in Inheritence second level.

example: Lets take an example two classes Class A & Class B in same package.

Class B can only inheritance protected as well as public methods of class A.

1
  • 5
    Protected methods... which are classes in the same package - this is not true. Protected methods are only available to classes available in the same hierarchy via inheritance - whether they're in the same package or not makes no difference. Protected Methods can't access in Inheritence second level. - again, not true - protected methods are available at any level of inheritance, just not from outside the object scope
    – scrowler
    Jul 19, 2016 at 3:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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