/** * Validate a route. * * @param string|array|Route|HasRoute $route A route array, string, or * object. * @return Route\Route Validated route. * @throws Route\RouteError If the route is invalid. * @throws \Jivoo\InvalidArgumentException If `$route` is not a recognized * type. */ public function validate($route) { if ($route instanceof Route\Route) { return $route; } if ($route instanceof Route\HasRoute) { return $this->validate($route->getRoute()); } if (is_callable($route)) { return new Route\CallableRoute($route); } if (is_string($route)) { if ($route == '') { $route = $this->findMatch([], 'GET'); if (!isset($route)) { throw new Route\RouteException('No root route'); } return $route; } else { if (preg_match('/^([a-zA-Z0-9\\.\\-+]+):/', $route, $matches) === 1) { $prefix = $matches[1]; if (isset($this->schemePrefixes[$prefix])) { $scheme = $this->schemePrefixes[$prefix]; return $scheme->fromString($route); } throw new Route\RouteException('Unknown route scheme: ' . $prefix); } // TODO: use current scheme .. e.g. 'action:' if in a controller throw new Route\RouteException('Missing route scheme'); } } \Jivoo\Assume::isArray($route); $default = ['parameters' => [], 'query' => [], 'fragment' => '', 'mergeQuery' => false]; $scheme = null; $parameters = []; foreach ($route as $key => $value) { if (is_int($key)) { $parameters[] = $value; } elseif ($key == 'parameters') { $parameters = array_merge($parameters, $value); } elseif (in_array($key, ['query', 'fragment', 'mergeQuery'])) { $default[$key] = $value; } elseif (isset($this->schemeKeys[$key])) { $default[$key] = $value; if (!isset($scheme)) { $scheme = $this->schemeKeys[$key]; } } else { throw new Route\RouteException('Undefined key in route: ' . $key); } } $route = $default; if (count($parameters)) { $route['parameters'] = $parameters; } if ($route['mergeQuery']) { $query = []; if (isset($this->request)) { $query = $this->request->getQueryParams(); } if (isset($route['query'])) { $query = merge_array($query, $route['query']); } $route['query'] = $query; } unset($route['mergeQuery']); if (isset($scheme)) { return $scheme->fromArray($route); } if (!isset($this->route)) { throw new Route\RouteException('Unknown route scheme'); } $copy = $this->route; if (isset($route['parameters'])) { $copy = $copy->withParameters($route['parameters']); } if (isset($route['query'])) { $copy = $copy->withQuery($route['query']); } if (isset($route['fragment'])) { $copy = $copy->withFragment($route['fragment']); } return $copy; }