Completed
Push — master ( 4e91f8...8d71d2 )
by Alexander
02:35
created

Enumerator::getFileFullPath()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
crap 1
1
<?php
2
declare(strict_types = 1);
3
/*
4
 * Go! AOP framework
5
 *
6
 * @copyright Copyright 2015, Lisachenko Alexander <[email protected]>
7
 *
8
 * This source file is subject to the license that is bundled
9
 * with this source code in the file LICENSE.
10
 */
11
12
namespace Go\Instrument\FileSystem;
13
14
use Closure;
15
use SplFileInfo;
16
17
/**
18
 * Enumerates files in the concrete directory, applying filtration logic
19
 */
20
class Enumerator
21
{
22
23
    /**
24
     * Path to the root directory, where enumeration should start
25
     *
26
     * @var string
27
     */
28
    private $rootDirectory;
29
30
    /**
31
     * List of additional include paths, should be below rootDirectory
32
     *
33
     * @var array
34
     */
35
    private $includePaths;
36
37
    /**
38
     * List of additional exclude paths, should be below rootDirectory
39
     *
40
     * @var array
41
     */
42
    private $excludePaths;
43
44
    /**
45
     * Initializes an enumerator
46
     *
47
     * @param string $rootDirectory Path to the root directory
48
     * @param array  $includePaths  List of additional include paths
49
     * @param array  $excludePaths  List of additional exclude paths
50
     */
51 7
    public function __construct(string $rootDirectory, array $includePaths = [], array $excludePaths = [])
52
    {
53 7
        $this->rootDirectory = $rootDirectory;
54 7
        $this->includePaths = $includePaths;
55 7
        $this->excludePaths = $excludePaths;
56 7
    }
57
58
    /**
59
     * Returns an enumerator for files
60
     *
61
     * @return \CallbackFilterIterator|\RecursiveIteratorIterator|SplFileInfo[]
62
     */
63 7
    public function enumerate()
64
    {
65 7
        $iterator = new \RecursiveIteratorIterator(
66 7
            new \RecursiveDirectoryIterator(
67 7
                $this->rootDirectory,
68 7
                \FilesystemIterator::SKIP_DOTS
69
            )
70
        );
71
72 7
        $callback = $this->getFilter();
73 7
        $iterator = new \CallbackFilterIterator($iterator, $callback);
74
75 7
        return $iterator;
76
    }
77
78
    /**
79
     * Returns a filter callback for enumerating files
80
     */
81 7
    public function getFilter() : Closure
82
    {
83 7
        $rootDirectory = $this->rootDirectory;
84 7
        $includePaths = $this->includePaths;
85 7
        $excludePaths = $this->excludePaths;
86
87 7
        return function (\SplFileInfo $file) use ($rootDirectory, $includePaths, $excludePaths) {
88
89 7
            if ($file->getExtension() !== 'php') {
90
                return false;
91
            };
92
93 7
            $fullPath = $this->getFileFullPath($file);
94
            // Do not touch files that not under rootDirectory
95 7
            if (strpos($fullPath, $rootDirectory) !== 0) {
96
                return false;
97
            }
98
99 7
            if (!empty($includePaths)) {
100 1
                $found = false;
101 1
                foreach ($includePaths as $includePattern) {
102 1
                    if (fnmatch("{$includePattern}*", $fullPath, FNM_NOESCAPE)) {
103 1
                        $found = true;
104 1
                        break;
105
                    }
106
                }
107 1
                if (!$found) {
108
                    return false;
109
                }
110
            }
111
112 7
            foreach ($excludePaths as $excludePattern) {
113 4
                if (fnmatch("{$excludePattern}*", $fullPath, FNM_NOESCAPE)) {
114 4
                    return false;
115
                }
116
            }
117
118 5
            return true;
119 7
        };
120
    }
121
122
    /**
123
     * Return the real path of the given file
124
     *
125
     * This is used for testing purpose with virtual file system.
126
     * In a vfs the 'realPath' methode will always return false.
127
     * So we have a chance to mock this single function to return different path.
128
     *
129
     * @param SplFileInfo $file
130
     *
131
     * @return string
132
     */
133 1
    protected function getFileFullPath(SplFileInfo $file) : string
134
    {
135 1
        return $file->getRealPath();
136
    }
137
138
}
139