Passed
Push — master ( cb7e35...4ff97b )
by Koldo
02:36
created

GetRealPathFromNamespace::__invoke()   A

Complexity

Conditions 6
Paths 7

Size

Total Lines 29
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 6.0052

Importance

Changes 3
Bugs 1 Features 0
Metric Value
cc 6
eloc 19
c 3
b 1
f 0
nc 7
nop 1
dl 0
loc 29
ccs 18
cts 19
cp 0.9474
crap 6.0052
rs 9.0111
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
    private GetClassNameFromFQCN $getClassNameFromFQCN;
21
    private GetNamespaceFromFQCN $getNamespaceFromFQCN;
22
23 4
    public function __construct(
24
        GetClassNameFromFQCN $getClassNameFromFQCN,
25
        GetNamespaceFromFQCN $getNamespaceFromFQCN
26
    ) {
27 4
        $this->getClassNameFromFQCN = $getClassNameFromFQCN;
28 4
        $this->getNamespaceFromFQCN = $getNamespaceFromFQCN;
29 4
    }
30
31 4
    public function __invoke(string $namespace): string
32
    {
33 4
        $classDir = null;
34 4
        $parts = '';
35 4
        $initialNamespace = $namespace;
36
        /** @var array $autoloadFunctions */
37 4
        $autoloadFunctions = spl_autoload_functions();
38 4
        foreach ($autoloadFunctions as $autoloader) {
39 4
            if (false === is_array($autoloader)) {
40
                continue;
41
            }
42
            /** @var ClassLoader $classLoader */
43 4
            $classLoader = $autoloader[0];
44 4
            $depth = 0;
45 4
            while (null === $classDir) {
46 4
                if (array_key_exists($namespace . "\\", $classLoader->getPrefixesPsr4())) {
47 2
                    $classDir = $classLoader->getPrefixesPsr4()[$namespace . "\\"][0];
48
                } else {
49 4
                    $parts = DIRECTORY_SEPARATOR . $this->getClassNameFromFQCN->__invoke($namespace) . $parts;
50 4
                    $namespace = $this->getNamespaceFromFQCN->__invoke($namespace);
51
                }
52 4
                if (10 <= $depth) {
53 2
                    throw new InvalidArgumentException(sprintf(self::MAXIMUM_DEPTH_MESSAGE, $initialNamespace));
54
                }
55 4
                $depth++;
56
            }
57
        }
58
59 2
        return sprintf('%s%s', $classDir, $parts);
60
    }
61
}
62