88
99use Magento \Framework \App \ObjectManager ;
1010use Magento \Framework \Code \Generator \EntityAbstract ;
11+ use Magento \Framework \Config \Scope ;
1112use Magento \Framework \Interception \Code \Generator \Interceptor ;
1213use Magento \Framework \Interception \DefinitionInterface ;
1314
@@ -16,6 +17,9 @@ class CompiledInterceptor extends Interceptor
1617
1718 protected $ plugins ;
1819
20+ protected $ classMethods = [];
21+ protected $ classProperties = [];
22+
1923 public function __construct (
2024 $ sourceClassName = null ,
2125 $ resultClassName = null ,
@@ -41,14 +45,12 @@ public function __construct(
4145 }
4246 }
4347
48+ /**
49+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
50+ */
4451 public function setInterceptedMethods ($ interceptedMethods )
4552 {
46- //DUMMY
47- }
48-
49- protected function _getClassProperties ()
50- {
51- return [];
53+ //NOOP
5254 }
5355
5456 protected function _generateCode ()
@@ -57,41 +59,98 @@ protected function _generateCode()
5759 $ reflection = new \ReflectionClass ($ typeName );
5860
5961 if ($ reflection ->isInterface ()) {
60- $ this -> _classGenerator -> setImplementedInterfaces ([ $ typeName ]) ;
62+ return false ;
6163 } else {
6264 $ this ->_classGenerator ->setExtendedClass ($ typeName );
6365 }
6466
6567 $ this ->_classGenerator ->addUse (ObjectManager::class);
66- $ this ->_classGenerator ->addUse (\Magento \Framework \Config \Scope::class);
68+ $ this ->_classGenerator ->addUse (Scope::class);
69+
70+ $ this ->classMethods = [];
71+ $ this ->classProperties = [];
72+ $ this ->overrideMethodsAndGeneratePluginGetters ($ reflection );
73+
74+ array_unshift ($ this ->classMethods , $ this ->_getConstructorInfo ($ reflection ->getConstructor ()));
75+ array_unshift ($ this ->classProperties , [
76+ 'name ' => '____scope ' ,
77+ 'visibility ' => 'private ' ,
78+ 'docblock ' => [
79+ 'tags ' => [['name ' => 'var ' , 'description ' => 'Scope ' ]],
80+ ]
81+ ]);
6782 //return parent::_generateCode();
6883 return EntityAbstract::_generateCode ();
6984 }
7085
71- protected function _getClassMethods ( )
86+ protected function overrideMethodsAndGeneratePluginGetters ( \ ReflectionClass $ reflection )
7287 {
73- $ reflectionClass = new \ReflectionClass ($ this ->getSourceClassName ());
74- $ publicMethods = $ reflectionClass ->getMethods (\ReflectionMethod::IS_PUBLIC );
88+ $ publicMethods = $ reflection ->getMethods (\ReflectionMethod::IS_PUBLIC );
7589
76- $ methods = [];
7790 $ allPlugins = [];
7891 foreach ($ publicMethods as $ method ) {
7992 if ($ this ->isInterceptedMethod ($ method )) {
8093 $ config = $ this ->_getPluginsConfig ($ method , $ allPlugins );
8194 if (!empty ($ config )) {
82- $ methods [] = $ this ->_getCompiledMethodInfo ($ method , $ config );
95+ $ this -> classMethods [] = $ this ->_getCompiledMethodInfo ($ method , $ config );
8396 }
8497 }
8598 }
86- if (!empty ($ methods ) && !empty ($ allPlugins )) {
87- foreach ($ allPlugins as $ key => $ plugins ) {
88- foreach ($ plugins as $ plugin ) {
89- $ methods [] = $ this ->_getPluginGetterInfo ($ plugin );
99+ foreach ($ allPlugins as $ plugins ) {
100+ foreach ($ plugins as $ plugin ) {
101+ $ this ->classMethods [] = $ this ->_getPluginGetterInfo ($ plugin );
102+ $ this ->classProperties [] = $ this ->_getPluginPropertyInfo ($ plugin );
103+ }
104+ }
105+ }
106+
107+ protected function _getClassMethods ()
108+ {
109+ return $ this ->classMethods ;
110+ }
111+
112+ protected function _getClassProperties ()
113+ {
114+ return $ this ->classProperties ;
115+ }
116+
117+ protected function _getConstructorInfo (\ReflectionMethod $ parentConstructor = null )
118+ {
119+ if ($ parentConstructor == null ) {
120+ $ parameters = [[
121+ 'name ' => 'scope ' ,
122+ 'type ' => Scope::class
123+ ]];
124+ $ body = ["\$this->____scope = \$scope; " ];
125+ } else {
126+ $ parameters = $ parentConstructor ->getParameters ();
127+ $ addScopeParam = true ;
128+ $ scopeParamName = '____scope ' ;
129+ foreach ($ parameters as $ parameter ) {
130+ $ parentCallParams [] = '$ ' . $ parameter ->getName ();
131+ if ($ parameter ->getType () == Scope::class) {
132+ $ scopeParamName = $ parameter ->getName ();
133+ $ addScopeParam = false ;
90134 }
91135 }
136+
137+ $ parameters = array_map (array ($ this , '_getMethodParameterInfo ' ), $ parameters );
138+ $ addScopeParam && array_unshift ($ parameters , [
139+ 'name ' => $ scopeParamName ,
140+ 'type ' => Scope::class
141+ ]);
142+ $ body = [
143+ "\$this->____scope = \$$ scopeParamName; " ,
144+ "parent::__construct( " . implode (', ' , $ parentCallParams ) ."); "
145+ ];
92146 }
93147
94- return $ methods ;
148+ return [
149+ 'name ' => '__construct ' ,
150+ 'parameters ' => $ parameters ,
151+ 'body ' => implode ("\n" , $ body ),
152+ 'docblock ' => ['shortDescription ' => '{@inheritdoc} ' ],
153+ ];
95154 }
96155
97156 private function addCodeSubBlock (&$ body , $ sub , $ indent = 1 )
@@ -117,8 +176,6 @@ protected function _getMethodSourceFromConfig(\ReflectionMethod $method, $conf,
117176 if (isset ($ conf [DefinitionInterface::LISTENER_BEFORE ])) {
118177 foreach ($ conf [DefinitionInterface::LISTENER_BEFORE ] as $ plugin ) {
119178 if ($ first ) $ first = false ; else $ body [] = "" ;
120- //$body[] = "/** @var \\" . "{$plugin['class']} \$plugin {$plugin['code']} */";
121- //$body[] = "\$plugin = \$this->" . $this->getGetterName($plugin) . "();";
122179
123180 $ call = "\$this-> " . $ this ->getGetterName ($ plugin ) . "()->before $ capName( \$this $ extraParams); " ;
124181
@@ -136,11 +193,8 @@ protected function _getMethodSourceFromConfig(\ReflectionMethod $method, $conf,
136193 $ main = [];
137194 if (isset ($ conf [DefinitionInterface::LISTENER_AROUND ])) {
138195 $ plugin = $ conf [DefinitionInterface::LISTENER_AROUND ];
139- //$body[] = "/** @var \\" . "{$plugin['class']} \$plugin {$plugin['code']} */";
140- //$body[] = "\$plugin = \$this->" . $this->getGetterName($plugin) . "();";
141196 $ main [] = "\$this-> " . $ this ->getGetterName ($ plugin ) . "()->around $ capName( \$this, function( {$ this ->_getParameterListForNextCallback ($ parameters )}){ " ;
142197 $ this ->addCodeSubBlock ($ main , $ this ->_getMethodSourceFromConfig ($ method , $ plugin ['next ' ] ?: [], $ parameters , $ returnVoid ));
143- //$body[] = "\treturn \$result;";
144198 $ main [] = "} $ extraParams); " ;
145199 } else {
146200 $ main [] = "parent:: {$ method ->getName ()}( {$ this ->_getParameterList ($ parameters )}); " ;
@@ -149,8 +203,6 @@ protected function _getMethodSourceFromConfig(\ReflectionMethod $method, $conf,
149203
150204 if (isset ($ conf [DefinitionInterface::LISTENER_AFTER ])) {
151205 foreach ($ conf [DefinitionInterface::LISTENER_AFTER ] as $ plugin ) {
152- //$body[] = "/** @var \\" . "{$plugin['class']} \$plugin {$plugin['code']} */";
153- //$body[] = "\$plugin = \$this->" . $this->getGetterName($plugin) . "();";
154206 if ($ returnVoid ) {
155207 $ chain [] = ["(( \$tmp = \$this-> " . $ this ->getGetterName ($ plugin ) . "()->after $ capName( \$this, \$result $ extraParams)) !== null) ? \$tmp : \$result; " ];
156208 } else {
@@ -206,16 +258,29 @@ protected function _getParameterList(array $parameters)
206258
207259 protected function getGetterName ($ plugin )
208260 {
209- return '_get_plugin_ ' . preg_replace ("/[^A-Za-z0-9_]/ " , '_ ' , $ plugin ['code ' ] . $ plugin ['suffix ' ]);
261+ return '____plugin_ ' . $ plugin ['clean_name ' ];
262+ }
263+
264+ protected function _getPluginPropertyInfo ($ plugin )
265+ {
266+ return [
267+ 'name ' => '____plugin_ ' . $ plugin ['clean_name ' ],
268+ 'visibility ' => 'private ' ,
269+ 'docblock ' => [
270+ 'tags ' => [['name ' => 'var ' , 'description ' => '\\' . $ plugin ['class ' ]]],
271+ ]
272+ ];
210273 }
211274
212275 protected function _getPluginGetterInfo ($ plugin )
213276 {
214277 $ body = [];
278+ $ varName = "\$this->____plugin_ " . $ plugin ['clean_name ' ];
215279
216- $ body [] = "static \$cache = null; " ;
217- $ body [] = "if ( \$cache === null) \$cache = ObjectManager::getInstance()->get( \\" . "{$ plugin ['class ' ]}::class); " ;
218- $ body [] = "return \$cache; " ;
280+ $ body [] = "if ( $ varName === null) { " ;
281+ $ body [] = "\t$ varName = ObjectManager::getInstance()->get( \\" . "{$ plugin ['class ' ]}::class); " ;
282+ $ body [] = "} " ;
283+ $ body [] = "return $ varName; " ;
219284
220285 return [
221286 'name ' => $ this ->getGetterName ($ plugin ),
@@ -234,7 +299,7 @@ protected function _getCompiledMethodInfo(\ReflectionMethod $method, $config)
234299 $ returnsVoid = ($ method ->hasReturnType () && $ method ->getReturnType ()->getName () == 'void ' );
235300
236301 $ body = [
237- 'switch(ObjectManager::getInstance()->get(Scope::class) ->getCurrentScope()){ '
302+ 'switch($this->____scope ->getCurrentScope()){ '
238303 ];
239304
240305 $ cases = [];
@@ -247,7 +312,7 @@ protected function _getCompiledMethodInfo(\ReflectionMethod $method, $config)
247312 //call parent method for scopes with no plugins (or when no scope is set)
248313 $ cases [] = ['cases ' =>["\tdefault: " ], 'conf ' =>[]];
249314
250- foreach ($ cases as $ case ) {
315+ foreach ($ cases as $ case ) {
251316 $ body = array_merge ($ body , $ case ['cases ' ]);
252317 $ this ->addCodeSubBlock ($ body , $ this ->_getMethodSourceFromConfig ($ method , $ case ['conf ' ], $ parameters , $ returnsVoid ), 2 );
253318 //$body[] = "\t\tbreak;";
@@ -269,10 +334,11 @@ protected function _getPluginInfo(CompiledPluginList $plugins, $code, $className
269334 $ className = $ plugins ->getPluginType ($ className , $ code );
270335 if (!isset ($ allPlugins [$ code ])) $ allPlugins [$ code ] = [];
271336 if (empty ($ allPlugins [$ code ][$ className ])) {
337+ $ suffix = count ($ allPlugins [$ code ]) ? count ($ allPlugins [$ code ]) + 1 : '' ;
272338 $ allPlugins [$ code ][$ className ] = [
273339 'code ' => $ code ,
274340 'class ' => $ className ,
275- 'suffix ' => count ( $ allPlugins [ $ code ]) ? count ( $ allPlugins [ $ code]) + 1 : ''
341+ 'clean_name ' => preg_replace ( " /[^A-Za-z0-9_]/ " , ' _ ' , $ code . $ suffix )
276342 ];
277343 }
278344 $ ret = $ allPlugins [$ code ][$ className ];
0 commit comments