Passed
Pull Request — master (#39)
by
unknown
02:42
created

ObjectProxy::afterCall()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 1
eloc 1
c 1
b 1
f 0
nc 1
nop 4
dl 0
loc 7
ccs 2
cts 2
cp 1
crap 1
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Proxy;
6
7
use Throwable;
8
9
/**
10
 * Base proxy class for objects to use in {@see ProxyManager}. A concrete implementation can be provided too.
11
 */
12
class ObjectProxy
13
{
14
    use ProxyTrait;
15
16 8
    public function __construct(
17
        /**
18
        * @var object An instance of the class for proxying method calls.
19
        */
20
        private object $instance
21
    ) {
22
    }
23
24
    /**
25
     * Gets instance.
26
     *
27
     * @return object {@see $instance}.
28
     */
29 1
    public function getInstance(): object
30
    {
31 1
        return $this->instance;
32
    }
33
34
    /**
35
     * Calls a method in the {@see $instance} additionally allowing to process result afterwards (even in case of
36
     * error).
37
     *
38
     * @param string $methodName A called method in the {@see $instance}.
39
     * @param array $arguments A list of arguments passed to a called method. The order must be maintained.
40
     *
41
     * @throws Throwable In case of error happen during the method call.
42
     *
43
     * @return $this|mixed Either a new instance of {@see $instance} class or return value of a called method.
44
     */
45 7
    protected function call(string $methodName, array $arguments): mixed
46
    {
47 7
        $this->resetCurrentError();
48 7
        $result = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $result is dead and can be removed.
Loading history...
49 7
        $timeStart = microtime(true);
50
        try {
51 7
            $result = $this->callInternal($methodName, $arguments);
52 3
        } catch (Throwable $e) {
53 3
            $this->repeatError($e);
54 4
        } finally {
55 7
            $result = $this->afterCall($methodName, $arguments, $result, $timeStart);
0 ignored issues
show
Bug introduced by
It seems like $timeStart can also be of type string; however, parameter $timeStart of Yiisoft\Proxy\ObjectProxy::afterCall() does only seem to accept double, 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

55
            $result = $this->afterCall($methodName, $arguments, $result, /** @scrutinizer ignore-type */ $timeStart);
Loading history...
56
        }
57
58 4
        return $this->processResult($result);
59
    }
60
61
    /**
62
     * An event executed after each call of a method. Can be used for handling errors, logging, etc. `$result` must be
63
     * always returned.
64
     *
65
     * @param string $methodName A called method in the {@see $instance}.
66
     * @param array $arguments A list of arguments passed to a called method. The order must be maintained.
67
     * @param mixed $result Return value of a called method.
68
     * @param float $timeStart UNIX timestamp right before proxy method call. For example: `1656657586.4849`.
69
     *
70
     * @return mixed Return value of a called method.
71
     */
72 7
    protected function afterCall(
73
        string $methodName,
74
        array $arguments,
75
        mixed $result,
76
        float $timeStart
77
    ): mixed {
78 7
        return $result;
79
    }
80
81
    /**
82
     * Gets new instance of {@see $instance} class.
83
     *
84
     * @param object $instance {@see $instance}.
85
     *
86
     * @return $this A new instance of the same class
87
     */
88 1
    protected function getNewStaticInstance(object $instance): self
89
    {
90 1
        return new static($instance);
91
    }
92
93
    /**
94
     * Just calls a method in the {@see $instance}.
95
     *
96
     * @param string $methodName A called method in the {@see $instance}.
97
     * @param array $arguments A list of arguments passed to a called method. The order must be maintained.
98
     *
99
     * @return mixed Return value of a called method.
100
     */
101 7
    private function callInternal(string $methodName, array $arguments): mixed
102
    {
103 7
        return $this->instance->$methodName(...$arguments);
104
    }
105
106
    /**
107
     * Processes return value of a called method - if it's a instance of the same class in {@see $instance} - a new
108
     * instance is created, otherwise it's returned as is.
109
     *
110
     * @param mixed $result Return value of a called method.
111
     *
112
     * @return $this|mixed Either a new instance of {@see $instance} class or return value of a called method.
113
     */
114 4
    private function processResult(mixed $result): mixed
115
    {
116 4
        if (is_object($result) && get_class($result) === get_class($this->instance)) {
117 1
            $result = $this->getNewStaticInstance($result);
118
        }
119
120 4
        return $result;
121
    }
122
}
123