Fiquei me perguntando por que não é possível criar plugins para protected
métodos. Há esse pedaço de código no 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;
}
Ele verifica se o método está public
antes de permitir sua interceptação. Ele pode ser facilmente alterado através da criação de um preference
no di.xml
de próprio módulo, é claro, como este:
<?xml version="1.0"?>
<config>
<preference for="Magento\Framework\Interception\Code\Generator\Interceptor" type="MyVendor\MyModule\Model\MyInterceptorModel" />
</config>
e reescrevendo o _getClassMethods
com o \ReflectionMethod::IS_PUBLIC
alterado para \ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_PROTECTED
dentro do método.
Mas eu me pergunto por que não é possível interceptar métodos protegidos na definição do método original? Isso tem um grande impacto no desempenho ou há outra razão para isso, como permitir que módulos de terceiros tornem a lógica do Magento muito "bagunçada"?
Se bem me lembro de uma apresentação de Anton Krill, ele disse que métodos tecnicamente protegidos podem ser interceptados, mas isso anula o propósito de tê-los "protegidos".
A classe interceptora gerada automaticamente estende a classe original para que ela tenha acesso aos métodos protegidos.
Mas ... Métodos protegidos não devem estar disponíveis fora da classe.
Portanto, é mais uma decisão do que uma limitação.
fonte
É um recurso de segurança OOPS não específico do magento.
Métodos públicos, rotulados por público, estão disponíveis para todas as classes. Os métodos protegidos, rotulados por protected, estão disponíveis para subclasses e classes amigáveis, que são classes no mesmo pacote. Métodos amigáveis, rotulados por nada (ou seja, padrão), estão disponíveis para classes amigáveis. Métodos particulares estão disponíveis apenas para a própria classe.
Razões:
1) Métodos protegidos não podem acessar no segundo nível de herança.
exemplo: Vamos dar um exemplo de duas classes Classe A e Classe B no mesmo pacote.
A classe B só pode proteger métodos de herança e métodos públicos da classe A.
fonte
Protected methods... which are classes in the same package
- isso não é verdade. Os métodos protegidos estão disponíveis apenas para classes disponíveis na mesma hierarquia por herança - se eles estão no mesmo pacote ou não, não faz diferença.Protected Methods can't access in Inheritence second level.
- mais uma vez, não é verdade - protegido métodos estão disponíveis em qualquer nível de herança, não apenas de fora do escopo do objeto