/** * prepares and executes a Route::redirect * * @param string destination page id * @param string $document * @param array query * @param int $statusCode * */ protected function redirect($url = NULL, $queryParams = [], $statusCode = 302) { if (is_null($url)) { return $this->route->redirect($queryParams, $statusCode); } if ($queryParams) { $query = (strpos($url, '?') === FALSE ? '?' : '&') . http_build_query($queryParams); } else { $query = ''; } return new RedirectResponse($url . $query, $statusCode); }
/** * 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; } }
/** * render menu markup * * @return string */ public function render() { // check authentication if (!$this->authenticateMenu($this->menu)) { return ''; } // if menu has not been prepared yet, do it now (caching avoids re-parsing for submenus) if (!in_array($this->menu, self::$primedMenus, TRUE)) { // clear selected menu entries (which remain in the session) $this->clearSelectedMenuEntries($this->menu); // walk entire menu and add dynamic entries where necessary $this->completeMenu($this->menu); // prepare path segments to identify active menu entries $this->pathSegments = explode('/', trim($this->request->getPathInfo(), '/')); // skip script name if ($this->useNiceUris && basename($this->request->getScriptName()) != 'index.php') { array_shift($this->pathSegments); } // skip locale if one found if (count($this->pathSegments) && Application::getInstance()->hasLocale($this->pathSegments[0])) { array_shift($this->pathSegments); } // walk tree until an active entry is reached $this->walkMenuTree($this->menu, $this->pathSegments[0] === '' ? explode('/', $this->route->getPath()) : $this->pathSegments); // cache menu for multiple renderings self::$primedMenus[] = $this->menu; } $htmlId = $this->id . 'menu'; // drill down to required submenu (if only submenu needs to be rendered) $m = $this->menu; if ($this->level !== FALSE) { $htmlId .= '_level_' . $this->level; if ($this->level > 0) { while ($this->level-- > 0) { $e = $this->menu->getSelectedEntry(); if (!$e || !$e->getSubMenu()) { break; } $m = $e->getSubMenu(); } if ($this->level >= 0) { return ''; } } } // output // instantiate renderer class, defaults to SimpleListRenderer if (!empty($this->decorator)) { $rendererName = $this->decorator; } else { $rendererName = 'SimpleList'; } $className = __NAMESPACE__ . '\\Menu\\Renderer\\' . $rendererName . 'Renderer'; $renderer = new $className($m); $renderer->setParameters($this->renderArgs); // enable or disable display of submenus $m->setShowSubmenus($this->level === FALSE); // enable or disable always active menu $m->setForceActive(self::$forceActiveMenu); // if no container tag was specified, use a DIV element if (!isset($this->renderArgs['containerTag'])) { $this->renderArgs['containerTag'] = 'div'; } // omit wrapper, if a falsy container tag was specified if ($this->renderArgs['containerTag']) { return sprintf('<%1$s%2$s>%3$s</%1$s>', $this->renderArgs['containerTag'], isset($this->renderArgs['omitId']) && $this->renderArgs['omitId'] ? '' : ' id="' . $htmlId . '"', $renderer->render()); } return $renderer->render(); }
/** * check path against placeholders of route * and return associative array with placeholders which would have a value assigned * * @param Route $route * @param string $path * @return array */ private static function getSatisfiedPlaceholders($route, $path) { $placeholderNames = $route->getPlaceholderNames(); if (!empty($placeholderNames)) { if (preg_match('~(?:/|^)' . $route->getMatchExpression() . '(?:/|$)~', $path, $matches)) { array_shift($matches); return array_combine(array_slice($placeholderNames, 0, count($matches)), $matches); } } return []; }