Je me demandais pourquoi il n'était pas possible de créer des plugins pour les protected
méthodes. Il y a ce morceau de code dans 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;
}
Il vérifie si la méthode est public
avant de permettre son interception. Il peut être facilement modifié en créant un preference
dans le di.xml
propre module, bien sûr, comme ceci:
<?xml version="1.0"?>
<config>
<preference for="Magento\Framework\Interception\Code\Generator\Interceptor" type="MyVendor\MyModule\Model\MyInterceptorModel" />
</config>
et réécriture du _getClassMethods
avec le \ReflectionMethod::IS_PUBLIC
changé à l' \ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_PROTECTED
intérieur de la méthode.
Mais je me demande pourquoi il n'est pas possible d'intercepter des méthodes protégées dans la définition de méthode d'origine? Cela a-t-il un impact majeur sur les performances, ou il y a une autre raison à cela, comme autoriser des modules tiers à rendre la logique de Magento trop "désordonnée"?
Si je me souviens bien d'une présentation d'Anton Krill, il a dit que les méthodes techniquement protégées peuvent être interceptées, mais cela va à l'encontre du but de les avoir "protégées".
La classe d'intercepteur générée automatiquement étend la classe d'origine afin qu'elle ait accès aux méthodes protégées.
Mais ... Les méthodes protégées ne devraient pas être disponibles en dehors de la classe.
Il s'agit donc plus d'une décision que d'une limitation.
la source
Il s'agit d'une fonction de sécurité OOPS qui n'est pas spécifique à magento.
Les méthodes publiques, étiquetées par public, sont disponibles pour chaque classe. Les méthodes protégées, étiquetées par protected, sont disponibles pour les sous-classes et les classes amies, qui sont des classes dans le même package. Les méthodes amies, étiquetées par rien (c'est-à-dire par défaut) sont disponibles pour les classes amies. Les méthodes privées ne sont disponibles que pour la classe elle-même.
Les raisons:
1) Les méthodes protégées ne peuvent pas accéder au deuxième niveau d'héritage.
exemple: Prenons un exemple de deux classes Classe A & Classe B dans le même package.
La classe B ne peut être héritée que par des méthodes publiques de classe A.
la source
Protected methods... which are classes in the same package
- ce n'est pas vrai. Les méthodes protégées ne sont disponibles que pour les classes disponibles dans la même hiérarchie via l'héritage - qu'elles soient ou non dans le même package ne fait aucune différence.Protected Methods can't access in Inheritence second level.
- encore une fois, ce n'est pas vrai - les méthodes protégées sont disponibles à tous les niveaux d'héritage, mais pas en dehors de la portée de l'objet