1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* @package s9e\TextFormatter |
5
|
|
|
* @copyright Copyright (c) 2010-2019 The s9e Authors |
6
|
|
|
* @license http://www.opensource.org/licenses/mit-license.php The MIT License |
7
|
|
|
*/ |
8
|
|
|
namespace s9e\TextFormatter\Configurator\Collections; |
9
|
|
|
|
10
|
|
|
use s9e\TextFormatter\Configurator\Helpers\RegexpBuilder; |
11
|
|
|
use s9e\TextFormatter\Configurator\Items\Regexp; |
12
|
|
|
|
13
|
|
|
class HostnameList extends NormalizedList |
14
|
|
|
{ |
15
|
|
|
/** |
16
|
|
|
* Return this hostname list as a regexp's config |
17
|
|
|
* |
18
|
|
|
* @return Regexp|null A Regexp instance, or NULL if the collection is empty |
19
|
|
|
*/ |
20
|
8 |
|
public function asConfig() |
21
|
|
|
{ |
22
|
8 |
|
if (empty($this->items)) |
23
|
|
|
{ |
24
|
1 |
|
return null; |
25
|
|
|
} |
26
|
|
|
|
27
|
7 |
|
return new Regexp($this->getRegexp()); |
28
|
|
|
} |
29
|
|
|
|
30
|
|
|
/** |
31
|
|
|
* Return a regexp that matches the list of hostnames |
32
|
|
|
* |
33
|
|
|
* @return string |
34
|
|
|
*/ |
35
|
7 |
|
public function getRegexp() |
36
|
|
|
{ |
37
|
7 |
|
$hosts = []; |
38
|
7 |
|
foreach ($this->items as $host) |
39
|
|
|
{ |
40
|
7 |
|
$hosts[] = $this->normalizeHostmask($host); |
41
|
|
|
} |
42
|
|
|
|
43
|
7 |
|
$regexp = RegexpBuilder::fromList( |
44
|
7 |
|
$hosts, |
45
|
|
|
[ |
46
|
|
|
// Asterisks * are turned into a catch-all expression, while ^ and $ are preserved |
47
|
|
|
'specialChars' => [ |
48
|
7 |
|
'*' => '.*', |
49
|
|
|
'^' => '^', |
50
|
|
|
'$' => '$' |
51
|
|
|
] |
52
|
|
|
] |
53
|
|
|
); |
54
|
|
|
|
55
|
7 |
|
return '/' . $regexp . '/DSis'; |
56
|
|
|
} |
57
|
|
|
|
58
|
|
|
/** |
59
|
|
|
* Normalize a hostmask to a regular expression |
60
|
|
|
* |
61
|
|
|
* @param string $host Hostname or hostmask |
62
|
|
|
* @return string |
63
|
|
|
*/ |
64
|
7 |
|
protected function normalizeHostmask($host) |
65
|
|
|
{ |
66
|
7 |
|
if (preg_match('#[\\x80-\xff]#', $host) && function_exists('idn_to_ascii')) |
67
|
|
|
{ |
68
|
1 |
|
$variant = (defined('INTL_IDNA_VARIANT_UTS46')) ? INTL_IDNA_VARIANT_UTS46 : 0; |
69
|
1 |
|
$host = idn_to_ascii($host, 0, $variant); |
70
|
|
|
} |
71
|
|
|
|
72
|
7 |
|
if (substr($host, 0, 1) === '*') |
73
|
|
|
{ |
74
|
|
|
// *.example.com => /\.example\.com$/ |
75
|
1 |
|
$host = ltrim($host, '*'); |
76
|
|
|
} |
77
|
|
|
else |
78
|
|
|
{ |
79
|
|
|
// example.com => /^example\.com$/ |
80
|
6 |
|
$host = '^' . $host; |
81
|
|
|
} |
82
|
|
|
|
83
|
7 |
|
if (substr($host, -1) === '*') |
84
|
|
|
{ |
85
|
|
|
// example.* => /^example\./ |
86
|
1 |
|
$host = rtrim($host, '*'); |
87
|
|
|
} |
88
|
|
|
else |
89
|
|
|
{ |
90
|
|
|
// example.com => /^example\.com$/ |
91
|
6 |
|
$host .= '$'; |
92
|
|
|
} |
93
|
|
|
|
94
|
7 |
|
return $host; |
95
|
|
|
} |
96
|
|
|
} |