Weaver::newInstance()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 6
Bugs 1 Features 1
Metric Value
eloc 5
c 6
b 1
f 1
dl 0
loc 8
rs 10
cc 1
nc 1
nop 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Ray\Aop;
6
7
use function assert;
8
use function class_exists;
9
use function file_exists;
10
use function sprintf;
11
use function str_replace;
12
13
final class Weaver
14
{
15
    /** @var BindInterface */
16
    private $bind;
17
18
    /** @var string */
19
    private $bindName;
20
21
    /** @var string */
22
    private $classDir;
23
24
    /** @var AopClassName */
25
    private $aopClassName;
26
27
    /** @var Compiler */
28
    private $compiler;
29
30
    public function __construct(BindInterface $bind, string $classDir)
31
    {
32
        $this->bind = $bind;
33
        $this->bindName = $bind->toString('');
34
        $this->compiler = new Compiler($classDir);
35
        $this->classDir = $classDir;
36
        $this->aopClassName = new AopClassName($classDir);
37
    }
38
39
    /**
40
     * @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...
41
     * @param array<int, mixed> $args
42
     */
43
    public function newInstance(string $class, array $args): object
44
    {
45
        $aopClass = $this->weave($class);
46
        $instance = (new ReflectionClass($aopClass))->newInstanceArgs($args);
47
        assert(isset($instance->bindings));
48
        $instance->bindings = $this->bind->getBindings();
49
50
        return $instance;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $instance returns the type object which is incompatible with the type-hinted return object.
Loading history...
51
    }
52
53
    /**
54
     * @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...
55
     *
56
     * @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...
57
     */
58
    public function weave(string $class): string
59
    {
60
        $aopClass = ($this->aopClassName)($class, $this->bindName);
61
        if (class_exists($aopClass, false)) {
62
            return $aopClass;
63
        }
64
65
        if ($this->loadClass($aopClass)) {
66
            assert(class_exists($aopClass));
67
68
            return $aopClass;
69
        }
70
71
        $this->compiler->compile($class, $this->bind);
72
        assert(class_exists($aopClass));
73
74
        return $aopClass;
75
    }
76
77
    private function loadClass(string $class): bool
78
    {
79
        $file = sprintf('%s/%s.php', $this->classDir, str_replace('\\', '_', $class));
80
        if (file_exists($file)) {
81
            require $file;
82
83
            return true;
84
        }
85
86
        return false;
87
    }
88
}
89