Test Setup Failed
Push — master ( bbcf9b...73bf86 )
by Kirill
02:39
created

ClassLoader   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 124
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 14
lcom 1
cbo 1
dl 0
loc 124
ccs 0
cts 55
cp 0
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * This file is part of Stream package.
5
 *
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 */
9
10
declare(strict_types=1);
11
12
namespace Serafim\Stream;
13
14
use Composer\Autoload\ClassLoader as Composer;
15
use Serafim\Stream\Exception\StreamCreatingException;
16
use Serafim\Stream\Filter\Filter;
17
use Serafim\Stream\Filter\FilterInterface;
18
19
/**
20
 * @property Filter $when
21
 */
22
class ClassLoader
23
{
24
    /**
25
     * @var Composer
26
     */
27
    private Composer $composer;
0 ignored issues
show
Bug introduced by
This code did not parse for me. Apparently, there is an error somewhere around this line:

Syntax error, unexpected T_STRING, expecting T_FUNCTION or T_CONST
Loading history...
28
29
    /**
30
     * @var array<FilterInterface>
31
     */
32
    private array $filters = [];
33
34
    /**
35
     * @var string
36
     */
37
    private string $vendorDir;
38
39
    /**
40
     * @param Composer $composer
41
     * @param bool $register
42
     */
43
    public function __construct(Composer $composer, bool $register = true)
44
    {
45
        $this->composer = $composer;
46
        $this->vendorDir = $this->getVendorDir($composer);
47
48
        if ($register) {
49
            $this->register();
50
        }
51
    }
52
53
    /**
54
     * @param Composer $composer
55
     * @return string
56
     */
57
    private function getVendorDir(Composer $composer): string
58
    {
59
        $dirname = \dirname((new \ReflectionObject($composer))->getFileName(), 2);
60
61
        return \str_replace('\\', '/', $dirname);
62
    }
63
64
    /**
65
     * @return $this
66
     */
67
    public function register(): self
68
    {
69
        \spl_autoload_register([$this, 'loadClass'], true, true);
70
71
        return $this;
72
    }
73
74
    /**
75
     * @return $this
76
     */
77
    public function unregister(): self
78
    {
79
        \spl_autoload_unregister([$this, 'loadClass']);
80
81
        return $this;
82
    }
83
84
    /**
85
     * @return FilterInterface
86
     * @throws StreamCreatingException
87
     */
88
    public function when(): FilterInterface
89
    {
90
        return $this->filters[] = new Filter($this->vendorDir);
91
    }
92
93
    /**
94
     * @param string $class
95
     * @return bool
96
     * @throws \Throwable
97
     */
98
    public function loadClass(string $class): bool
99
    {
100
        if ($this->isSameNamespace($class)) {
101
            return false;
102
        }
103
104
        if (! \is_string($file = $this->composer->findFile($class))) {
105
            return false;
106
        }
107
108
        $file = \str_replace('\\', '/', \realpath($file));
109
110
        foreach ($this->filters as $filter) {
111
            if ($filter->match($class, $file)) {
112
                /** @noinspection PhpIncludeInspection */
113
                require $filter->pathname($file);
114
115
                return true;
116
            }
117
        }
118
119
        return false;
120
    }
121
122
    /**
123
     * @param string $class
124
     * @return bool
125
     */
126
    private function isSameNamespace(string $class): bool
127
    {
128
        return \strpos($class, __NAMESPACE__) === 0;
129
    }
130
131
    /**
132
     * @param string $name
133
     * @return Filter|null
134
     * @throws StreamCreatingException
135
     */
136
    public function __get(string $name)
137
    {
138
        if ($name === 'when') {
139
            return $this->when();
140
        }
141
142
        return null;
143
    }
144
}
145