namespace Ice\Mvc\Route\Dispatcher;
use Ice\Mvc\Route\Dispatcher\DispatcherInterface;
use Ice\Mvc\FastRouter;
abstract class Regex implements DispatcherInterface
{
protected staticRouteMap { set };
protected variableRouteData { set };
public function setData(array! data = [])
{
let this->staticRouteMap = data[0],
this->variableRouteData = data[1];
}
protected abstract function dispatchVariableRoute(routeData, uri);
public function dispatch(string httpMethod, string uri)
{
var handler, varRouteData, result, allowedMethods, uriMap, method, routeData;
if isset this->staticRouteMap[httpMethod] && isset this->staticRouteMap[httpMethod][uri] {
let handler = this->staticRouteMap[httpMethod][uri];
return [FastRouter::FOUND, handler, []];
}
let varRouteData = this->variableRouteData;
if isset varRouteData[httpMethod] {
let result = this->dispatchVariableRoute(varRouteData[httpMethod], uri);
if result[0] === FastRouter::FOUND {
return result;
}
}
// For HEAD requests, attempt fallback to GET
if httpMethod === "HEAD" {
if isset this->staticRouteMap["GET"][uri] {
let handler = this->staticRouteMap["GET"][uri];
return [FastRouter::FOUND, handler, []];
}
if isset varRouteData["GET"] {
let result = this->dispatchVariableRoute(varRouteData["GET"], uri);
if result[0] === FastRouter::FOUND {
return result;
}
}
}
// If nothing else matches, try fallback routes
if isset this->staticRouteMap["*"][uri] {
let handler = this->staticRouteMap["*"][uri];
return [FastRouter::FOUND, handler, []];
}
if isset varRouteData["*"] {
let result = this->dispatchVariableRoute(varRouteData["*"], uri);
if result[0] === FastRouter::FOUND {
return result;
}
}
// Find allowed methods for this URI by matching against all other HTTP methods as well
let allowedMethods = [];
for method, uriMap in this->staticRouteMap {
if method !== httpMethod && isset uriMap[uri] {
let allowedMethods[] = method;
}
}
for method, routeData in varRouteData {
if method === httpMethod {
continue;
}
let result = this->dispatchVariableRoute(routeData, uri);
if result[0] === FastRouter::FOUND {
let allowedMethods[] = method;
}
}
// If there are no allowed methods the route simply does not exist
if allowedMethods {
return [FastRouter::METHOD_NOT_ALLOWED, allowedMethods];
} else {
return [FastRouter::NOT_FOUND];
}
}
}