8
8
use Illuminate \Support \Arr ;
9
9
use Illuminate \Support \Str ;
10
10
use ReflectionFunction ;
11
+ use ReflectionMethod ;
11
12
12
13
class Helper
13
14
{
@@ -53,6 +54,36 @@ protected static function isItemOrderInvalid($item, $array)
53
54
return $ item ['order ' ] === false || $ item ['order ' ] >= count ($ array );
54
55
}
55
56
57
+ /**
58
+ * Gets the parameter of a callable thing (from is_callable) and returns it's arguments using reflection.
59
+ *
60
+ * @param callable $callable
61
+ * @return \ReflectionParameter[]
62
+ *
63
+ * @throws \ReflectionException
64
+ * @throws \InvalidArgumentException
65
+ */
66
+ private static function reflectCallableParameters ($ callable )
67
+ {
68
+ /*
69
+ loosely after https://github.com/technically-php/callable-reflection/blob/main/src/CallableReflection.php#L72-L86.
70
+ Licence is compatible, both project use MIT
71
+ */
72
+ if ($ callable instanceof Closure) {
73
+ $ reflection = new ReflectionFunction ($ callable );
74
+ } elseif (is_string ($ callable ) && function_exists ($ callable )) {
75
+ $ reflection = new ReflectionFunction ($ callable );
76
+ } elseif (is_string ($ callable ) && str_contains ($ callable , ':: ' )) {
77
+ $ reflection = new ReflectionMethod ($ callable );
78
+ } elseif (is_object ($ callable ) && method_exists ($ callable , '__invoke ' )) {
79
+ $ reflection = new ReflectionMethod ($ callable , '__invoke ' );
80
+ } else {
81
+ throw new \InvalidArgumentException ('argument is not callable or the code is wrong ' );
82
+ }
83
+
84
+ return $ reflection ->getParameters ();
85
+ }
86
+
56
87
/**
57
88
* Determines if content is callable or blade string, processes and returns.
58
89
*
@@ -69,9 +100,8 @@ public static function compileContent($content, array $data, array|object $param
69
100
return static ::compileBlade ($ content , static ::getMixedValue ($ data , $ param ));
70
101
}
71
102
72
- if ($ content instanceof Closure) {
73
- $ reflection = new ReflectionFunction ($ content );
74
- $ arguments = $ reflection ->getParameters ();
103
+ if (is_callable ($ content )) {
104
+ $ arguments = self ::reflectCallableParameters ($ content );
75
105
76
106
if (count ($ arguments ) > 0 ) {
77
107
return app ()->call ($ content , [$ arguments [0 ]->name => $ param ]);
0 commit comments