@@ -7,25 +7,95 @@ class FunctionInjector
7
7
<?php
8
8
namespace {{ns}};
9
9
if (!function_exists('{{ns}}\{{func}}')) {
10
- function {{func}}() {
11
- if (( \$__am_res = __amock_before_func('{{ns}}','{{func}}', func_get_args())) !== __AM_CONTINUE__) {
12
- return \$__am_res;
10
+ function {{func}}() {
11
+ if (( \$__am_res = __amock_before_func('{{ns}}','{{func}}', func_get_args())) !== __AM_CONTINUE__) {
12
+ return \$__am_res;
13
+ }
14
+ return call_user_func_array('{{func}}', func_get_args());
13
15
}
14
- return call_user_func_array('{{func}}', func_get_args());
15
16
}
17
+ EOF ;
18
+
19
+ protected $ templateByRefOptional = <<<EOF
20
+ <?php
21
+ namespace {{ns}};
22
+ if (!function_exists('{{ns}}\{{func}}')) {
23
+ function {{func}}({{arguments}}) {
24
+ \$args = [];
25
+ switch(count(func_get_args())) {
26
+ {{code}} }
27
+ if (( \$__am_res = __amock_before_func('{{ns}}','{{func}}', \$args)) !== __AM_CONTINUE__) {
28
+ return \$__am_res;
29
+ }
30
+ return call_user_func_array('{{func}}', \$args);
31
+ }
16
32
}
17
33
EOF ;
34
+
18
35
protected $ namespace ;
36
+
19
37
protected $ function ;
20
38
protected $ fileName ;
21
39
22
40
function __construct ($ namespace , $ function )
23
41
{
24
42
$ this ->namespace = $ namespace ;
25
43
$ this ->function = $ function ;
44
+ $ this ->placeOptionalAndReferenceFunction ($ namespace , $ function );
26
45
$ this ->place ('ns ' , $ this ->namespace );
27
46
$ this ->place ('func ' , $ this ->function );
47
+ }
48
+
49
+ public function getParameterDeclaration (\ReflectionParameter $ parameter , $ internal )
50
+ {
51
+ $ text = (string )$ parameter ;
52
+ if (preg_match ('@Parameter\s#[0-9]+\s\[\s<(required|optional)>(.*)(\sor NULL)(.*)\s\]@ ' , $ text , $ match )) {
53
+ $ text = $ match (2 ).$ match [4 ];
54
+ } elseif (preg_match ('@Parameter\s#[0-9]+\s\[\s<(required|optional)>\s(.*)\s\]@ ' , $ text , $ match )) {
55
+ $ text = $ match [2 ];
56
+ } else {
57
+ throw new \Exception ('reflection api changed. adjust code. ' );
58
+ }
59
+ if ($ internal && $ parameter ->isOptional ()) {
60
+ $ text .= "=NULL " ;
61
+ }
62
+ return $ text ;
63
+ }
28
64
65
+ public function placeOptionalAndReferenceFunction ($ namespace , $ function )
66
+ {
67
+ $ reflect = new \ReflectionFunction ($ function );
68
+ $ parameters = [];
69
+ $ args = '' ;
70
+ $ byRef = false ;
71
+ $ optionals = false ;
72
+ $ names = [];
73
+ $ internal = $ reflect ->isInternal ();
74
+ foreach ($ reflect ->getParameters () as $ parameter ) {
75
+ $ name = '$ ' .$ parameter ->getName ();
76
+ $ newname = '$p ' .$ parameter ->getPosition ();
77
+ $ declaration = str_replace ($ name , $ newname , $ this ->getParameterDeclaration ($ parameter , $ internal ));
78
+ $ name = $ newname ;
79
+ if (!$ optionals && $ parameter ->isOptional ()) {
80
+ $ optionals = true ;
81
+ }
82
+ if ($ parameter ->isPassedByReference ()) {
83
+ $ name = '& ' .$ name ;
84
+ $ byRef = true ;
85
+ }
86
+ $ names [] = $ name ;
87
+ $ parameters [$ newname ] = $ declaration ;
88
+ }
89
+ if ($ byRef ) {
90
+ $ this ->template = $ this ->templateByRefOptional ;
91
+ $ this ->place ('arguments ' , join (', ' , $ parameters ));
92
+ $ code = '' ;
93
+ for ($ i = count ($ parameters ); $ i > 0 ; $ i --) {
94
+ $ code .= " case {$ i }: \$args = [ " . join (', ' , $ names ) . "]; break; \n" ;
95
+ array_pop ($ names );
96
+ }
97
+ $ this ->place ('code ' , $ code );
98
+ }
29
99
}
30
100
31
101
public function save ()
0 commit comments