/** * parse page routes * called seperately for differing script attributes * * @param SimpleXMLElement $pages * @throws ConfigException */ private function parsePagesSettings(\SimpleXMLElement $pages) { $scriptName = empty($pages->attributes()->script) ? $this->site->root_document : (string) $pages->attributes()->script; $redirect = empty($pages->attributes()->default_redirect) ? NULL : (string) $pages->attributes()->default_redirect; foreach ($pages->page as $page) { $parameters = ['redirect' => $redirect]; $a = $page->attributes(); // get route id $pageId = (string) $a->id; if ($pageId === '') { throw new ConfigException('Route with missing or invalid id found.'); } // read optional controller if (isset($a->controller)) { // clean path delimiters, prepend leading backslash, replace slashes with backslashes, apply ucfirst to all namespaces $namespaces = explode('\\', ltrim(str_replace('/', '\\', (string) $a->controller), '/\\')); if (count($namespaces) && $namespaces[0]) { $parameters['controller'] = '\\Controller\\' . implode('\\', array_map('ucfirst', $namespaces)) . 'Controller'; } else { throw new ConfigException(sprintf("Controller string '%s' cannot be parsed.", (string) $a->controller)); } } // read optional controller method if (isset($a->method)) { $parameters['method'] = (string) $a->method; } // read optional controller method if (isset($a->request_methods)) { $allowedMethods = 'GET POST PUT DELETE'; $requestMethods = preg_split('~\\s*,\\s*~', strtoupper((string) $a->request_methods)); foreach ($requestMethods as $requestMethod) { if (strpos($allowedMethods, $requestMethod) === -1) { throw new ConfigException(sprintf("Invalid request method '%s' for route '%s'.", $requestMethod, $pageId)); } } $parameters['requestMethods'] = $requestMethods; } // when no path is defined page id will be used for route lookup if (isset($a->path)) { // initialize lookup expression $rex = (string) $a->path; // extract route parameters and default values if (preg_match_all('~\\{(.*?)(=.*?)?\\}~', (string) $a->path, $matches)) { $placeholders = []; if (!empty($matches[1])) { foreach ($matches[1] as $ndx => $name) { $name = strtolower($name); if (!empty($matches[2][$ndx])) { $placeholders[$name] = ['name' => $name, 'default' => substr($matches[2][$ndx], 1)]; // turn this path parameter into regexp and make it optional $rex = preg_replace('~\\/{.*?\\}~', '(?:/([^/]+))?', $rex, 1); } else { $placeholders[$name] = ['name' => $name]; // turn this path parameter into regexp $rex = preg_replace('~\\{.*?\\}~', '([^/]+)', $rex, 1); } } } $parameters['placeholders'] = $placeholders; } $parameters['path'] = (string) $a->path; } else { $rex = $pageId; } $parameters['match'] = $rex; if (isset($a->auth)) { $auth = strtoupper(trim((string) $a->auth)); if (defined("vxPHP\\User\\User::AUTH_{$auth}")) { $auth = constant("vxPHP\\User\\User::AUTH_{$auth}"); if (isset($a->auth_parameters)) { $parameters['authParameters'] = trim((string) $a->auth_parameters); } } else { $auth = -1; } $parameters['auth'] = $auth; } if (isset($this->routes[$scriptName][$pageId])) { throw new ConfigException(sprintf("Route '%s' for script '%s' found more than once.", $pageId, $scriptName)); } $route = new Route($pageId, $scriptName, $parameters); $this->routes[$scriptName][$route->getRouteId()] = $route; } }