Completed
Pull Request — master (#724)
by Jonathan
02:33
created

Finder::isReflectionClassInNamespace()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 2
dl 0
loc 7
ccs 4
cts 4
cp 1
crap 2
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Migrations\Finder;
6
7
use InvalidArgumentException;
8
use ReflectionClass;
9
use const PHP_EOL;
10
use const SORT_STRING;
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 sprintf;
17
use function strlen;
18
use function strncmp;
19
use function substr;
20
21
/**
22
 * The Finder class is responsible for for finding migrations on disk at a given path.
23
 */
24
abstract class Finder implements MigrationFinder
25
{
26 41
    protected static function requireOnce(string $path) : void
27
    {
28 41
        require_once $path;
29 41
    }
30
31 110
    protected function getRealPath(string $directory) : string
32
    {
33 110
        $dir = realpath($directory);
34
35 110
        if ($dir === false || ! is_dir($dir)) {
36 4
            throw new InvalidArgumentException(sprintf(
37 4
                'Cannot load migrations from "%s" because it is not a valid directory',
38 4
                $directory
39
            ));
40
        }
41
42 106
        return $dir;
43
    }
44
45
    /**
46
     * @param string[] $files
47
     *
48
     * @return string[]
49
     */
50 106
    protected function loadMigrations(array $files, ?string $namespace) : array
51
    {
52 106
        $includedFiles = [];
53 106
        foreach ($files as $file) {
54 41
            static::requireOnce($file);
55 41
            $includedFiles[] = realpath($file);
56
        }
57
58 106
        $classes  = $this->loadMigrationClasses($includedFiles, $namespace);
59 106
        $versions = [];
60 106
        foreach ($classes as $class) {
61 41
            $version = substr($class->getShortName(), 7);
62
63 41
            if ($version === '0') {
64 1
                throw new InvalidArgumentException(sprintf(
65
                    'Cannot load a migrations with the name "%s" because it is a reserved number by doctrine migrations' . PHP_EOL .
66 1
                    'It\'s used to revert all migrations including the first one.',
67 1
                    $version
68
                ));
69
            }
70
71 40
            $versions[$version] = $class->getName();
72
        }
73
74 105
        ksort($versions, SORT_STRING);
75
76 105
        return $versions;
77
    }
78
79
    /**
80
     * Look up all declared classes and find those classes contained
81
     * in the given `$files` array.
82
     *
83
     * @param string[]    $files     The set of files that were `required`
84
     * @param string|null $namespace If not null only classes in this namespace will be returned
85
     * @return ReflectionClass[] the classes in `$files`
86
     */
87 106
    protected function loadMigrationClasses(array $files, ?string $namespace) : array
88
    {
89 106
        $classes = [];
90 106
        foreach (get_declared_classes() as $class) {
91 106
            $reflectionClass = new ReflectionClass($class);
92
93 106
            if (! in_array($reflectionClass->getFileName(), $files, true)) {
94 106
                continue;
95
            }
96
97 41
            if ($namespace !== null && ! $this->isReflectionClassInNamespace($reflectionClass, $namespace)) {
98 3
                continue;
99
            }
100
101 41
            $classes[] = $reflectionClass;
102
        }
103
104 106
        return $classes;
105
    }
106
107 33
    private function isReflectionClassInNamespace(ReflectionClass $reflectionClass, string $namespace) : bool
108
    {
109 33
        if (strncmp($reflectionClass->getName(), $namespace . '\\', strlen($namespace) + 1) === 0) {
110 33
            return true;
111
        }
112
113 3
        return false;
114
    }
115
}
116