1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
|
<?php
/**
*
* This file is part of Aura for PHP.
*
* @license http://opensource.org/licenses/bsd-license.php BSD
*
*/
namespace Aura\Router\Rule;
use Aura\Router\Route;
use Psr\Http\Message\ServerRequestInterface;
/**
*
* A rule for the HTTP host.
*
* @package Aura.Router
*
*/
class Host implements RuleInterface
{
/**
*
* Use this Route to build the regex.
*
* @var Route
*
*/
protected $route;
/**
*
* The regular expression for the host.
*
* @var string
*
*/
protected $regex;
/**
*
* Checks that the Request host matches the Route host.
*
* @param ServerRequestInterface $request The HTTP request.
*
* @param Route $route The route.
*
* @return bool True on success, false on failure.
*
*/
public function __invoke(ServerRequestInterface $request, Route $route)
{
if (! $route->host) {
return true;
}
$match = preg_match(
$this->buildRegex($route),
$request->getUri()->getHost(),
$matches
);
if (! $match) {
return false;
}
$route->attributes($this->getAttributes($matches));
return true;
}
/**
*
* Gets the attributes out of the regex matches.
*
* @param array $matches The regex matches.
*
* @return array
*
*/
protected function getAttributes($matches)
{
$attributes = [];
foreach ($matches as $key => $val) {
if (is_string($key)) {
$attributes[$key] = $val;
}
}
return $attributes;
}
/**
*
* Builds the regular expression for the route host.
*
* @param Route $route The Route.
*
* @return string
*
*/
protected function buildRegex(Route $route)
{
$this->route = $route;
$this->regex = str_replace('.', '\\.', $this->route->host);
$this->setRegexAttributes();
$this->regex = '#^' . $this->regex . '$#';
return $this->regex;
}
/**
*
* Expands attribute names in the regex to named subpatterns; adds default
* `null` values for attributes without defaults.
*
* @return null
*
*/
protected function setRegexAttributes()
{
$find = '#{([a-z][a-zA-Z0-9_]*)}#';
$attributes = $this->route->attributes;
$newAttributes = [];
preg_match_all($find, $this->regex, $matches, PREG_SET_ORDER);
foreach ($matches as $match) {
$name = $match[1];
$subpattern = $this->getSubpattern($name);
$this->regex = str_replace("{{$name}}", $subpattern, $this->regex);
if (! isset($attributes[$name])) {
$newAttributes[$name] = null;
}
}
$this->route->attributes($newAttributes);
}
/**
*
* Returns a named subpattern for a attribute name.
*
* @param string $name The attribute name.
*
* @return string The named subpattern.
*
*/
protected function getSubpattern($name)
{
// is there a custom subpattern for the name?
if (isset($this->route->tokens[$name])) {
return "(?P<{$name}>{$this->route->tokens[$name]})";
}
// use a default subpattern, stop at first dot
return "(?P<{$name}>[^\.]+)";
}
}
|