Completed
Pull Request — master (#196)
by Andreas
01:43
created

FileManager::getPhpFiles()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 1
dl 0
loc 9
rs 9.9666
c 0
b 0
f 0
1
<?php declare(strict_types = 1);
2
3
namespace Churn\Managers;
4
5
use Churn\Collections\FileCollection;
6
use Churn\Values\File;
7
use RecursiveDirectoryIterator;
8
use RecursiveIteratorIterator;
9
use SplFileInfo;
10
11
class FileManager
12
{
13
    /**
14
     * Collection of File objects.
15
     * @var FileCollection;
16
     */
17
    private $files;
18
19
    /**
20
     * List of file extensions to look for.
21
     * @var array
22
     */
23
    private $fileExtensions;
24
25
    /**
26
     * List of files to ignore.
27
     * @var array
28
     */
29
    private $filesToIgnore;
30
31
    /**
32
     * FileManager constructor.
33
     * @param array $fileExtensions List of file extensions to look for.
34
     * @param array $filesToIgnore  List of files to ignore.
35
     */
36
    public function __construct(array $fileExtensions, array $filesToIgnore)
37
    {
38
        $this->fileExtensions = $fileExtensions;
39
        $this->filesToIgnore = $filesToIgnore;
40
    }
41
42
    /**
43
     * Recursively finds all files with the .php extension in the provided
44
     * $paths and returns list as array.
45
     * @param  array $paths Paths in which to look for .php files.
46
     * @return FileCollection
47
     */
48
    public function getPhpFiles(array $paths): FileCollection
49
    {
50
        $this->files = new FileCollection;
51
        foreach ($paths as $path) {
52
            $this->getPhpFilesFromPath($path);
53
        }
54
55
        return $this->files;
56
    }
57
58
    /**
59
     * Recursively finds all files with the .php extension in the provided
60
     * $path adds them to $this->files.
61
     * @param  string $path Path in which to look for .php files.
62
     * @return void
63
     */
64
    private function getPhpFilesFromPath(string $path): void
65
    {
66
        $directoryIterator = new RecursiveDirectoryIterator($path);
67
        foreach (new RecursiveIteratorIterator($directoryIterator) as $file) {
68
            $this->collectFile($file);
69
        }
70
    }
71
72
    /**
73
     * Collects file information unless it should be ignored.
74
     * @param SplFileInfo $file The file information.
75
     * @return void
76
     */
77
    private function collectFile(SplFileInfo $file): void
78
    {
79
        if (! in_array($file->getExtension(), $this->fileExtensions)) {
80
            return;
81
        }
82
83
        if ($this->fileShouldBeIgnored($file)) {
84
            return;
85
        }
86
87
        $this->files->push(new File(['displayPath' => $file->getPathName(), 'fullPath' => $file->getRealPath()]));
88
    }
89
90
    /**
91
     * Determines if a file should be ignored.
92
     * @param \SplFileInfo $file File.
93
     * @return boolean
94
     */
95
    private function fileShouldBeIgnored(SplFileInfo $file): bool
96
    {
97
        $path = $file->getPathname();
98
99
        $matchingFilesToIgnore = array_filter($this->filesToIgnore, function (string $fileToIgnore) use ($path): bool {
100
            $regex = $this->patternToRegex($fileToIgnore);
101
102
            return preg_match("#{$regex}#", $path) === 1;
103
        });
104
105
        return 0 < count($matchingFilesToIgnore);
106
    }
107
108
    /**
109
     * Translate file path pattern to regex string.
110
     * @param string $filePattern File pattern to be ignored.
111
     * @return string
112
     */
113
    private function patternToRegex(string $filePattern): string
114
    {
115
        $regex = preg_replace("#/(.*)\*([\w.]*)$#", "/$1.+$2$", $filePattern);
116
        return $regex;
117
    }
118
}
119