Passed
Push — main ( 1d9df5...8b05a9 )
by Michael
03:25
created

CallProxy   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 155
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 20
Bugs 3 Features 0
Metric Value
eloc 45
dl 0
loc 155
ccs 45
cts 45
cp 1
rs 10
c 20
b 3
f 0
wmc 21

7 Methods

Rating   Name   Duplication   Size   Complexity  
A containerCall() 0 17 3
A shouldForward() 0 3 2
A __call() 0 7 3
A __set() 0 14 5
A __construct() 0 18 3
A __get() 0 9 4
A getInternal() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace MichaelRubel\EnhancedContainer\Core;
6
7
use Illuminate\Support\Traits\ForwardsCalls;
8
use MichaelRubel\EnhancedContainer\Call;
9
use MichaelRubel\EnhancedContainer\Exceptions\PropertyNotFoundException;
10
use MichaelRubel\EnhancedContainer\Traits\HelpsProxies;
11
12
class CallProxy implements Call
13
{
14
    use HelpsProxies, ForwardsCalls;
0 ignored issues
show
introduced by
The trait MichaelRubel\EnhancedContainer\Traits\HelpsProxies requires some properties which are not provided by MichaelRubel\EnhancedContainer\Core\CallProxy: $contextual, $map
Loading history...
15
16
    /**
17
     * @var object
18
     */
19
    private object $instance;
20
21
    /**
22
     * @var object|null
23
     */
24
    private ?object $forwardsTo = null;
25
26
    /**
27
     * CallProxy constructor.
28
     *
29
     * @param object|string $class
30
     * @param array         $dependencies
31
     * @param string|null   $context
32
     */
33 63
    public function __construct(
34
        private object | string $class,
35
        private array $dependencies = [],
36
        private ?string $context = null
37
    ) {
38 63
        $this->instance = ! is_object($class)
39 50
            ? $this->resolvePassedClass(
40 50
                $this->class,
0 ignored issues
show
Bug introduced by
It seems like $this->class can also be of type object; however, parameter $class of MichaelRubel\EnhancedCon...y::resolvePassedClass() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

40
                /** @scrutinizer ignore-type */ $this->class,
Loading history...
41 50
                $this->dependencies,
42 50
                $this->context
43
            )
44 16
            : $class;
45
46 63
        if (isForwardingEnabled()) {
47 18
            $this->forwardsTo = app(MethodForwarder::class, [
48 18
                'class'        => $this->class,
49 18
                'dependencies' => $this->dependencies,
50 18
            ])->getClass();
51
        }
52 63
    }
53
54
    /**
55
     * Perform the container call.
56
     *
57
     * @param object $service
58
     * @param string $method
59
     * @param array  $parameters
60
     *
61
     * @return mixed
62
     * @throws \ReflectionException
63
     */
64 56
    public function containerCall(object $service, string $method, array $parameters): mixed
65
    {
66
        try {
67 56
            return app()->call(
68 56
                [$service, $method],
69 56
                $this->getPassedParameters(
70 56
                    $service,
71
                    $method,
72
                    $parameters
73
                )
74
            );
75 11
        } catch (\ReflectionException $e) {
76 2
            if (config('enhanced-container.manual_forwarding') ?? false) {
77 1
                return $this->forwardCallTo($service, $method, $parameters);
78
            }
79
80 1
            throw $e;
81
        }
82
    }
83
84
    /**
85
     * Gets the internal property by name.
86
     *
87
     * @param string $property
88
     *
89
     * @return mixed
90
     */
91 3
    public function getInternal(string $property): mixed
92
    {
93 3
        return $this->{$property};
94
    }
95
96
    /**
97
     * Determine if the method should be forwarded.
98
     *
99
     * @param string $method
100
     *
101
     * @return bool
102
     */
103 14
    public function shouldForward(string $method): bool
104
    {
105 14
        return isForwardingEnabled() && ! method_exists($this->instance, $method);
106
    }
107
108
    /**
109
     * Pass the call through container.
110
     *
111
     * @param string $method
112
     * @param array  $parameters
113
     *
114
     * @return mixed
115
     * @throws \ReflectionException
116
     */
117 56
    public function __call(string $method, array $parameters): mixed
118
    {
119 56
        if (! is_null($this->forwardsTo) && $this->shouldForward($method)) {
120 10
            return $this->containerCall($this->forwardsTo, $method, $parameters);
121
        }
122
123 46
        return $this->containerCall($this->instance, $method, $parameters);
124
    }
125
126
    /**
127
     * Get the instance's property.
128
     *
129
     * @param string $name
130
     *
131
     * @return mixed
132
     * @throws PropertyNotFoundException
133
     */
134 5
    public function __get(string $name): mixed
135
    {
136 5
        if (property_exists($this->instance, $name)) {
137 3
            return $this->instance->{$name};
138 2
        } elseif (isForwardingEnabled() && ! is_null($this->forwardsTo)) {
139 1
            return $this->forwardsTo->{$name};
140
        }
141
142 1
        return $this->throwPropertyNotFoundException($name, $this->instance);
143
    }
144
145
    /**
146
     * Set the instance's property.
147
     *
148
     * @param string $name
149
     * @param mixed  $value
150
     *
151
     * @throws PropertyNotFoundException
152
     */
153 4
    public function __set(string $name, mixed $value): void
154
    {
155 4
        if (property_exists($this->instance, $name)) {
156 1
            $this->instance->{$name} = $value;
157
        } else {
158 3
            if (isForwardingEnabled() && ! is_null($this->forwardsTo)) {
159 2
                property_exists($this->forwardsTo, $name)
160 1
                    ? $this->forwardsTo->{$name} = $value
161 1
                    : $this->throwPropertyNotFoundException($name, $this->forwardsTo);
162
163 1
                return;
164
            }
165
166 1
            $this->throwPropertyNotFoundException($name, $this->instance);
167
        }
168 1
    }
169
}
170