Injector   A
last analyzed

Complexity

Total Complexity 8

Size/Duplication

Total Lines 69
Duplicated Lines 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
wmc 8
eloc 24
c 3
b 0
f 0
dl 0
loc 69
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A getInstance() 0 14 2
A bind() 0 7 1
A __construct() 0 13 3
A __wakeup() 0 7 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Ray\Di;
6
7
use Ray\Aop\Compiler;
8
use Ray\Di\Exception\DirectoryNotWritable;
9
use Ray\Di\Exception\Untargeted;
10
11
use function assert;
12
use function file_exists;
13
use function is_dir;
14
use function is_writable;
15
use function spl_autoload_register;
16
use function sprintf;
17
use function str_replace;
18
use function sys_get_temp_dir;
19
20
/**
21
 * @psalm-import-type BindableInterface from Types
22
 * @psalm-import-type ModuleList from Types
23
 * @psalm-import-type ScriptDir from Types
24
 */
25
final class Injector implements InjectorInterface
26
{
27
    /** @var ScriptDir */
0 ignored issues
show
Bug introduced by
The type Ray\Di\ScriptDir 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...
28
    private readonly string $classDir;
29
    private readonly Container $container;
30
31
    /**
32
     * @param AbstractModule|ModuleList|null $module Module(s)
0 ignored issues
show
Bug introduced by
The type Ray\Di\ModuleList 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...
33
     * @param string                         $tmpDir Temp directory for generated class
34
     */
35
    public function __construct($module = null, string $tmpDir = '')
36
    {
37
        /** @var ScriptDir $classDir */
38
        $classDir = is_dir($tmpDir) ? $tmpDir : sys_get_temp_dir();
39
        if (! is_writable($classDir)) {
40
            throw new DirectoryNotWritable($classDir); // @codeCoverageIgnore
41
        }
42
43
        $this->classDir = $classDir;
0 ignored issues
show
Bug introduced by
The property classDir is declared read-only in Ray\Di\Injector.
Loading history...
44
        $this->container = (new ContainerFactory())($module, $this->classDir);
0 ignored issues
show
Bug introduced by
The property container is declared read-only in Ray\Di\Injector.
Loading history...
45
        // Bind injector (built-in bindings)
46
        (new Bind($this->container, InjectorInterface::class))->toInstance($this);
47
        $this->container->sort();
48
    }
49
50
    /**
51
     * Wakeup
52
     */
53
    public function __wakeup()
54
    {
55
        spl_autoload_register(
56
            function (string $class): void {
57
                $file = sprintf('%s/%s.php', $this->classDir, str_replace('\\', '_', $class));
58
                if (file_exists($file)) {
59
                    include $file; //@codeCoverageIgnore
60
                }
61
            }
62
        );
63
    }
64
65
    /**
66
     * {@inheritDoc}
67
     */
68
    public function getInstance($interface, $name = Name::ANY)
69
    {
70
        try {
71
            /** @psalm-suppress MixedAssignment */
72
            $instance = $this->container->getInstance($interface, $name);
73
        } catch (Untargeted) {
74
            /** @psalm-var class-string $interface */
75
            $this->bind($interface);
76
            /** @psalm-suppress MixedAssignment */
77
            $instance = $this->getInstance($interface, $name);
78
        }
79
80
        /** @psalm-suppress MixedReturnStatement */
81
        return $instance;
82
    }
83
84
    /**
85
     * @param BindableInterface $class
0 ignored issues
show
Bug introduced by
The type Ray\Di\BindableInterface 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...
86
     */
87
    private function bind(string $class): void
88
    {
89
        new Bind($this->container, $class);
90
        $bound = $this->container->getContainer()[$class . '-' . Name::ANY];
91
        assert($bound instanceof Dependency);
92
        /** @psalm-suppress InvalidArgument */
93
        $this->container->weaveAspect(new Compiler($this->classDir), $bound)->getInstance($class);
94
    }
95
}
96