Weaver   A
last analyzed

Complexity

Total Complexity 8

Size/Duplication

Total Lines 79
Duplicated Lines 0 %

Importance

Changes 6
Bugs 0 Features 0
Metric Value
eloc 29
c 6
b 0
f 0
dl 0
loc 79
rs 10
wmc 8

4 Methods

Rating   Name   Duplication   Size   Complexity  
A newInstance() 0 13 2
A loadClass() 0 10 2
A __construct() 0 6 1
A weave() 0 17 3
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 Compiler */
25
    private $compiler;
26
27
    public function __construct(BindInterface $bind, string $classDir)
28
    {
29
        $this->bind = $bind;
30
        $this->bindName = (string) $bind;
31
        $this->compiler = new Compiler($classDir);
32
        $this->classDir = $classDir;
33
    }
34
35
    /**
36
     * @param class-string<T> $class
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<T> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<T>.
Loading history...
37
     * @param list<mixed>     $args
38
     *
39
     * @return T
40
     *
41
     * @template T of object
42
     */
43
    public function newInstance(string $class, array $args): object
44
    {
45
        $aopClass = $this->weave($class);
46
        $instance = (new ReflectionClass($aopClass))->newInstanceArgs($args);
47
        if (! isset($instance->bindings)) {
48
            /** @var T $instance  */
49
            return $instance;
50
        }
51
52
        $instance->bindings = $this->bind->getBindings();
53
        assert($instance instanceof $class);
54
55
        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...
56
    }
57
58
    /**
59
     * @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...
60
     *
61
     * @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...
62
     */
63
    public function weave(string $class): string
64
    {
65
        $aopClass = new AopPostfixClassName($class, $this->bindName, $this->classDir);
66
        if (class_exists($aopClass->fqn, false)) {
67
            return $aopClass->fqn;
68
        }
69
70
        if ($this->loadClass($aopClass->fqn)) {
71
            assert(class_exists($aopClass->fqn));
72
73
            return $aopClass->fqn;
74
        }
75
76
        $newClass = $this->compiler->compile($class, $this->bind);
77
        assert(class_exists($newClass));
78
79
        return $newClass;
80
    }
81
82
    private function loadClass(string $class): bool
83
    {
84
        $file = sprintf('%s/%s.php', $this->classDir, str_replace('\\', '_', $class));
85
        if (file_exists($file)) {
86
            require $file;
87
88
            return true;
89
        }
90
91
        return false;
92
    }
93
}
94