NewInstance   A
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 102
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 12
eloc 30
c 1
b 0
f 0
dl 0
loc 102
rs 10

8 Methods

Rating   Name   Duplication   Size   Complexity  
A weaveAspects() 0 4 1
A accept() 0 7 1
A __invoke() 0 7 2
A newInstanceArgs() 0 5 1
A enableAop() 0 9 2
A __construct() 0 13 3
A postNewInstance() 0 8 1
A __toString() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Ray\Di;
6
7
use Ray\Aop\Bind as AopBind;
8
use Ray\Aop\WeavedInterface;
9
use ReflectionClass;
10
use ReflectionException;
11
12
use function assert;
13
14
/**
15
 * @psalm-import-type MethodArguments from Types
16
 */
17
final class NewInstance
18
{
19
    /** @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...
20
    private $class;
21
22
    /** @var SetterMethods */
23
    private $setterMethods;
24
25
    /** @var ?Arguments */
26
    private $arguments;
27
28
    /** @var ?AspectBind */
29
    private $bind;
30
31
    /**
32
     * @phpstan-param ReflectionClass<object> $class
33
     */
34
    public function __construct(
35
        ReflectionClass $class,
36
        SetterMethods $setterMethods,
37
        ?Name $constructorName = null
38
    ) {
39
        $constructorName = $constructorName ?: new Name(Name::ANY);
40
        $this->class = $class->getName();
41
        $constructor = $class->getConstructor();
42
        if ($constructor) {
43
            $this->arguments = new Arguments($constructor, $constructorName);
44
        }
45
46
        $this->setterMethods = $setterMethods;
47
    }
48
49
    /**
50
     * @throws ReflectionException
51
     */
52
    public function __invoke(Container $container): object
53
    {
54
        $reflection = new ReflectionClass($this->class);
55
        /** @psalm-suppress MixedMethodCall */
56
        $instance = $this->arguments instanceof Arguments ? $reflection->newInstanceArgs($this->arguments->inject($container)) : new $this->class();
57
58
        return $this->postNewInstance($container, $instance);
59
    }
60
61
    /**
62
     * @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...
63
     */
64
    public function __toString()
65
    {
66
        return $this->class;
67
    }
68
69
    /**
70
     * @param MethodArguments $params
0 ignored issues
show
Bug introduced by
The type Ray\Di\MethodArguments was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
71
     *
72
     * @throws ReflectionException
73
     */
74
    public function newInstanceArgs(Container $container, array $params): object
75
    {
76
        $instance = (new ReflectionClass($this->class))->newInstanceArgs($params);
77
78
        return $this->postNewInstance($container, $instance);
79
    }
80
81
    /**
82
     * @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...
83
     */
84
    public function weaveAspects(string $class, AopBind $bind): void
85
    {
86
        $this->class = $class;
87
        $this->bind = new AspectBind($bind);
88
    }
89
90
    public function accept(VisitorInterface $visitor): void
91
    {
92
        $visitor->visitNewInstance(
93
            $this->class,
94
            $this->setterMethods,
95
            $this->arguments,
96
            $this->bind
97
        );
98
    }
99
100
    private function postNewInstance(Container $container, object $instance): object
101
    {
102
        $this->enableAop($instance, $container);
103
104
        // setter injection
105
        ($this->setterMethods)($instance, $container);
106
107
        return $instance;
108
    }
109
110
    public function enableAop(object $instance, Container $container): void
111
    {
112
        if (! $this->bind instanceof AspectBind) {
113
            return;
114
        }
115
116
        assert($instance instanceof WeavedInterface);
117
118
        $instance->_setBindings($this->bind->inject($container));  // Ray.Aop ^2.18
119
    }
120
}
121