Commit 91c32e3d authored by alexpott's avatar alexpott

Issue #2010024 by damiankloip, dawehner, ParisLiakos: Move url related...

Issue #2010024 by damiankloip, dawehner, ParisLiakos: Move url related functions to a new Url component.
parent a5c93987
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
use Drupal\Component\Utility\String; use Drupal\Component\Utility\String;
use Drupal\Component\Utility\Timer; use Drupal\Component\Utility\Timer;
use Drupal\Component\Utility\Unicode; use Drupal\Component\Utility\Unicode;
use Drupal\Component\Utility\UrlValidator; use Drupal\Component\Utility\Url;
use Drupal\Core\DrupalKernel; use Drupal\Core\DrupalKernel;
use Drupal\Core\Database\Database; use Drupal\Core\Database\Database;
use Drupal\Core\DependencyInjection\ContainerBuilder; use Drupal\Core\DependencyInjection\ContainerBuilder;
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
use Drupal\Component\Utility\Json; use Drupal\Component\Utility\Json;
use Drupal\Component\Utility\String; use Drupal\Component\Utility\String;
use Drupal\Component\Utility\Tags; use Drupal\Component\Utility\Tags;
use Drupal\Component\Utility\UrlValidator; use Drupal\Component\Utility\Url;
use Drupal\Component\Utility\Xss; use Drupal\Component\Utility\Xss;
use Drupal\Core\Cache\Cache; use Drupal\Core\Cache\Cache;
use Drupal\Core\Language\Language; use Drupal\Core\Language\Language;
...@@ -440,56 +440,14 @@ function drupal_get_feeds($delimiter = "\n") { ...@@ -440,56 +440,14 @@ function drupal_get_feeds($delimiter = "\n") {
* *
* @return * @return
* An array containing query parameters, which can be used for url(). * An array containing query parameters, which can be used for url().
*
* @deprecated as of Drupal 8.0. Use Url::filterQueryParameters() instead.
*/ */
function drupal_get_query_parameters(array $query = NULL, array $exclude = array(), $parent = '') { function drupal_get_query_parameters(array $query = NULL, array $exclude = array(), $parent = '') {
// Set defaults, if none given.
if (!isset($query)) { if (!isset($query)) {
$query = $_GET; $query = Drupal::request()->query->all();
}
// If $exclude is empty, there is nothing to filter.
if (empty($exclude)) {
return $query;
}
elseif (!$parent) {
$exclude = array_flip($exclude);
}
$params = array();
foreach ($query as $key => $value) {
$string_key = ($parent ? $parent . '[' . $key . ']' : $key);
if (isset($exclude[$string_key])) {
continue;
}
if (is_array($value)) {
$params[$key] = drupal_get_query_parameters($value, $exclude, $string_key);
}
else {
$params[$key] = $value;
}
}
return $params;
}
/**
* Splits a URL-encoded query string into an array.
*
* @param $query
* The query string to split.
*
* @return
* An array of URL decoded couples $param_name => $value.
*/
function drupal_get_query_array($query) {
$result = array();
if (!empty($query)) {
foreach (explode('&', $query) as $param) {
$param = explode('=', $param);
$result[$param[0]] = isset($param[1]) ? rawurldecode($param[1]) : '';
}
} }
return $result; return Url::filterQueryParameters($query, $exclude, $parent);
} }
/** /**
...@@ -497,12 +455,13 @@ function drupal_get_query_array($query) { ...@@ -497,12 +455,13 @@ function drupal_get_query_array($query) {
* *
* @see \Drupal\Core\Routing\PathBasedGeneratorInterface::httpBuildQuery() * @see \Drupal\Core\Routing\PathBasedGeneratorInterface::httpBuildQuery()
* @see drupal_get_query_parameters() * @see drupal_get_query_parameters()
* @deprecated as of Drupal 8.0. Use * @deprecated as of Drupal 8.0. Use Url::buildQuery() instead.
* Drupal::urlGenerator()->httpBuildQuery() instead.
* @ingroup php_wrappers * @ingroup php_wrappers
*
* @deprecated as of Drupal 8.0. Use Url::buildQuery() instead.
*/ */
function drupal_http_build_query(array $query, $parent = '') { function drupal_http_build_query(array $query, $parent = '') {
return Drupal::urlGenerator()->httpBuildQuery($query, $parent); return Url::buildQuery($query, $parent);
} }
/** /**
...@@ -527,12 +486,13 @@ function drupal_get_destination() { ...@@ -527,12 +486,13 @@ function drupal_get_destination() {
return $destination; return $destination;
} }
if (isset($_GET['destination'])) { $query = Drupal::request()->query;
$destination = array('destination' => $_GET['destination']); if ($query->has('destination')) {
$destination = array('destination' => $query->get('destination'));
} }
else { else {
$path = current_path(); $path = current_path();
$query = Drupal::urlGenerator()->httpBuildQuery(drupal_get_query_parameters()); $query = Url::buildQuery(Url::filterQueryParameters($query->all()));
if ($query != '') { if ($query != '') {
$path .= '?' . $query; $path .= '?' . $query;
} }
...@@ -573,46 +533,11 @@ function drupal_get_destination() { ...@@ -573,46 +533,11 @@ function drupal_get_destination() {
* *
* @see url() * @see url()
* @ingroup php_wrappers * @ingroup php_wrappers
*
* @deprecated as of Drupal 8.0. Use Url::parse() instead.
*/ */
function drupal_parse_url($url) { function drupal_parse_url($url) {
$options = array( return Url::parse($url);
'path' => NULL,
'query' => array(),
'fragment' => '',
);
// External URLs: not using parse_url() here, so we do not have to rebuild
// the scheme, host, and path without having any use for it.
if (strpos($url, '://') !== FALSE) {
// Split off everything before the query string into 'path'.
$parts = explode('?', $url);
$options['path'] = $parts[0];
// If there is a query string, transform it into keyed query parameters.
if (isset($parts[1])) {
$query_parts = explode('#', $parts[1]);
parse_str($query_parts[0], $options['query']);
// Take over the fragment, if there is any.
if (isset($query_parts[1])) {
$options['fragment'] = $query_parts[1];
}
}
}
// Internal URLs.
else {
// parse_url() does not support relative URLs, so make it absolute. E.g. the
// relative URL "foo/bar:1" isn't properly parsed.
$parts = parse_url('http://example.com/' . $url);
// Strip the leading slash that was just added.
$options['path'] = substr($parts['path'], 1);
if (isset($parts['query'])) {
parse_str($parts['query'], $options['query']);
}
if (isset($parts['fragment'])) {
$options['fragment'] = $parts['fragment'];
}
}
return $options;
} }
/** /**
...@@ -625,9 +550,11 @@ function drupal_parse_url($url) { ...@@ -625,9 +550,11 @@ function drupal_parse_url($url) {
* *
* @param $path * @param $path
* The Drupal path to encode. * The Drupal path to encode.
*
* @deprecated as of Drupal 8.0. Use Url::encodePath() instead.
*/ */
function drupal_encode_path($path) { function drupal_encode_path($path) {
return str_replace('%2F', '/', rawurlencode($path)); return Url::encodePath($path);
} }
/** /**
...@@ -638,20 +565,11 @@ function drupal_encode_path($path) { ...@@ -638,20 +565,11 @@ function drupal_encode_path($path) {
* *
* @return * @return
* TRUE if the URL has the same domain and base path. * TRUE if the URL has the same domain and base path.
*
* @deprecated as of Drupal 8.0. Use Url::externalIsLocal() instead.
*/ */
function _external_url_is_local($url) { function _external_url_is_local($url) {
$url_parts = parse_url($url); return Url::externalIsLocal($url, base_path());
$base_host = parse_url($GLOBALS['base_url'], PHP_URL_HOST);
if (!isset($url_parts['path'])) {
return ($url_parts['host'] == $base_host);
}
else {
// When comparing base paths, we need a trailing slash to make sure a
// partial URL match isn't occuring. Since base_path() always returns with
// a trailing slash, we don't need to add the trailing slash here.
return ($url_parts['host'] == $base_host && stripos($url_parts['path'], base_path()) === 0);
}
} }
/** /**
...@@ -705,12 +623,12 @@ function valid_email_address($mail) { ...@@ -705,12 +623,12 @@ function valid_email_address($mail) {
* @return * @return
* TRUE if the URL is in a valid format. * TRUE if the URL is in a valid format.
* *
* @see \Drupal\Component\Utility\UrlValidator::isValid() * @see \Drupal\Component\Utility\Url::isValid()
* *
* @deprecated as of Drupal 8.0. Use UrlValidator::isValid() instead. * @deprecated as of Drupal 8.0. Use Url::isValid() instead.
*/ */
function valid_url($url, $absolute = FALSE) { function valid_url($url, $absolute = FALSE) {
return UrlValidator::isValid($url, $absolute); return Url::isValid($url, $absolute);
} }
/** /**
...@@ -795,7 +713,7 @@ function valid_number_step($value, $step, $offset = 0.0) { ...@@ -795,7 +713,7 @@ function valid_number_step($value, $step, $offset = 0.0) {
* @see \Drupal\Component\Utility\Url::stripDangerousProtocols() * @see \Drupal\Component\Utility\Url::stripDangerousProtocols()
*/ */
function drupal_strip_dangerous_protocols($uri) { function drupal_strip_dangerous_protocols($uri) {
return UrlValidator::stripDangerousProtocols($uri); return Url::stripDangerousProtocols($uri);
} }
/** /**
...@@ -817,7 +735,7 @@ function drupal_strip_dangerous_protocols($uri) { ...@@ -817,7 +735,7 @@ function drupal_strip_dangerous_protocols($uri) {
* @see \Drupal\Component\Utility\String::checkPlain() * @see \Drupal\Component\Utility\String::checkPlain()
*/ */
function check_url($uri) { function check_url($uri) {
return String::checkPlain(UrlValidator::stripDangerousProtocols($uri)); return String::checkPlain(Url::stripDangerousProtocols($uri));
} }
/** /**
...@@ -885,7 +803,7 @@ function filter_xss($string, $allowed_tags = array('a', 'em', 'strong', 'cite', ...@@ -885,7 +803,7 @@ function filter_xss($string, $allowed_tags = array('a', 'em', 'strong', 'cite',
* @see \Drupal\Component\Utility\Url::filterBadProtocol() * @see \Drupal\Component\Utility\Url::filterBadProtocol()
*/ */
function filter_xss_bad_protocol($string) { function filter_xss_bad_protocol($string) {
return UrlValidator::filterBadProtocol($string); return Url::filterBadProtocol($string);
} }
/** /**
...@@ -1313,11 +1231,7 @@ function url($path = NULL, array $options = array()) { ...@@ -1313,11 +1231,7 @@ function url($path = NULL, array $options = array()) {
* Boolean TRUE or FALSE, where TRUE indicates an external path. * Boolean TRUE or FALSE, where TRUE indicates an external path.
*/ */
function url_is_external($path) { function url_is_external($path) {
$colonpos = strpos($path, ':'); return Url::isExternal($path);
// Avoid calling drupal_strip_dangerous_protocols() if there is any
// slash (/), hash (#) or question_mark (?) before the colon (:)
// occurrence - if any - as this would clearly mean it is not a URL.
return $colonpos !== FALSE && !preg_match('![/?#]!', substr($path, 0, $colonpos)) && drupal_strip_dangerous_protocols($path) == $path;
} }
/** /**
...@@ -4019,7 +3933,7 @@ function _drupal_bootstrap_code() { ...@@ -4019,7 +3933,7 @@ function _drupal_bootstrap_code() {
// of allowed protocols for these cases. // of allowed protocols for these cases.
$allowed_protocols = array('http', 'https'); $allowed_protocols = array('http', 'https');
} }
UrlValidator::setAllowedProtocols($allowed_protocols); Url::setAllowedProtocols($allowed_protocols);
} }
/** /**
......
...@@ -225,7 +225,7 @@ protected static function attributes($attributes) { ...@@ -225,7 +225,7 @@ protected static function attributes($attributes) {
case 2: case 2:
// Attribute value, a URL after href= for instance. // Attribute value, a URL after href= for instance.
if (preg_match('/^"([^"]*)"(\s+|$)/', $attributes, $match)) { if (preg_match('/^"([^"]*)"(\s+|$)/', $attributes, $match)) {
$thisval = UrlValidator::filterBadProtocol($match[1]); $thisval = Url::filterBadProtocol($match[1]);
if (!$skip) { if (!$skip) {
$attributes_array[] = "$attribute_name=\"$thisval\""; $attributes_array[] = "$attribute_name=\"$thisval\"";
...@@ -237,7 +237,7 @@ protected static function attributes($attributes) { ...@@ -237,7 +237,7 @@ protected static function attributes($attributes) {
} }
if (preg_match("/^'([^']*)'(\s+|$)/", $attributes, $match)) { if (preg_match("/^'([^']*)'(\s+|$)/", $attributes, $match)) {
$thisval = UrlValidator::filterBadProtocol($match[1]); $thisval = Url::filterBadProtocol($match[1]);
if (!$skip) { if (!$skip) {
$attributes_array[] = "$attribute_name='$thisval'"; $attributes_array[] = "$attribute_name='$thisval'";
...@@ -248,7 +248,7 @@ protected static function attributes($attributes) { ...@@ -248,7 +248,7 @@ protected static function attributes($attributes) {
} }
if (preg_match("%^([^\s\"']+)(\s+|$)%", $attributes, $match)) { if (preg_match("%^([^\s\"']+)(\s+|$)%", $attributes, $match)) {
$thisval = UrlValidator::filterBadProtocol($match[1]); $thisval = Url::filterBadProtocol($match[1]);
if (!$skip) { if (!$skip) {
$attributes_array[] = "$attribute_name=\"$thisval\""; $attributes_array[] = "$attribute_name=\"$thisval\"";
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
use Symfony\Cmf\Component\Routing\ProviderBasedGenerator; use Symfony\Cmf\Component\Routing\ProviderBasedGenerator;
use Drupal\Component\Utility\Settings; use Drupal\Component\Utility\Settings;
use Drupal\Component\Utility\UrlValidator; use Drupal\Component\Utility\Url;
use Drupal\Core\Config\ConfigFactory; use Drupal\Core\Config\ConfigFactory;
use Drupal\Core\PathProcessor\OutboundPathProcessorInterface; use Drupal\Core\PathProcessor\OutboundPathProcessorInterface;
...@@ -83,7 +83,7 @@ public function __construct(RouteProviderInterface $provider, OutboundPathProces ...@@ -83,7 +83,7 @@ public function __construct(RouteProviderInterface $provider, OutboundPathProces
$this->pathProcessor = $path_processor; $this->pathProcessor = $path_processor;
$this->mixedModeSessions = $settings->get('mixed_mode_sessions', FALSE); $this->mixedModeSessions = $settings->get('mixed_mode_sessions', FALSE);
$allowed_protocols = $config->get('system.filter')->get('protocols') ?: array('http', 'https'); $allowed_protocols = $config->get('system.filter')->get('protocols') ?: array('http', 'https');
UrlValidator::setAllowedProtocols($allowed_protocols); Url::setAllowedProtocols($allowed_protocols);
} }
/** /**
...@@ -112,7 +112,7 @@ public function generate($name, $parameters = array(), $absolute = FALSE) { ...@@ -112,7 +112,7 @@ public function generate($name, $parameters = array(), $absolute = FALSE) {
if ($name instanceof SymfonyRoute) { if ($name instanceof SymfonyRoute) {
$route = $name; $route = $name;
} }
elseif (null === $route = $this->provider->getRouteByName($name, $parameters)) { elseif (NULL === $route = $this->provider->getRouteByName($name, $parameters)) {
throw new RouteNotFoundException(sprintf('Route "%s" does not exist.', $name)); throw new RouteNotFoundException(sprintf('Route "%s" does not exist.', $name));
} }
...@@ -239,7 +239,7 @@ public function generateFromPath($path = NULL, $options = array()) { ...@@ -239,7 +239,7 @@ public function generateFromPath($path = NULL, $options = array()) {
// that would require another function call, and performance inside url() is // that would require another function call, and performance inside url() is
// critical. // critical.
$colonpos = strpos($path, ':'); $colonpos = strpos($path, ':');
$options['external'] = ($colonpos !== FALSE && !preg_match('![/?#]!', substr($path, 0, $colonpos)) && UrlValidator::stripDangerousProtocols($path) == $path); $options['external'] = ($colonpos !== FALSE && !preg_match('![/?#]!', substr($path, 0, $colonpos)) && Url::stripDangerousProtocols($path) == $path);
} }
if (isset($options['fragment']) && $options['fragment'] !== '') { if (isset($options['fragment']) && $options['fragment'] !== '') {
...@@ -257,7 +257,7 @@ public function generateFromPath($path = NULL, $options = array()) { ...@@ -257,7 +257,7 @@ public function generateFromPath($path = NULL, $options = array()) {
} }
// Append the query. // Append the query.
if ($options['query']) { if ($options['query']) {
$path .= (strpos($path, '?') !== FALSE ? '&' : '?') . $this->httpBuildQuery($options['query']); $path .= (strpos($path, '?') !== FALSE ? '&' : '?') . Url::buildQuery($options['query']);
} }
if (isset($options['https']) && $this->mixedModeSessions) { if (isset($options['https']) && $this->mixedModeSessions) {
if ($options['https'] === TRUE) { if ($options['https'] === TRUE) {
...@@ -300,7 +300,7 @@ public function generateFromPath($path = NULL, $options = array()) { ...@@ -300,7 +300,7 @@ public function generateFromPath($path = NULL, $options = array()) {
$prefix = empty($path) ? rtrim($options['prefix'], '/') : $options['prefix']; $prefix = empty($path) ? rtrim($options['prefix'], '/') : $options['prefix'];
$path = str_replace('%2F', '/', rawurlencode($prefix . $path)); $path = str_replace('%2F', '/', rawurlencode($prefix . $path));
$query = $options['query'] ? ('?' . $this->httpBuildQuery($options['query'])) : ''; $query = $options['query'] ? ('?' . Url::buildQuery($options['query'])) : '';
return $base . $options['script'] . $path . $query . $options['fragment']; return $base . $options['script'] . $path . $query . $options['fragment'];
} }
...@@ -325,47 +325,6 @@ public function setScriptPath($path) { ...@@ -325,47 +325,6 @@ public function setScriptPath($path) {
$this->scriptPath = $path; $this->scriptPath = $path;
} }
/**
* Parses an array into a valid, rawurlencoded query string.
*
* This differs from http_build_query() as we need to rawurlencode() (instead of
* urlencode()) all query parameters.
*
* @param $query
* The query parameter array to be processed, e.g. $_GET.
* @param $parent
* Internal use only. Used to build the $query array key for nested items.
*
* @return
* A rawurlencoded string which can be used as or appended to the URL query
* string.
*
* @see drupal_get_query_parameters()
* @ingroup php_wrappers
*/
public function httpBuildQuery(array $query, $parent = '') {
$params = array();
foreach ($query as $key => $value) {
$key = ($parent ? $parent . '[' . rawurlencode($key) . ']' : rawurlencode($key));
// Recurse into children.
if (is_array($value)) {
$params[] = $this->httpBuildQuery($value, $key);
}
// If a query parameter value is NULL, only append its key.
elseif (!isset($value)) {
$params[] = $key;
}
else {
// For better readability of paths in query strings, we decode slashes.
$params[] = $key . '=' . str_replace('%2F', '/', rawurlencode($value));
}
}
return implode('&', $params);
}
/** /**
* Passes the path to a processor manager to allow alterations. * Passes the path to a processor manager to allow alterations.
*/ */
......
...@@ -347,7 +347,8 @@ function _contextual_id_to_links($id) { ...@@ -347,7 +347,8 @@ function _contextual_id_to_links($id) {
foreach ($contexts as $context) { foreach ($contexts as $context) {
list($module, $parent_path, $path_args, $metadata_raw) = explode(':', $context); list($module, $parent_path, $path_args, $metadata_raw) = explode(':', $context);
$path_args = explode('/', $path_args); $path_args = explode('/', $path_args);
$metadata = drupal_get_query_array($metadata_raw); $metadata = array();
parse_str($metadata_raw, $metadata);
$contextual_links[$module] = array($parent_path, $path_args, $metadata); $contextual_links[$module] = array($parent_path, $path_args, $metadata);
} }
return $contextual_links; return $contextual_links;
......
...@@ -500,7 +500,9 @@ function language_url_rewrite_session(&$path, &$options) { ...@@ -500,7 +500,9 @@ function language_url_rewrite_session(&$path, &$options) {
// user language preference even with cookies disabled. // user language preference even with cookies disabled.
if ($query_rewrite) { if ($query_rewrite) {
if (is_string($options['query'])) { if (is_string($options['query'])) {
$options['query'] = drupal_get_query_array($options['query']); $query = array();
parse_str($options['query'], $query);
$options['query'] = $query;
} }
if (!isset($options['query'][$query_param])) { if (!isset($options['query'][$query_param])) {
$options['query'][$query_param] = $query_value; $options['query'][$query_param] = $query_value;
......
...@@ -227,7 +227,8 @@ public function validate(array $form, array &$form_state) { ...@@ -227,7 +227,8 @@ public function validate(array $form, array &$form_state) {
if (!url_is_external($menu_link->link_path)) { if (!url_is_external($menu_link->link_path)) {
$parsed_link = parse_url($menu_link->link_path); $parsed_link = parse_url($menu_link->link_path);
if (isset($parsed_link['query'])) { if (isset($parsed_link['query'])) {
$menu_link->options['query'] = drupal_get_query_array($parsed_link['query']); $menu_link->options['query'] = array();
parse_str($parsed_link['query'], $menu_link->options['query']);
} }
else { else {
// Use unset() rather than setting to empty string // Use unset() rather than setting to empty string
......
...@@ -196,16 +196,6 @@ function testDrupalGetQueryParameters() { ...@@ -196,16 +196,6 @@ function testDrupalGetQueryParameters() {
$this->assertEqual(drupal_get_query_parameters($original, array('a', 'b[e]', 'c')), $result, "'a', 'b[e]', 'c' were removed."); $this->assertEqual(drupal_get_query_parameters($original, array('a', 'b[e]', 'c')), $result, "'a', 'b[e]', 'c' were removed.");
} }
/**
* Tests drupal_http_build_query().
*/
function testDrupalHttpBuildQuery() {
$this->assertEqual(drupal_http_build_query(array('a' => ' &#//+%20@۞')), 'a=%20%26%23//%2B%2520%40%DB%9E', 'Value was properly encoded.');
$this->assertEqual(drupal_http_build_query(array(' &#//+%20@۞' => 'a')), '%20%26%23%2F%2F%2B%2520%40%DB%9E=a', 'Key was properly encoded.');
$this->assertEqual(drupal_http_build_query(array('a' => '1', 'b' => '2', 'c' => '3')), 'a=1&b=2&c=3', 'Multiple values were properly concatenated.');
$this->assertEqual(drupal_http_build_query(array('a' => array('b' => '2', 'c' => '3'), 'd' => 'foo')), 'a[b]=2&a[c]=3&d=foo', 'Nested array was properly encoded.');
}
/** /**
* Tests drupal_parse_url(). * Tests drupal_parse_url().
*/ */
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
use Drupal\Component\Utility\String; use Drupal\Component\Utility\String;
use Drupal\Component\Utility\Unicode; use Drupal\Component\Utility\Unicode;
use Drupal\Component\Utility\UrlValidator; use Drupal\Component\Utility\Url;
use Drupal\Component\Utility\Xss; use Drupal\Component\Utility\Xss;
use Drupal\views\Plugin\views\display\DisplayPluginBase; use Drupal\views\Plugin\views\display\DisplayPluginBase;
use Drupal\views\Plugin\views\PluginBase; use Drupal\views\Plugin\views\PluginBase;
...@@ -221,7 +221,7 @@ public function sanitizeValue($value, $type = NULL) { ...@@ -221,7 +221,7 @@ public function sanitizeValue($value, $type = NULL) {
$value = Xss::filterAdmin($value); $value = Xss::filterAdmin($value);
break; break;
case 'url': case 'url':
$value = String::checkPlain(UrlValidator::stripDangerousProtocols($value)); $value = String::checkPlain(Url::stripDangerousProtocols($value));
break; break;
default: default:
$value = String::checkPlain($value); $value = String::checkPlain($value);
......
...@@ -1365,7 +1365,8 @@ protected function renderAsLink($alter, $text, $tokens) { ...@@ -1365,7 +1365,8 @@ protected function renderAsLink($alter, $text, $tokens) {
if (isset($url['query'])) { if (isset($url['query'])) {
$path = strtr($path, array('?' . $url['query'] => '')); $path = strtr($path, array('?' . $url['query'] => ''));
$query = drupal_get_query_array($url['query']); $query = array();
parse_str($url['query'], $query);
// Remove query parameters that were assigned a query string replacement // Remove query parameters that were assigned a query string replacement
// token for which there is no value available. // token for which there is no value available.
foreach ($query as $param => $val) { foreach ($query as $param => $val) {
...@@ -1421,7 +1422,9 @@ protected function renderAsLink($alter, $text, $tokens) { ...@@ -1421,7 +1422,9 @@ protected function renderAsLink($alter, $text, $tokens) {
// convert back to an array form for l(). // convert back to an array form for l().
$options['query'] = drupal_http_build_query($alter['query']); $options['query'] = drupal_http_build_query($alter['query']);
$options['query'] = strtr($options['query'], $tokens); $options['query'] = strtr($options['query'], $tokens);
$options['query'] = drupal_get_query_array($options['query']); $query = array();
parse_str($options['query'], $query);
$options['query'] = $query;
} }
if (isset($alter['alias'])) { if (isset($alter['alias'])) {
// Alias is a boolean field, so no token. // Alias is a boolean field, so no token.
......
...@@ -2,30 +2,63 @@ ...@@ -2,30 +2,63 @@
/** /**
* @file * @file
* Contains \Drupal\Tests\Core\Common\UrlValidatorTest. * Contains \Drupal\Tests\Component\Utility\UrlTest.
*/ */
namespace Drupal\Tests\Core\Common; namespace Drupal\Tests\Component\Utility;
use Drupal\Component\Utility\Url;
use Drupal\Component\Utility\String; use Drupal\Component\Utility\String;
use Drupal\Component\Utility\UrlValidator;
use Drupal\Tests\UnitTestCase; use Drupal\Tests\UnitTestCase;
/** /**
* Tests URL validation by valid_url(). * Tests the http query methods.
*
* @see \Drupal\Component\Utility\Url
*/ */
class UrlValidatorTest extends UnitTestCase { class UrlTest extends UnitTestCase {
public static function getInfo() { public static function getInfo() {
return array( return array(
'name' => 'URL validation', 'name' => t('Url Tests'),
'description' => 'Tests URL validation by valid_url()', 'description' => t('Tests the Url utility class.'),
'group' => 'Common', 'group' => t('Path API'),
);
}
/**
* Provides test data for testBuildQuery().
*
* @return array
*/
public function providerTestBuildQuery() {
return array(
array(array('a' => ' &#//+%20@۞'), 'a=%20%26%23//%2B%2520%40%DB%9E', 'Value was properly encoded.'),
array(array(' &#//+%20@۞' => 'a'), '%20%26%23%2F%2F%2B%2520%40%DB%9E=a', 'Key was properly encoded.'),
array(array('a' => '1', 'b' => '2', 'c' => '3'), 'a=1&b=2&c=3', 'Multiple values were properly concatenated.'),
array(array('a' => array('b' => '2', 'c' => '3'), 'd' => 'foo'), 'a[b]=2&a[c]=3&d=foo', 'Nested array was properly encoded.'),
); );
} }
/** /**
* Data provider for absolute URLs. * Tests Url::buildQuery().
*
* @param array $query
* The array of query parameters.
* @param string $expected
* The expected query string.
* @param string $message
* The assertion message.
*
* @dataProvider providerTestBuildQuery
*/
public function testBuildQuery($query, $expected, $message) {
$this->assertEquals(Url::buildQuery($query), $expected, $message);
}