Issues (94)

src/di/NewInstance.php (4 issues)

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
use Stringable;
12
13
use function assert;
14
15
/**
16
 * @psalm-import-type MethodArguments from Types
17
 */
18
final class NewInstance implements Stringable
19
{
20
    /** @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...
21
    private string $class;
22
23
    /** @var SetterMethods */
24
    private $setterMethods;
25
    private ?Arguments $arguments = null;
26
    private ?AspectBind $bind = null;
27
28
    /**
29
     * @phpstan-param ReflectionClass<object> $class
30
     */
31
    public function __construct(
32
        ReflectionClass $class,
33
        SetterMethods $setterMethods,
34
        ?Name $constructorName = null
35
    ) {
36
        $constructorName = $constructorName ?: new Name(Name::ANY);
37
        $this->class = $class->getName();
38
        $constructor = $class->getConstructor();
39
        if ($constructor) {
40
            $this->arguments = new Arguments($constructor, $constructorName);
41
        }
42
43
        $this->setterMethods = $setterMethods;
44
    }
45
46
    /**
47
     * @throws ReflectionException
48
     */
49
    public function __invoke(Container $container): object
50
    {
51
        $reflection = new ReflectionClass($this->class);
52
        /** @psalm-suppress MixedMethodCall */
53
        $instance = $this->arguments instanceof Arguments ? $reflection->newInstanceArgs($this->arguments->inject($container)) : new $this->class();
54
55
        return $this->postNewInstance($container, $instance);
56
    }
57
58
    /**
59
     * @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...
60
     */
61
    public function __toString(): string
62
    {
63
        return $this->class;
64
    }
65
66
    /**
67
     * @param MethodArguments $params
0 ignored issues
show
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...
68
     *
69
     * @throws ReflectionException
70
     */
71
    public function newInstanceArgs(Container $container, array $params): object
72
    {
73
        $instance = (new ReflectionClass($this->class))->newInstanceArgs($params);
74
75
        return $this->postNewInstance($container, $instance);
76
    }
77
78
    /**
79
     * @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...
80
     */
81
    public function weaveAspects(string $class, AopBind $bind): void
82
    {
83
        $this->class = $class;
84
        $this->bind = new AspectBind($bind);
85
    }
86
87
    public function accept(VisitorInterface $visitor): void
88
    {
89
        $visitor->visitNewInstance(
90
            $this->class,
91
            $this->setterMethods,
92
            $this->arguments,
93
            $this->bind
94
        );
95
    }
96
97
    private function postNewInstance(Container $container, object $instance): object
98
    {
99
        $this->enableAop($instance, $container);
100
101
        // setter injection
102
        ($this->setterMethods)($instance, $container);
103
104
        return $instance;
105
    }
106
107
    public function enableAop(object $instance, Container $container): void
108
    {
109
        if (! $this->bind instanceof AspectBind) {
110
            return;
111
        }
112
113
        assert($instance instanceof WeavedInterface);
114
115
        $instance->_setBindings($this->bind->inject($container));  // Ray.Aop ^2.18
116
    }
117
}
118