imanghafoori1 /
laravel-smart-facades
This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | |||
| 3 | namespace Imanghafoori\SmartFacades; |
||
| 4 | |||
| 5 | use Illuminate\Support\Facades\Event; |
||
| 6 | use Illuminate\Support\Facades\Facade as LaravelFacade; |
||
| 7 | use Illuminate\Support\Str; |
||
| 8 | use ReflectionMethod; |
||
| 9 | use RuntimeException; |
||
| 10 | use TypeError; |
||
| 11 | |||
| 12 | class Facade extends LaravelFacade |
||
| 13 | { |
||
| 14 | protected static $tmpDriver = null; |
||
| 15 | |||
| 16 | /** |
||
| 17 | * Get the registered name of the component. |
||
| 18 | * |
||
| 19 | * @return string |
||
| 20 | */ |
||
| 21 | 9 | protected static function getFacadeAccessor() |
|
| 22 | { |
||
| 23 | 9 | if ($tmp = static::$tmpDriver) { |
|
| 24 | 2 | static::$tmpDriver = null; |
|
| 25 | |||
| 26 | 2 | return $tmp; |
|
| 27 | } |
||
| 28 | |||
| 29 | 9 | return static::class; |
|
| 30 | } |
||
| 31 | |||
| 32 | /** |
||
| 33 | * Temporarily changes the driver, only for the next call. |
||
| 34 | * |
||
| 35 | * @param \Closure|string $name |
||
| 36 | * |
||
| 37 | * @return string |
||
| 38 | */ |
||
| 39 | 2 | public static function changeProxyTo($name) |
|
| 40 | { |
||
| 41 | 2 | static::$tmpDriver = $name; |
|
| 42 | |||
| 43 | 2 | return static::class; |
|
| 44 | } |
||
| 45 | |||
| 46 | /** |
||
| 47 | * Temporarily changes the driver, only for the next call. |
||
| 48 | * |
||
| 49 | * @param \Closure|string $name |
||
| 50 | * |
||
| 51 | * @return string |
||
| 52 | */ |
||
| 53 | 1 | public static function withDriver($name) |
|
| 54 | { |
||
| 55 | 1 | return static::changeProxyTo($name); |
|
| 56 | } |
||
| 57 | |||
| 58 | /** |
||
| 59 | * Changes the default driver of the facade. |
||
| 60 | * |
||
| 61 | * @param \Closure|string $name |
||
|
0 ignored issues
–
show
|
|||
| 62 | * |
||
| 63 | * @return string |
||
| 64 | */ |
||
| 65 | 9 | public static function shouldProxyTo($class) |
|
| 66 | { |
||
| 67 | 9 | static::$app->singleton(self::getFacadeAccessor(), $class); |
|
| 68 | |||
| 69 | 9 | return static::class; |
|
| 70 | } |
||
| 71 | |||
| 72 | /** |
||
| 73 | * Sets up a listener to be invoked before the actual method call. |
||
| 74 | * |
||
| 75 | * @param string $methodName |
||
| 76 | * @param \Closure|string $listener |
||
| 77 | */ |
||
| 78 | 3 | public static function preCall($methodName, $listener) |
|
| 79 | { |
||
| 80 | 3 | $listener = self::makeListener($methodName, $listener); |
|
| 81 | |||
| 82 | 3 | Event::listen('calling: '.static::class.'@'.$methodName, $listener); |
|
| 83 | 3 | } |
|
| 84 | |||
| 85 | /** |
||
| 86 | * Sets up a listener to be invoked after the actual method. |
||
| 87 | * |
||
| 88 | * @param string $methodName |
||
| 89 | * @param \Closure|string $listener |
||
| 90 | */ |
||
| 91 | 3 | public static function postCall($methodName, $listener) |
|
| 92 | { |
||
| 93 | 3 | $listener = self::makeListener($methodName, $listener); |
|
| 94 | |||
| 95 | 3 | Event::listen('called: '.static::class.'@'.$methodName, $listener); |
|
| 96 | 3 | } |
|
| 97 | |||
| 98 | /** |
||
| 99 | * Handle dynamic, static calls to the object. |
||
| 100 | * |
||
| 101 | * @param string $method |
||
| 102 | * @param array $args |
||
| 103 | * @return mixed |
||
| 104 | * |
||
| 105 | * @throws \RuntimeException |
||
| 106 | * @throws \ReflectionException |
||
| 107 | */ |
||
| 108 | 8 | public static function __callStatic($method, $args) |
|
| 109 | { |
||
| 110 | 8 | Event::dispatch('calling: '.static::class.'@'.$method, [$method, $args]); |
|
| 111 | 8 | $instance = static::getFacadeRoot(); |
|
| 112 | |||
| 113 | 8 | if (! $instance) { |
|
| 114 | throw new RuntimeException('A facade root has not been set.'); |
||
| 115 | } |
||
| 116 | |||
| 117 | try { |
||
| 118 | 8 | $result = $instance->$method(...$args); |
|
| 119 | 7 | Event::dispatch('called: '.static::class.'@'.$method, [$method, $args, $result]); |
|
| 120 | |||
| 121 | 7 | return $result; |
|
| 122 | 4 | } catch (TypeError $error) { |
|
| 123 | 4 | $params = (new ReflectionMethod($instance, $method))->getParameters(); |
|
| 124 | 4 | self::addMissingDependencies($params, $args); |
|
|
0 ignored issues
–
show
$params is of type array<integer,object<ReflectionParameter>>, but the function expects a array<integer,object<Ima...s\ReflectionParameter>>.
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
Loading history...
|
|||
| 125 | 4 | $result = $instance->$method(...$args); |
|
| 126 | 3 | Event::dispatch('called: '.static::class.'@'.$method, [$method, $args, $result]); |
|
| 127 | |||
| 128 | 3 | return $result; |
|
| 129 | } |
||
| 130 | } |
||
| 131 | |||
| 132 | /** |
||
| 133 | * Adds missing dependencies to the user-provided input. |
||
| 134 | * |
||
| 135 | * @param ReflectionParameter[] $parameters |
||
| 136 | * @param array $inputData |
||
| 137 | */ |
||
| 138 | 4 | private static function addMissingDependencies($parameters, array &$inputData) |
|
| 139 | { |
||
| 140 | 4 | foreach ($parameters as $i => $parameter) { |
|
| 141 | // Injects missing type hinted parameters within the array |
||
| 142 | 4 | $class = $parameter->getClass()->name ?? false; |
|
| 143 | 4 | if ($class && ! ($inputData[$i] ?? false) instanceof $class) { |
|
| 144 | 4 | array_splice($inputData, $i, 0, [self::$app[$class]]); |
|
| 145 | 3 | } elseif (! array_key_exists($i, $inputData) && $parameter->isDefaultValueAvailable()) { |
|
| 146 | 3 | $inputData[] = $parameter->getDefaultValue(); |
|
| 147 | } |
||
| 148 | } |
||
| 149 | 4 | } |
|
| 150 | |||
| 151 | 3 | private static function makeListener(string $method, $listener) |
|
| 152 | { |
||
| 153 | 3 | if (Str::contains($method, '*')) { |
|
| 154 | // The $_eventName variable is passed to us by laravel |
||
| 155 | // but we do not need it, because we already know it. |
||
| 156 | return function ($_eventName, $methodAndArguments) use ($listener) { |
||
| 157 | 1 | static::$app->call($listener, $methodAndArguments); |
|
| 158 | 1 | }; |
|
| 159 | } |
||
| 160 | |||
| 161 | return function ($methodName, $args, $result = null) use ($listener) { |
||
| 162 | 1 | static::$app->call($listener, [ |
|
| 163 | 1 | 'methodName' => $methodName, |
|
| 164 | 1 | 'args' => $args, |
|
| 165 | 1 | 'result' => $result, |
|
| 166 | ]); |
||
| 167 | 2 | }; |
|
| 168 | } |
||
| 169 | } |
||
| 170 |
This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.
Consider the following example. The parameter
$italyis not defined by the methodfinale(...).The most likely cause is that the parameter was removed, but the annotation was not.