Completed
Push — master ( c6bc12...8e6b80 )
by Iman
01:46
created

Facade::getFacadeAccessor()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 1
1
<?php
2
3
namespace Imanghafoori\SmartFacades;
4
5
use TypeError;
6
use ReflectionMethod;
7
use RuntimeException;
8
use Illuminate\Support\Str;
9
use Illuminate\Support\Facades\Event;
10
use Illuminate\Support\Facades\Facade as LaravelFacade;
11
12
class Facade extends LaravelFacade
13
{
14 5
    protected static function getFacadeAccessor()
15
    {
16 5
        return static::class;
17
    }
18
19 5
    static function shouldProxyTo($class)
20
    {
21 5
        static::$app->singleton(self::getFacadeAccessor(), $class);
22 5
    }
23
24
    public static function preCall(string $method, $listener)
25
    {
26
        $listener = self::makeListener($method, $listener);
27
28
        Event::listen('calling: '. static::class.'@'. $method, $listener);
29
    }
30
31
    public static function postCall(string $method, $listener)
32
    {
33
        $listener = self::makeListener($method, $listener);
34
35
        Event::listen('called: '. static::class.'@'. $method, $listener);
36
    }
37
38
    /**
39
     * Handle dynamic, static calls to the object.
40
     *
41
     * @param string $method
42
     * @param array $args
43
     * @return mixed
44
     *
45
     * @throws \RuntimeException
46
     * @throws \ReflectionException
47
     */
48 5
    public static function __callStatic($method, $args)
49
    {
50 5
        $instance = static::getFacadeRoot();
51
52 5
        if (! $instance) {
53
            throw new RuntimeException('A facade root has not been set.');
54
        }
55
56
        try {
57 5
            event('calling: '. static::class.'@'. $method, [$method, $args]);
58 5
            $result =  $instance->$method(...$args);
59 4
            event('called: '. static::class.'@'. $method, [$result]);
60
61 4
            return $result;
62 5
        } catch (TypeError $error) {
63 5
            $params = (new ReflectionMethod($instance, $method))->getParameters();
64 5
            self::addMissingDependencies($params, $args);
0 ignored issues
show
Documentation introduced by
$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...
65 5
            return $instance->$method(...$args);
66
        }
67
    }
68
69
    /**
70
     * Adds missing dependencies to the user-provided input.
71
     *
72
     * @param ReflectionParameter[] $parameters
73
     * @param array $inputData
74
     */
75 5
    private static function addMissingDependencies($parameters, array &$inputData)
76
    {
77 5
        foreach ($parameters as $i => $parameter) {
78
            // Injects missing type hinted parameters within the array
79 5
            $class = $parameter->getClass()->name ?? false;
80 5
            if ($class && ! ($inputData[$i] ?? false) instanceof $class) {
81 5
                array_splice($inputData, $i, 0, [self::$app[$class]]);
82 4
            } elseif (! array_key_exists($i, $inputData) && $parameter->isDefaultValueAvailable()) {
83 4
                $inputData[] = $parameter->getDefaultValue();
84
            }
85
        }
86 5
    }
87
88
    private static function makeListener(string $method, $listener)
89
    {
90
        if (Str::contains($method, '*')) {
91
            $listener = function ($_eventName, $methodAndArguments) use ($listener) {
92
                static::$app->call($listener, $methodAndArguments);
93
            };
94
        } else {
95
            $listener = function ($methodName, $args) use ($listener) {
96
                static::$app->call($listener, [
97
                    $methodName,
98
                    $args
99
                ]);
100
            };
101
        }
102
103
        return $listener;
104
    }
105
}
106