Passed
Pull Request — master (#22)
by Sergei
11:58
created

PathMatcher::only()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 5
rs 10
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Files;
6
7
use Yiisoft\Strings\WildcardPattern;
8
9
final class PathMatcher
10
{
11
    private ?array $only = null;
12
    private ?array $except = null;
13
    private ?array $callbacks = null;
14
15
    private bool $caseSensitive = false;
16
17
    public function caseSensitive(): self
18
    {
19
        $new = clone $this;
20
        $new->caseSensitive = true;
21
        return $new;
22
    }
23
24
    public function notCaseSensitive(): self
25
    {
26
        $new = clone $this;
27
        $new->caseSensitive = false;
28
        return $new;
29
    }
30
31
    /**
32
     * @param string|WildcardPattern ...$patterns
33
     * @return self
34
     */
35
    public function only(...$patterns): self
36
    {
37
        $new = clone $this;
38
        $new->only = $patterns;
39
        return $new;
40
    }
41
42
    /**
43
     * @param string|WildcardPattern ...$patterns
44
     * @return self
45
     */
46
    public function except(string ...$patterns): self
47
    {
48
        $new = clone $this;
49
        $new->except = $patterns;
50
        return $new;
51
    }
52
53
    public function callback(callable ...$callbacks): self
54
    {
55
        $new = clone $this;
56
        $new->callbacks = $callbacks;
57
        return $new;
58
    }
59
60
    public function match(string $path): bool
61
    {
62
        $path = str_replace('\\', '/', $path);
63
64
        if ($this->only !== null) {
65
            if (!$this->matchWildcardPatterns($path, $this->only)) {
66
                return false;
67
            }
68
        }
69
70
        if ($this->except !== null) {
71
            if ($this->matchWildcardPatterns($path, $this->except)) {
72
                return false;
73
            }
74
        }
75
76
        if ($this->callbacks !== null) {
77
            foreach ($this->callbacks as $callback) {
78
                if (!$callback($path)) {
79
                    return false;
80
                }
81
            }
82
        }
83
84
        return true;
85
    }
86
87
    /**
88
     * @param string $path
89
     * @param string|WildcardPattern[] $patterns
90
     * @return bool
91
     */
92
    private function matchWildcardPatterns(string $path, array $patterns): bool
93
    {
94
        $patterns = $this->makeWildcardPatterns($patterns);
95
96
        foreach ($patterns as $pattern) {
97
            if ($pattern->match($path)) {
98
                return true;
99
            }
100
        }
101
102
        return false;
103
    }
104
105
    /**
106
     * @param string[]|WildcardPattern[] $patterns
107
     * @return WildcardPattern[]
108
     */
109
    private function makeWildcardPatterns(array $patterns): array
110
    {
111
        $wildcardPatterns = [];
112
        foreach ($patterns as $pattern) {
113
            if ($pattern instanceof WildcardPattern) {
114
                $wildcardPatterns[] = $pattern;
115
                continue;
116
            }
117
118
            $wildcardPattern = new WildcardPattern('*' . $pattern);
119
120
            if (!$this->caseSensitive) {
121
                $wildcardPattern = $wildcardPattern->ignoreCase();
122
            }
123
124
            $wildcardPatterns[] = $wildcardPattern;
125
        }
126
        return $wildcardPatterns;
127
    }
128
}
129