Finder::requireOnce()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Migrations\Finder;
6
7
use Doctrine\Migrations\Finder\Exception\InvalidDirectory;
8
use Doctrine\Migrations\Finder\Exception\NameIsReserved;
9
use ReflectionClass;
10
use function assert;
11
use function get_declared_classes;
12
use function in_array;
13
use function is_dir;
14
use function ksort;
15
use function realpath;
16
use function strlen;
17
use function strncmp;
18
use const SORT_STRING;
19
20
/**
21
 * The Finder class is responsible for for finding migrations on disk at a given path.
22
 */
23
abstract class Finder implements MigrationFinder
24
{
25 14
    protected static function requireOnce(string $path) : void
26
    {
27 14
        require_once $path;
28 14
    }
29
30
    /**
31
     * @throws InvalidDirectory
32
     */
33 41
    protected function getRealPath(string $directory) : string
34
    {
35 41
        $dir = realpath($directory);
36
37 41
        if ($dir === false || ! is_dir($dir)) {
38 4
            throw InvalidDirectory::new($directory);
39
        }
40
41 37
        return $dir;
42
    }
43
44
    /**
45
     * @param string[] $files
46
     *
47
     * @return string[]
48
     *
49
     * @throws NameIsReserved
50
     */
51 37
    protected function loadMigrations(array $files, ?string $namespace) : array
52
    {
53 37
        $includedFiles = [];
54 37
        foreach ($files as $file) {
55 14
            static::requireOnce($file);
56
57 14
            $realFile = realpath($file);
58 14
            assert($realFile !== false);
59
60 14
            $includedFiles[] = $realFile;
61
        }
62
63 37
        $classes  = $this->loadMigrationClasses($includedFiles, $namespace);
64 37
        $versions = [];
65 37
        foreach ($classes as $class) {
66 14
            $versions[] = $class->getName();
67
        }
68
69 37
        ksort($versions, SORT_STRING);
70
71 37
        return $versions;
72
    }
73
74
    /**
75
     * Look up all declared classes and find those classes contained
76
     * in the given `$files` array.
77
     *
78
     * @param string[]    $files     The set of files that were `required`
79
     * @param string|null $namespace If not null only classes in this namespace will be returned
80
     *
81
     * @return ReflectionClass<object>[] the classes in `$files`
0 ignored issues
show
Documentation introduced by
The doc-type ReflectionClass<object>[] could not be parsed: Expected "|" or "end of type", but got "<" at position 15. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
82
     */
83 37
    protected function loadMigrationClasses(array $files, ?string $namespace = null) : array
84
    {
85 37
        $classes = [];
86 37
        foreach (get_declared_classes() as $class) {
87 37
            $reflectionClass = new ReflectionClass($class);
88
89 37
            if (! in_array($reflectionClass->getFileName(), $files, true)) {
90 37
                continue;
91
            }
92
93 14
            if ($namespace !== null && ! $this->isReflectionClassInNamespace($reflectionClass, $namespace)) {
94 3
                continue;
95
            }
96
97 14
            $classes[] = $reflectionClass;
98
        }
99
100 37
        return $classes;
101
    }
102
103
    /**
104
     * @param ReflectionClass<object> $reflectionClass
0 ignored issues
show
Documentation introduced by
The doc-type ReflectionClass<object> could not be parsed: Expected "|" or "end of type", but got "<" at position 15. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
105
     */
106 11
    private function isReflectionClassInNamespace(ReflectionClass $reflectionClass, string $namespace) : bool
107
    {
108 11
        return strncmp($reflectionClass->getName(), $namespace . '\\', strlen($namespace) + 1) === 0;
0 ignored issues
show
Bug introduced by
Consider using $reflectionClass->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
109
    }
110
}
111