8
8
9
9
use Magento \Framework \App \ObjectManager ;
10
10
use Magento \Framework \Code \Generator \EntityAbstract ;
11
+ use Magento \Framework \Config \Scope ;
11
12
use Magento \Framework \Interception \Code \Generator \Interceptor ;
12
13
use Magento \Framework \Interception \DefinitionInterface ;
13
14
@@ -16,6 +17,9 @@ class CompiledInterceptor extends Interceptor
16
17
17
18
protected $ plugins ;
18
19
20
+ protected $ classMethods = [];
21
+ protected $ classProperties = [];
22
+
19
23
public function __construct (
20
24
$ sourceClassName = null ,
21
25
$ resultClassName = null ,
@@ -41,14 +45,12 @@ public function __construct(
41
45
}
42
46
}
43
47
48
+ /**
49
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
50
+ */
44
51
public function setInterceptedMethods ($ interceptedMethods )
45
52
{
46
- //DUMMY
47
- }
48
-
49
- protected function _getClassProperties ()
50
- {
51
- return [];
53
+ //NOOP
52
54
}
53
55
54
56
protected function _generateCode ()
@@ -57,41 +59,98 @@ protected function _generateCode()
57
59
$ reflection = new \ReflectionClass ($ typeName );
58
60
59
61
if ($ reflection ->isInterface ()) {
60
- $ this -> _classGenerator -> setImplementedInterfaces ([ $ typeName ]) ;
62
+ return false ;
61
63
} else {
62
64
$ this ->_classGenerator ->setExtendedClass ($ typeName );
63
65
}
64
66
65
67
$ 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
+ ]);
67
82
//return parent::_generateCode();
68
83
return EntityAbstract::_generateCode ();
69
84
}
70
85
71
- protected function _getClassMethods ( )
86
+ protected function overrideMethodsAndGeneratePluginGetters ( \ ReflectionClass $ reflection )
72
87
{
73
- $ reflectionClass = new \ReflectionClass ($ this ->getSourceClassName ());
74
- $ publicMethods = $ reflectionClass ->getMethods (\ReflectionMethod::IS_PUBLIC );
88
+ $ publicMethods = $ reflection ->getMethods (\ReflectionMethod::IS_PUBLIC );
75
89
76
- $ methods = [];
77
90
$ allPlugins = [];
78
91
foreach ($ publicMethods as $ method ) {
79
92
if ($ this ->isInterceptedMethod ($ method )) {
80
93
$ config = $ this ->_getPluginsConfig ($ method , $ allPlugins );
81
94
if (!empty ($ config )) {
82
- $ methods [] = $ this ->_getCompiledMethodInfo ($ method , $ config );
95
+ $ this -> classMethods [] = $ this ->_getCompiledMethodInfo ($ method , $ config );
83
96
}
84
97
}
85
98
}
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 ;
90
134
}
91
135
}
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
+ ];
92
146
}
93
147
94
- return $ methods ;
148
+ return [
149
+ 'name ' => '__construct ' ,
150
+ 'parameters ' => $ parameters ,
151
+ 'body ' => implode ("\n" , $ body ),
152
+ 'docblock ' => ['shortDescription ' => '{@inheritdoc} ' ],
153
+ ];
95
154
}
96
155
97
156
private function addCodeSubBlock (&$ body , $ sub , $ indent = 1 )
@@ -117,8 +176,6 @@ protected function _getMethodSourceFromConfig(\ReflectionMethod $method, $conf,
117
176
if (isset ($ conf [DefinitionInterface::LISTENER_BEFORE ])) {
118
177
foreach ($ conf [DefinitionInterface::LISTENER_BEFORE ] as $ plugin ) {
119
178
if ($ first ) $ first = false ; else $ body [] = "" ;
120
- //$body[] = "/** @var \\" . "{$plugin['class']} \$plugin {$plugin['code']} */";
121
- //$body[] = "\$plugin = \$this->" . $this->getGetterName($plugin) . "();";
122
179
123
180
$ call = "\$this-> " . $ this ->getGetterName ($ plugin ) . "()->before $ capName( \$this $ extraParams); " ;
124
181
@@ -136,11 +193,8 @@ protected function _getMethodSourceFromConfig(\ReflectionMethod $method, $conf,
136
193
$ main = [];
137
194
if (isset ($ conf [DefinitionInterface::LISTENER_AROUND ])) {
138
195
$ plugin = $ conf [DefinitionInterface::LISTENER_AROUND ];
139
- //$body[] = "/** @var \\" . "{$plugin['class']} \$plugin {$plugin['code']} */";
140
- //$body[] = "\$plugin = \$this->" . $this->getGetterName($plugin) . "();";
141
196
$ main [] = "\$this-> " . $ this ->getGetterName ($ plugin ) . "()->around $ capName( \$this, function( {$ this ->_getParameterListForNextCallback ($ parameters )}){ " ;
142
197
$ this ->addCodeSubBlock ($ main , $ this ->_getMethodSourceFromConfig ($ method , $ plugin ['next ' ] ?: [], $ parameters , $ returnVoid ));
143
- //$body[] = "\treturn \$result;";
144
198
$ main [] = "} $ extraParams); " ;
145
199
} else {
146
200
$ main [] = "parent:: {$ method ->getName ()}( {$ this ->_getParameterList ($ parameters )}); " ;
@@ -149,8 +203,6 @@ protected function _getMethodSourceFromConfig(\ReflectionMethod $method, $conf,
149
203
150
204
if (isset ($ conf [DefinitionInterface::LISTENER_AFTER ])) {
151
205
foreach ($ conf [DefinitionInterface::LISTENER_AFTER ] as $ plugin ) {
152
- //$body[] = "/** @var \\" . "{$plugin['class']} \$plugin {$plugin['code']} */";
153
- //$body[] = "\$plugin = \$this->" . $this->getGetterName($plugin) . "();";
154
206
if ($ returnVoid ) {
155
207
$ chain [] = ["(( \$tmp = \$this-> " . $ this ->getGetterName ($ plugin ) . "()->after $ capName( \$this, \$result $ extraParams)) !== null) ? \$tmp : \$result; " ];
156
208
} else {
@@ -206,16 +258,29 @@ protected function _getParameterList(array $parameters)
206
258
207
259
protected function getGetterName ($ plugin )
208
260
{
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
+ ];
210
273
}
211
274
212
275
protected function _getPluginGetterInfo ($ plugin )
213
276
{
214
277
$ body = [];
278
+ $ varName = "\$this->____plugin_ " . $ plugin ['clean_name ' ];
215
279
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; " ;
219
284
220
285
return [
221
286
'name ' => $ this ->getGetterName ($ plugin ),
@@ -234,7 +299,7 @@ protected function _getCompiledMethodInfo(\ReflectionMethod $method, $config)
234
299
$ returnsVoid = ($ method ->hasReturnType () && $ method ->getReturnType ()->getName () == 'void ' );
235
300
236
301
$ body = [
237
- 'switch(ObjectManager::getInstance()->get(Scope::class) ->getCurrentScope()){ '
302
+ 'switch($this->____scope ->getCurrentScope()){ '
238
303
];
239
304
240
305
$ cases = [];
@@ -247,7 +312,7 @@ protected function _getCompiledMethodInfo(\ReflectionMethod $method, $config)
247
312
//call parent method for scopes with no plugins (or when no scope is set)
248
313
$ cases [] = ['cases ' =>["\tdefault: " ], 'conf ' =>[]];
249
314
250
- foreach ($ cases as $ case ) {
315
+ foreach ($ cases as $ case ) {
251
316
$ body = array_merge ($ body , $ case ['cases ' ]);
252
317
$ this ->addCodeSubBlock ($ body , $ this ->_getMethodSourceFromConfig ($ method , $ case ['conf ' ], $ parameters , $ returnsVoid ), 2 );
253
318
//$body[] = "\t\tbreak;";
@@ -269,10 +334,11 @@ protected function _getPluginInfo(CompiledPluginList $plugins, $code, $className
269
334
$ className = $ plugins ->getPluginType ($ className , $ code );
270
335
if (!isset ($ allPlugins [$ code ])) $ allPlugins [$ code ] = [];
271
336
if (empty ($ allPlugins [$ code ][$ className ])) {
337
+ $ suffix = count ($ allPlugins [$ code ]) ? count ($ allPlugins [$ code ]) + 1 : '' ;
272
338
$ allPlugins [$ code ][$ className ] = [
273
339
'code ' => $ code ,
274
340
'class ' => $ className ,
275
- 'suffix ' => count ( $ allPlugins [ $ code ]) ? count ( $ allPlugins [ $ code]) + 1 : ''
341
+ 'clean_name ' => preg_replace ( " /[^A-Za-z0-9_]/ " , ' _ ' , $ code . $ suffix )
276
342
];
277
343
}
278
344
$ ret = $ allPlugins [$ code ][$ className ];
0 commit comments