Completed
Push — master ( aeab7d...5360da )
by Iman
29s queued 11s
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 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 7
    protected static function getFacadeAccessor()
15
    {
16 7
        return static::class;
17
    }
18
19 7
    public static function shouldProxyTo($class)
20
    {
21 7
        static::$app->singleton(self::getFacadeAccessor(), $class);
22 7
    }
23
24 3
    public static function preCall($methodName, $listener)
25
    {
26 3
        $listener = self::makeListener($methodName, $listener);
27
28 3
        Event::listen('calling: '.static::class.'@'.$methodName, $listener);
29 3
    }
30
31 3
    public static function postCall($methodName, $listener)
32
    {
33 3
        $listener = self::makeListener($methodName, $listener);
34
35 3
        Event::listen('called: '.static::class.'@'.$methodName, $listener);
36 3
    }
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 7
    public static function __callStatic($method, $args)
49
    {
50 7
        $instance = static::getFacadeRoot();
51
52 7
        if (! $instance) {
53
            throw new RuntimeException('A facade root has not been set.');
54
        }
55
56
        try {
57 7
            Event::dispatch('calling: '.static::class.'@'.$method, [$method, $args]);
58 7
            $result = $instance->$method(...$args);
59 6
            Event::dispatch('called: '.static::class.'@'.$method, [$method, $args, $result]);
60
61 6
            return $result;
62 4
        } catch (TypeError $error) {
63 4
            $params = (new ReflectionMethod($instance, $method))->getParameters();
64 4
            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 4
            $result = $instance->$method(...$args);
66 3
            Event::dispatch('called: '.static::class.'@'.$method, [$method, $args, $result]);
67
68 3
            return $result;
69
        }
70
    }
71
72
    /**
73
     * Adds missing dependencies to the user-provided input.
74
     *
75
     * @param ReflectionParameter[] $parameters
76
     * @param array $inputData
77
     */
78 4
    private static function addMissingDependencies($parameters, array &$inputData)
79
    {
80 4
        foreach ($parameters as $i => $parameter) {
81
            // Injects missing type hinted parameters within the array
82 4
            $class = $parameter->getClass()->name ?? false;
83 4
            if ($class && ! ($inputData[$i] ?? false) instanceof $class) {
84 4
                array_splice($inputData, $i, 0, [self::$app[$class]]);
85 3
            } elseif (! array_key_exists($i, $inputData) && $parameter->isDefaultValueAvailable()) {
86 3
                $inputData[] = $parameter->getDefaultValue();
87
            }
88
        }
89 4
    }
90
91 3
    private static function makeListener(string $method, $listener)
92
    {
93 3
        if (Str::contains($method, '*')) {
94
            // The $_eventName variable is passed to us by laravel
95
            // but we do not need it, because we already know it.
96
            return function ($_eventName, $methodAndArguments) use ($listener) {
97 1
                static::$app->call($listener, $methodAndArguments);
98 1
            };
99
        }
100
101
        return function ($methodName, $args, $result = null) use ($listener) {
102 1
            static::$app->call($listener, [
103 1
                $methodName,
104 1
                $args,
105 1
                $result,
106
            ]);
107 2
        };
108
    }
109
}
110