/** * Finds URL for specified action. * * Returns an URL pointing to a combination of controller and action. * * ### Usage * * - `Router::url('/posts/edit/1');` Returns the string with the base dir prepended. * This usage does not use reverser routing. * - `Router::url(['controller' => 'posts', 'action' => 'edit']);` Returns a URL * generated through reverse routing. * - `Router::url(['_name' => 'custom-name', ...]);` Returns a URL generated * through reverse routing. This form allows you to leverage named routes. * * There are a few 'special' parameters that can change the final URL string that is generated * * - `_base` - Set to false to remove the base path from the generated URL. If your application * is not in the root directory, this can be used to generate URLs that are 'cake relative'. * cake relative URLs are required when using requestAction. * - `_scheme` - Set to create links on different schemes like `webcal` or `ftp`. Defaults * to the current scheme. * - `_host` - Set the host to use for the link. Defaults to the current host. * - `_port` - Set the port if you need to create links on non-standard ports. * - `_full` - If true output of `Router::fullBaseUrl()` will be prepended to generated URLs. * - `#` - Allows you to set URL hash fragments. * - `_ssl` - Set to true to convert the generated URL to https, or false to force http. * - `_name` - Name of route. If you have setup named routes you can use this key * to specify it. * * @param string|array $url An array specifying any of the following: * 'controller', 'action', 'plugin' additionally, you can provide routed * elements or query string parameters. If string it can be name any valid url * string. * @param bool $full If true, the full base URL will be prepended to the result. * Default is false. * @return string Full translated URL with base path. * @throws \Cake\Core\Exception\Exception When the route name is not found */ public static function url($url = null, $full = false) { if (!static::$initialized) { static::_loadRoutes(); } $params = ['plugin' => null, 'controller' => null, 'action' => 'index', '_ext' => null]; $here = $base = $output = $frag = null; $request = static::getRequest(true); if ($request) { $params = $request->params; $here = $request->here; $base = $request->base; } if (!isset($base)) { $base = Configure::read('App.base'); } if (empty($url)) { $output = isset($here) ? $here : $base . '/'; if ($full) { $output = static::fullBaseUrl() . $output; } return $output; } elseif (is_array($url)) { if (isset($url['_full']) && $url['_full'] === true) { $full = true; unset($url['_full']); } // Compatibility for older versions. if (isset($url['?'])) { $q = $url['?']; unset($url['?']); $url = array_merge($url, $q); } if (isset($url['#'])) { $frag = '#' . $url['#']; unset($url['#']); } if (isset($url['_ssl'])) { $url['_scheme'] = $url['_ssl'] === true ? 'https' : 'http'; unset($url['_ssl']); } $url = static::_applyUrlFilters($url); if (!isset($url['_name'])) { // Copy the current action if the controller is the current one. if (empty($url['action']) && (empty($url['controller']) || $params['controller'] === $url['controller'])) { $url['action'] = $params['action']; } // Keep the current prefix around if none set. if (isset($params['prefix']) && !isset($url['prefix'])) { $url['prefix'] = $params['prefix']; } $url += ['plugin' => $params['plugin'], 'controller' => $params['controller'], 'action' => 'index', '_ext' => null]; } $output = static::$_collection->match($url, static::$_requestContext + ['params' => $params]); } else { $plainString = strpos($url, 'javascript:') === 0 || strpos($url, 'mailto:') === 0 || strpos($url, 'tel:') === 0 || strpos($url, 'sms:') === 0 || strpos($url, '#') === 0 || strpos($url, '?') === 0 || strpos($url, '//') === 0 || strpos($url, '://') !== false; if ($plainString) { return $url; } $output = $base . $url; } $protocol = preg_match('#^[a-z][a-z0-9+\\-.]*\\://#i', $output); if ($protocol === 0) { $output = str_replace('//', '/', '/' . $output); if ($full) { $output = static::fullBaseUrl() . $output; } } return $output . $frag; }
/** * Finds URL for specified action. * * Returns an URL pointing to a combination of controller and action. * * ### Usage * * - `Router::url('/posts/edit/1');` Returns the string with the base dir prepended. * This usage does not use reverser routing. * - `Router::url(array('controller' => 'posts', 'action' => 'edit'));` Returns a URL * generated through reverse routing. * - `Router::url('custom-name', array(...));` Returns a URL generated through reverse * routing. This form allows you to leverage named routes. * * There are a few 'special' parameters that can change the final URL string that is generated * * - `_base` - Set to false to remove the base path from the generated URL. If your application * is not in the root directory, this can be used to generate URLs that are 'cake relative'. * cake relative URLs are required when using requestAction. * - `_scheme` - Set to create links on different schemes like `webcal` or `ftp`. Defaults * to the current scheme. * - `_host` - Set the host to use for the link. Defaults to the current host. * - `_port` - Set the port if you need to create links on non-standard ports. * - `_full` - If true output of `Router::fullBaseUrl()` will be prepended to generated URLs. * - `#` - Allows you to set URL hash fragments. * - `ssl` - Set to true to convert the generated URL to https, or false to force http. * * @param string|array $url Cake-relative URL, like "/products/edit/92" or "/presidents/elect/4" * or an array specifying any of the following: 'controller', 'action', 'plugin' * additionally, you can provide routed elements or query string parameters. * @param bool|array $options If (bool) true, the full base URL will be prepended to the result. * If an array accepts the following keys. If used with a named route you can provide * a list of query string parameters. * @return string Full translated URL with base path. * @throws \Cake\Error\Exception When the route name is not found */ public static function url($url = null, $options = []) { if (!static::$initialized) { static::_loadRoutes(); } $full = false; if (is_bool($options)) { list($full, $options) = array($options, []); } $urlType = gettype($url); $hasLeadingSlash = $plainString = false; if ($urlType === 'string') { $plainString = strpos($url, 'javascript:') === 0 || strpos($url, 'mailto:') === 0 || strpos($url, 'tel:') === 0 || strpos($url, 'sms:') === 0 || strpos($url, '#') === 0 || strpos($url, '?') === 0 || strpos($url, '//') === 0 || strpos($url, '://') !== false; $hasLeadingSlash = isset($url[0]) ? $url[0] === '/' : false; } $params = array('plugin' => null, 'controller' => null, 'action' => 'index', '_ext' => null); $here = $base = $output = $frag = null; $request = static::getRequest(true); if ($request) { $params = $request->params; $here = $request->here; $base = $request->base; } if (!isset($base)) { $base = Configure::read('App.base'); } if (empty($url)) { $output = isset($here) ? $here : '/'; if ($full) { $output = static::fullBaseUrl() . $base . $output; } return $output; } elseif ($urlType === 'array') { if (isset($url['_full']) && $url['_full'] === true) { $full = true; unset($url['_full']); } // Compatibility for older versions. if (isset($url['?'])) { $q = $url['?']; unset($url['?']); $url = array_merge($url, $q); } if (isset($url['#'])) { $frag = '#' . $url['#']; unset($url['#']); } if (isset($url['ext'])) { $url['_ext'] = $url['ext']; unset($url['ext']); } if (isset($url['ssl'])) { $url['_scheme'] = $url['ssl'] == true ? 'https' : 'http'; unset($url['ssl']); } // Copy the current action if the controller is the current one. if (empty($url['action']) && (empty($url['controller']) || $params['controller'] === $url['controller'])) { $url['action'] = $params['action']; } // Keep the current prefix around if none set. if (isset($params['prefix']) && !isset($url['prefix'])) { $url['prefix'] = $params['prefix']; } $url += array('plugin' => $params['plugin'], 'controller' => $params['controller'], 'action' => 'index', '_ext' => $params['_ext']); $url = static::_applyUrlFilters($url); $output = static::$_routes->match($url); } elseif ($urlType === 'string' && !$hasLeadingSlash && !$plainString) { // named route. $route = static::$_routes->get($url); if (!$route) { throw new Error\Exception(sprintf('No route matching the name "%s" was found.', $url)); } $url = $options + $route->defaults + array('_name' => $url); $url = static::_applyUrlFilters($url); $output = static::$_routes->match($url); } else { // String urls. if ($plainString) { return $url; } $output = $base . $url; } $protocol = preg_match('#^[a-z][a-z0-9+\\-.]*\\://#i', $output); if ($protocol === 0) { $output = str_replace('//', '/', '/' . $output); if ($full) { $output = static::fullBaseUrl() . $output; } } return $output . $frag; }