Passed
Push — ray-aop-set-bindings ( f5205e )
by Akihito
02:22
created

NewInstance::enableAop()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 3
c 1
b 0
f 0
dl 0
loc 7
rs 10
cc 2
nc 2
nop 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Ray\Di;
6
7
use Ray\Aop\Bind as AopBind;
8
use ReflectionClass;
9
use ReflectionException;
10
11
final class NewInstance
12
{
13
    /** @var class-string */
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string.
Loading history...
14
    private $class;
15
16
    /** @var SetterMethods */
17
    private $setterMethods;
18
19
    /** @var ?Arguments */
20
    private $arguments;
21
22
    /** @var ?AspectBind */
23
    private $bind;
24
25
    /**
26
     * @phpstan-param ReflectionClass<object> $class
27
     */
28
    public function __construct(
29
        ReflectionClass $class,
30
        SetterMethods $setterMethods,
31
        ?Name $constructorName = null
32
    ) {
33
        $constructorName = $constructorName ?: new Name(Name::ANY);
34
        $this->class = $class->getName();
35
        $constructor = $class->getConstructor();
36
        if ($constructor) {
37
            $this->arguments = new Arguments($constructor, $constructorName);
38
        }
39
40
        $this->setterMethods = $setterMethods;
41
    }
42
43
    /**
44
     * @throws ReflectionException
45
     */
46
    public function __invoke(Container $container): object
47
    {
48
        /** @psalm-suppress MixedMethodCall */
49
        $instance = $this->arguments instanceof Arguments ? (new ReflectionClass($this->class))->newInstanceArgs($this->arguments->inject($container)) : new $this->class();
50
51
        return $this->postNewInstance($container, $instance);
52
    }
53
54
    /**
55
     * @return class-string
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string.
Loading history...
56
     */
57
    public function __toString()
58
    {
59
        return $this->class;
60
    }
61
62
    /**
63
     * @param array<int, mixed> $params
64
     *
65
     * @throws ReflectionException
66
     */
67
    public function newInstanceArgs(Container $container, array $params): object
68
    {
69
        $instance = (new ReflectionClass($this->class))->newInstanceArgs($params);
70
71
        return $this->postNewInstance($container, $instance);
72
    }
73
74
    /**
75
     * @param class-string $class
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string.
Loading history...
76
     */
77
    public function weaveAspects(string $class, AopBind $bind): void
78
    {
79
        $this->class = $class;
80
        $this->bind = new AspectBind($bind);
81
    }
82
83
    public function accept(VisitorInterface $visitor): void
84
    {
85
        $visitor->visitNewInstance(
86
            $this->class,
87
            $this->setterMethods,
88
            $this->arguments,
89
            $this->bind
90
        );
91
    }
92
93
    private function postNewInstance(Container $container, object $instance): object
94
    {
95
        $this->enableAop($instance, $container);
96
97
        // setter injection
98
        ($this->setterMethods)($instance, $container);
99
100
        return $instance;
101
    }
102
103
    public function enableAop(object $instance, Container $container): void
104
    {
105
        if (! $this->bind instanceof AspectBind) {
106
            return;
107
        }
108
109
        $instance->__setBindings($this->bind->inject($container));  // Ray.Aop ^2.18
110
    }
111
}
112