public function match(Nette\Http\IRequest $httpRequest)
{
// combine with precedence: mask (params in URL-path), fixity, query, (post,) defaults
// 1) URL MASK
$url = $httpRequest->getUrl();
$re = $this->re;
if ($this->type === self::HOST) {
$host = $url->getHost();
$path = '//' . $host . $url->getPath();
$parts = ip2long($host) ? [$host] : array_reverse(explode('.', $host));
$re = strtr($re, ['/%basePath%/' => preg_quote($url->getBasePath(), '#'), '%tld%' => preg_quote($parts[0], '#'), '%domain%' => preg_quote(isset($parts[1]) ? "{$parts['1']}.{$parts['0']}" : $parts[0], '#'), '%sld%' => preg_quote(isset($parts[1]) ? $parts[1] : '', '#'), '%host%' => preg_quote($host, '#')]);
} elseif ($this->type === self::RELATIVE) {
$basePath = $url->getBasePath();
if (strncmp($url->getPath(), $basePath, strlen($basePath)) !== 0) {
return NULL;
}
$path = (string) substr($url->getPath(), strlen($basePath));
} else {
$path = $url->getPath();
}
if ($path !== '') {
$path = rtrim(rawurldecode($path), '/') . '/';
}
if (!($matches = Strings::match($path, $re))) {
// stop, not matched
return NULL;
}
// assigns matched values to parameters
$params = [];
foreach ($matches as $k => $v) {
if (is_string($k) && $v !== '') {
$params[$this->aliases[$k]] = $v;
}
}
// 2) CONSTANT FIXITY
foreach ($this->metadata as $name => $meta) {
if (!isset($params[$name]) && isset($meta['fixity']) && $meta['fixity'] !== self::OPTIONAL) {
$params[$name] = NULL;
// cannot be overwriten in 3) and detected by isset() in 4)
}
}
// 3) QUERY
if ($this->xlat) {
$params += self::renameKeys($httpRequest->getQuery(), array_flip($this->xlat));
} else {
$params += $httpRequest->getQuery();
}
// 4) APPLY FILTERS & FIXITY
foreach ($this->metadata as $name => $meta) {
if (isset($params[$name])) {
if (!is_scalar($params[$name])) {
} elseif (isset($meta[self::FILTER_TABLE][$params[$name]])) {
// applies filterTable only to scalar parameters
$params[$name] = $meta[self::FILTER_TABLE][$params[$name]];
} elseif (isset($meta[self::FILTER_TABLE]) && !empty($meta[self::FILTER_STRICT])) {
return NULL;
// rejected by filterTable
} elseif (isset($meta[self::FILTER_IN])) {
// applies filterIn only to scalar parameters
$params[$name] = call_user_func($meta[self::FILTER_IN], (string) $params[$name]);
if ($params[$name] === NULL && !isset($meta['fixity'])) {
return NULL;
// rejected by filter
}
}
} elseif (isset($meta['fixity'])) {
$params[$name] = $meta[self::VALUE];
}
}
if (isset($this->metadata[NULL][self::FILTER_IN])) {
$params = call_user_func($this->metadata[NULL][self::FILTER_IN], $params);
if ($params === NULL) {
return NULL;
}
}
// 5) BUILD Request
if (!isset($params[self::PRESENTER_KEY])) {
throw new Nette\InvalidStateException('Missing presenter in route definition.');
} elseif (!is_string($params[self::PRESENTER_KEY])) {
return NULL;
}
$presenter = $params[self::PRESENTER_KEY];
unset($params[self::PRESENTER_KEY]);
if (isset($this->metadata[self::MODULE_KEY])) {
$presenter = (isset($params[self::MODULE_KEY]) ? $params[self::MODULE_KEY] . ':' : '') . $presenter;
unset($params[self::MODULE_KEY]);
}
return new Application\Request($presenter, $httpRequest->getMethod(), $params, $httpRequest->getPost(), $httpRequest->getFiles(), [Application\Request::SECURED => $httpRequest->isSecured()]);
}