Passed
Push — master ( 008e85...df25f0 )
by Koldo
02:32
created

GetRealPathFromNamespace   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 51
Duplicated Lines 0 %

Test Coverage

Coverage 88.89%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 30
c 1
b 0
f 0
dl 0
loc 51
ccs 24
cts 27
cp 0.8889
rs 10
wmc 9

2 Methods

Rating   Name   Duplication   Size   Complexity  
B __invoke() 0 35 8
A __construct() 0 6 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Antidot\DevTools\Application\Service;
6
7
use Composer\Autoload\ClassLoader;
8
use InvalidArgumentException;
9
10
use function array_key_exists;
11
use function is_array;
12
use function is_string;
13
use function spl_autoload_functions;
14
use function sprintf;
15
16
class GetRealPathFromNamespace
17
{
18
    public const MAXIMUM_DEPTH_MESSAGE =
19
        'Given class name %s exceeded maximum path depth, probably given namespace is not defined';
20
    public const NOT_AUTOLOAD_MESSAGE = 'Your autoload stack is not activated';
21
    private GetClassNameFromFQCN $getClassNameFromFQCN;
22
    private GetNamespaceFromFQCN $getNamespaceFromFQCN;
23
24 4
    public function __construct(
25
        GetClassNameFromFQCN $getClassNameFromFQCN,
26
        GetNamespaceFromFQCN $getNamespaceFromFQCN
27
    ) {
28 4
        $this->getClassNameFromFQCN = $getClassNameFromFQCN;
29 4
        $this->getNamespaceFromFQCN = $getNamespaceFromFQCN;
30 4
    }
31
32 4
    public function __invoke(string $namespace): string
33
    {
34 4
        $classDir = null;
35 4
        $parts = '';
36 4
        $initialNamespace = $namespace;
37 4
        $autoloadFunctions = spl_autoload_functions();
38 4
        if (!is_array($autoloadFunctions)) {
0 ignored issues
show
introduced by
The condition is_array($autoloadFunctions) is always true.
Loading history...
39
            throw new \RuntimeException(self::NOT_AUTOLOAD_MESSAGE);
40
        }
41 4
        foreach ($autoloadFunctions as $autoloader) {
42 4
            if (false === is_array($autoloader)) {
43
                continue;
44
            }
45
            /** @var ClassLoader $classLoader */
46 4
            $classLoader = $autoloader[0];
47 4
            $depth = 0;
48 4
            while (null === $classDir) {
49 4
                if (array_key_exists($namespace . "\\", $classLoader->getPrefixesPsr4())) {
50 2
                    $classDir = $classLoader->getPrefixesPsr4()[$namespace . "\\"][0];
51
                } else {
52 4
                    $parts = DIRECTORY_SEPARATOR . $this->getClassNameFromFQCN->__invoke($namespace) . $parts;
53 4
                    $namespace = $this->getNamespaceFromFQCN->__invoke($namespace);
54
                }
55 4
                if (10 <= $depth) {
56 2
                    throw new InvalidArgumentException(sprintf(self::MAXIMUM_DEPTH_MESSAGE, $initialNamespace));
57
                }
58 4
                $depth++;
59
            }
60
        }
61
62 2
        if (false === is_string($classDir)) {
63
            throw new InvalidArgumentException(sprintf(self::MAXIMUM_DEPTH_MESSAGE, $initialNamespace));
64
        }
65
66 2
        return sprintf('%s%s', $classDir, $parts);
67
    }
68
}
69