/**
* 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;
}