Passed
Branch main (958b85)
by Michael
03:44
created

CallProxy   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 137
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 16
Bugs 3 Features 0
Metric Value
eloc 41
c 16
b 3
f 0
dl 0
loc 137
ccs 40
cts 40
cp 1
rs 10
wmc 16

6 Methods

Rating   Name   Duplication   Size   Complexity  
A containerCall() 0 8 1
A __call() 0 12 4
A __set() 0 14 5
A __construct() 0 15 1
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 BadMethodCallException;
8
use MichaelRubel\EnhancedContainer\Call;
9
use MichaelRubel\EnhancedContainer\Exceptions\PropertyNotFoundException;
10
use MichaelRubel\EnhancedContainer\Traits\HelpsProxies;
11
use ReflectionException;
12
13
class CallProxy implements Call
14
{
15
    use HelpsProxies;
0 ignored issues
show
Bug introduced by
The trait MichaelRubel\EnhancedContainer\Traits\HelpsProxies requires the property $contextual which is not provided by MichaelRubel\EnhancedContainer\Core\CallProxy.
Loading history...
16
17
    /**
18
     * @var object
19
     */
20
    private object $instance;
21
22
    /**
23
     * @var object|null
24
     */
25
    private ?object $forwardsTo;
26
27
    /**
28
     * CallProxy constructor.
29
     *
30
     * @param object|class-string $class
31
     * @param array               $dependencies
32
     * @param string|null         $context
33
     */
34 58
    public function __construct(
35
        private object | string $class,
36
        private array $dependencies = [],
37
        private ?string $context = null
38
    ) {
39 58
        $this->instance = $this->resolvePassedClass(
40 58
            $this->class,
41 58
            $this->dependencies,
42 58
            $this->context
43
        );
44
45 58
        $this->forwardsTo = (new MethodForwarder(
46 58
            $this->class,
47 58
            $this->dependencies
48 58
        ))->getClass();
49 58
    }
50
51
    /**
52
     * Perform the container call.
53
     *
54
     * @param object $service
55
     * @param string $method
56
     * @param array  $parameters
57
     *
58
     * @return mixed
59
     * @throws ReflectionException
60
     */
61 47
    public function containerCall(object $service, string $method, array $parameters): mixed
62
    {
63 47
        return app()->call(
64 47
            [$service, $method],
65 47
            $this->getPassedParameters(
66 47
                $service,
67
                $method,
68
                $parameters
69
            )
70
        );
71
    }
72
73
    /**
74
     * Gets the internal property by name.
75
     *
76
     * @param string $property
77
     *
78
     * @return mixed
79
     */
80 1
    public function getInternal(string $property): mixed
81
    {
82 1
        return $this->{$property};
83
    }
84
85
    /**
86
     * Pass the call through container.
87
     *
88
     * @param string $method
89
     * @param array  $parameters
90
     *
91
     * @return mixed
92
     * @throws ReflectionException
93
     */
94 51
    public function __call(string $method, array $parameters): mixed
95
    {
96 51
        if (method_exists($this->instance, $method)) {
97 39
            return $this->containerCall($this->instance, $method, $parameters);
98 12
        } elseif (isForwardingEnabled() && ! is_null($this->forwardsTo)) {
99 8
            return $this->containerCall($this->forwardsTo, $method, $parameters);
100
        }
101
102 4
        throw new BadMethodCallException(sprintf(
103 4
            'Call to undefined method %s::%s()',
104 4
            $this->instance::class,
105
            $method
106
        ));
107
    }
108
109
    /**
110
     * Get the instance's property.
111
     *
112
     * @param string $name
113
     *
114
     * @return mixed
115
     * @throws PropertyNotFoundException
116
     */
117 5
    public function __get(string $name): mixed
118
    {
119 5
        if (property_exists($this->instance, $name)) {
120 3
            return $this->instance->{$name};
121 2
        } elseif (isForwardingEnabled() && ! is_null($this->forwardsTo)) {
122 1
            return $this->forwardsTo->{$name};
123
        }
124
125 1
        return $this->throwPropertyNotFoundException($name, $this->instance);
126
    }
127
128
    /**
129
     * Set the instance's property.
130
     *
131
     * @param string $name
132
     * @param mixed  $value
133
     *
134
     * @throws PropertyNotFoundException
135
     */
136 4
    public function __set(string $name, mixed $value): void
137
    {
138 4
        if (property_exists($this->instance, $name)) {
139 1
            $this->instance->{$name} = $value;
140
        } else {
141 3
            if (isForwardingEnabled() && ! is_null($this->forwardsTo)) {
142 2
                property_exists($this->forwardsTo, $name)
143 1
                    ? $this->forwardsTo->{$name} = $value
144 1
                    : $this->throwPropertyNotFoundException($name, $this->forwardsTo);
145
146 1
                return;
147
            }
148
149 1
            $this->throwPropertyNotFoundException($name, $this->instance);
150
        }
151 1
    }
152
}
153