Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
23 / 23 |
|
100.00% |
3 / 3 |
CRAP | |
100.00% |
1 / 1 |
RegexWindowsFilename | |
100.00% |
23 / 23 |
|
100.00% |
3 / 3 |
6 | |
100.00% |
1 / 1 |
__construct | |
100.00% |
10 / 10 |
|
100.00% |
1 / 1 |
2 | |||
getIllegalFilenames | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
2 | |||
getIllegalChars | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
2 |
1 | <?php |
2 | /** |
3 | * @package: pvc |
4 | * @author: Doug Wilbourne (dougwilbourne@gmail.com) |
5 | */ |
6 | |
7 | declare(strict_types = 1); |
8 | |
9 | namespace pvc\regex\filename; |
10 | |
11 | use pvc\regex\err\RegexInvalidDelimiterException; |
12 | use pvc\regex\Regex; |
13 | |
14 | /** |
15 | * Class RegexWindowsFilename |
16 | * |
17 | * Documentation for windows file names can be found at |
18 | * https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file |
19 | */ |
20 | class RegexWindowsFilename extends Regex |
21 | { |
22 | public function __construct(bool $allowFileExtension = true) |
23 | { |
24 | /** |
25 | * illegal filenames are coded as a series of case-insensitive negative lookahead assertions |
26 | * first bracket each filename with begin / end of subject |
27 | */ |
28 | |
29 | $badFileNames = []; |
30 | foreach ($this->getIllegalFilenames() as $filename) { |
31 | $badFileNames[] = '^' . $filename . '$'; |
32 | } |
33 | |
34 | $pattern = ''; |
35 | $pattern .= '/^(?!(?i)(' . implode('|', $badFileNames) . '))'; |
36 | |
37 | // illegal characters are coded as a negative character class. |
38 | $pattern .= '[^' . $this->getIllegalChars($allowFileExtension) . ']*'; |
39 | |
40 | // assert end of subject / end of pattern |
41 | $pattern .= '$/'; |
42 | |
43 | $label = 'windows filename'; |
44 | |
45 | $this->setPattern($pattern); |
46 | $this->setLabel($label); |
47 | } |
48 | |
49 | /** |
50 | * getIllegalFilenames |
51 | * @return array<string> |
52 | */ |
53 | private function getIllegalFilenames(): array |
54 | { |
55 | $illegalFilenames = []; |
56 | $illegalFilenames[] = 'CON'; |
57 | $illegalFilenames[] = 'PRN'; |
58 | $illegalFilenames[] = 'AUX'; |
59 | $illegalFilenames[] = 'NUL'; |
60 | for ($i = 1; $i < 10; $i++) { |
61 | $illegalFilenames[] = 'COM' . $i; |
62 | $illegalFilenames[] = 'LPT' . $i; |
63 | } |
64 | return $illegalFilenames; |
65 | } |
66 | |
67 | /** |
68 | * getIllegalChars |
69 | * @param bool $allowFileExtension |
70 | * @return string |
71 | * @throws RegexInvalidDelimiterException |
72 | * @throws RegexInvalidDelimiterException |
73 | */ |
74 | // the following chars are illegal: < > : " \ / | ? * |
75 | private function getIllegalChars(bool $allowFileExtension): string |
76 | { |
77 | $result = '<>:"\/|?*'; |
78 | if (!$allowFileExtension) { |
79 | $result .= '.'; |
80 | } |
81 | return Regex::escapeString($result, '/'); |
82 | } |
83 | } |