Passed
Pull Request — master (#248)
by Fabien
02:25
created

FileFinder   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 90
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 12
eloc 22
dl 0
loc 90
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A fileShouldBeIgnored() 0 10 3
A getPhpFilesFromPath() 0 13 4
A patternToRegex() 0 8 2
A __construct() 0 4 1
A getPhpFiles() 0 4 2
1
<?php declare(strict_types = 1);
2
3
namespace Churn\File;
4
5
use const DIRECTORY_SEPARATOR;
6
use Generator;
7
use function in_array;
8
use function preg_match;
9
use function preg_replace;
10
use RecursiveDirectoryIterator;
11
use RecursiveIteratorIterator;
12
use SplFileInfo;
13
use function str_replace;
14
15
class FileFinder
16
{
17
    /**
18
     * List of file extensions to look for.
19
     * @var array
20
     */
21
    private $fileExtensions;
22
23
    /**
24
     * List of files to ignore.
25
     * @var array
26
     */
27
    private $filesToIgnore;
28
29
    /**
30
     * Class constructor.
31
     * @param array $fileExtensions List of file extensions to look for.
32
     * @param array $filesToIgnore  List of files to ignore.
33
     */
34
    public function __construct(array $fileExtensions, array $filesToIgnore)
35
    {
36
        $this->fileExtensions = $fileExtensions;
37
        $this->filesToIgnore = $filesToIgnore;
38
    }
39
40
    /**
41
     * Recursively finds all files with the .php extension in the provided
42
     * $paths and returns list as array.
43
     * @param array $paths Paths in which to look for .php files.
44
     * @return Generator
45
     */
46
    public function getPhpFiles(array $paths): Generator
47
    {
48
        foreach ($paths as $path) {
49
            yield from $this->getPhpFilesFromPath($path);
50
        }
51
    }
52
53
    /**
54
     * Recursively finds all files with the .php extension in the provided
55
     * $path adds them to $this->files.
56
     * @param string $path Path in which to look for .php files.
57
     * @return Generator
58
     */
59
    private function getPhpFilesFromPath(string $path): Generator
60
    {
61
        $directoryIterator = new RecursiveDirectoryIterator($path);
62
        foreach (new RecursiveIteratorIterator($directoryIterator) as $file) {
63
            if (! in_array($file->getExtension(), $this->fileExtensions)) {
64
                continue;
65
            }
66
67
            if ($this->fileShouldBeIgnored($file)) {
68
                continue;
69
            }
70
71
            yield new File($file->getRealPath(), $file->getPathName());
72
        }
73
    }
74
75
    /**
76
     * Determines if a file should be ignored.
77
     * @param \SplFileInfo $file File.
78
     * @return boolean
79
     */
80
    private function fileShouldBeIgnored(SplFileInfo $file): bool
81
    {
82
        foreach ($this->filesToIgnore as $fileToIgnore) {
83
            $regex = $this->patternToRegex($fileToIgnore);
84
            if (preg_match("#{$regex}#", $file->getRealPath())) {
85
                return true;
86
            }
87
        }
88
89
        return false;
90
    }
91
92
    /**
93
     * Translate file path pattern to regex string.
94
     * @param string $filePattern File pattern to be ignored.
95
     * @return string
96
     */
97
    private function patternToRegex(string $filePattern): string
98
    {
99
        $regex = preg_replace("#(.*)\*([\w.]*)$#", "$1.+$2$", $filePattern);
100
        if (DIRECTORY_SEPARATOR === '\\') {
101
            $regex = str_replace('/', '\\\\', $regex);
102
        }
103
104
        return $regex;
105
    }
106
}
107