/** * Takes some input and returns the corresponding URL * @method url * @static * @param {string|boolean|array|Q_Uri} $source This can be a Q_Uri, an array or string representing a uri, * an absolute url, or "true". If you pass "true", then the Q_Request::baseUrl(true) is used as input. * @param {string|null} [$routePattern=null] If you know which route pattern to use, then specify it here. Otherwise, leave it null. * @param {boolean} [$noProxy=false] If set to true, Q_Uri::proxySource($url) is not called before returning the result. * @param {string} [$controller=true] The controller to pass to `Q_Request::baseUrl($controller)` when forming the URL. * @return {string} */ static function url($source, $routePattern = null, $noProxy = false, $controller = true) { if (empty($source)) { return $source; } if ($source === true) { $source = Q_Request::baseUrl($controller); } if ($source instanceof Q_Uri and $source->Q_url) { return $source->Q_url; } static $cache = array(); $cache_key = $noProxy ? $source . ' noproxy=1' : $source; if (is_string($source) and isset($cache[$cache_key])) { return $cache[$cache_key]; } if (is_string($source) and isset($source[0]) and $source[0] == '#') { // $source is a fragment reference return $source; } if (Q_Valid::url($source)) { // $source is already a URL $result = self::proxySource($source); if (is_string($source)) { $cache[$source] = $result; } return $result; } /** * @event Q/url {before} * @param {string|boolean|array|Q_Uri} source This can be a Q_Uri, an array or string representing a uri, * an absolute url, or "true". If you pass "true", then the Q_Request::baseUrl(true) is used as input. * @param {string|null} routePattern If you know which route pattern to use, then specify it here. Otherwise, leave it null. * @param {boolean} noProxy If set to true, Q_Uri::proxySource($url) is not called before returning the result. * @return {string} */ $url = Q::event('Q/url', compact('source', 'routePattern', 'noProxy'), 'before'); if (!isset($url)) { $uri = self::from($source); if (!$uri) { $url = null; } else { if ($controller === true) { // If developer set a custom controller, calculate it. $cs = Q_Config::get('Q', 'web', 'controllerSuffix', null); if (isset($cs)) { $controller = $cs; } } $url = $uri->toUrl($routePattern, $controller); } } if (!isset($url)) { $hash = Q_Uri::unreachableUri(); if ($hash) { $result = $hash; if (is_string($source)) { $cache[$source] = $result; } return $result; } } if ($noProxy) { $result = $url; if (is_string($source)) { $cache[$source] = $result; } return $result; } $result = self::proxySource($url); if (is_string($source)) { $cache[$source] = $result; } return $result; }
/** * Sets a header to redirect to a given URI or URL. * @method redirect * @static * @param {string} $uri The URL or internal URI to redirect to * @param {array} $options An array of options that can include: * "loop" => Defaults to false. If true, sets the redirect header even if the current URL is the same. * "noProxy" => Defaults to false. If true, doesn't use the proxy mapping to determine URL * "permanently" => If true, sets response code as 304 instead of 302 * @param {boolean} [$noProxy=false] * @return {boolean} * Return whether the redirect header was set. */ static function redirect($uri, $options = array()) { extract($options); $url = Q_Uri::url($uri, null, !empty($noProxy)); if ($url === Q_Uri::unreachableUri()) { throw new Q_Exception_BadValue(array('internal' => 'uri', 'problem' => 'no url routes to it')); } $level = ob_get_level(); for ($i = 0; $i < $level; ++$i) { ob_clean(); } /** * @event Q/response {before} * @param {string} permanently * @param {string} uri * @param {string} url * @param {string} loop * @return {boolean} */ $result = Q::event('Q/redirect', compact('uri', 'url', 'loop', 'permanently', 'noProxy', 'level'), 'before'); if (isset($result)) { return $result; } if (!empty($loop) and Q_Request::url() === $url) { return false; } if (!Q_Request::isAjax()) { if (!empty($permanently)) { header("HTTP/1.1 301 Moved Permanently"); } header("Location: {$url}"); } self::$redirected = $uri; return true; }