diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index be8c695..f991991 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -6,7 +6,7 @@
use Drupal\Component\Utility\String;
use Drupal\Component\Utility\Timer;
use Drupal\Component\Utility\Unicode;
-use Drupal\Component\Utility\Url;
+use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\DrupalKernel;
use Drupal\Core\Database\Database;
use Drupal\Core\DependencyInjection\ContainerBuilder;
diff --git a/core/includes/common.inc b/core/includes/common.inc
index b97cc5e..f06cae2 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -6,7 +6,7 @@
use Drupal\Component\Utility\SortArray;
use Drupal\Component\Utility\String;
use Drupal\Component\Utility\Tags;
-use Drupal\Component\Utility\Url;
+use Drupal\Component\Utility\UrlHelper;
use Drupal\Component\Utility\Xss;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Language\Language;
@@ -421,26 +421,26 @@ function drupal_get_feeds($delimiter = "\n") {
* @return
* An array containing query parameters, which can be used for url().
*
- * @deprecated as of Drupal 8.0. Use Url::filterQueryParameters() instead.
+ * @deprecated as of Drupal 8.0. Use UrlHelper::filterQueryParameters() instead.
*/
function drupal_get_query_parameters(array $query = NULL, array $exclude = array(), $parent = '') {
if (!isset($query)) {
$query = \Drupal::request()->query->all();
}
- return Url::filterQueryParameters($query, $exclude, $parent);
+ return UrlHelper::filterQueryParameters($query, $exclude, $parent);
}
/**
* Parses an array into a valid, rawurlencoded query string.
*
* @see drupal_get_query_parameters()
- * @deprecated as of Drupal 8.0. Use Url::buildQuery() instead.
+ * @deprecated as of Drupal 8.0. Use UrlHelper::buildQuery() instead.
* @ingroup php_wrappers
*
- * @deprecated as of Drupal 8.0. Use Url::buildQuery() instead.
+ * @deprecated as of Drupal 8.0. Use UrlHelper::buildQuery() instead.
*/
function drupal_http_build_query(array $query, $parent = '') {
- return Url::buildQuery($query, $parent);
+ return UrlHelper::buildQuery($query, $parent);
}
/**
@@ -471,7 +471,7 @@ function drupal_get_destination() {
}
else {
$path = current_path();
- $query = Url::buildQuery(Url::filterQueryParameters($query->all()));
+ $query = UrlHelper::buildQuery(UrlHelper::filterQueryParameters($query->all()));
if ($query != '') {
$path .= '?' . $query;
}
@@ -513,10 +513,10 @@ function drupal_get_destination() {
* @see url()
* @ingroup php_wrappers
*
- * @deprecated as of Drupal 8.0. Use Url::parse() instead.
+ * @deprecated as of Drupal 8.0. Use UrlHelper::parse() instead.
*/
function drupal_parse_url($url) {
- return Url::parse($url);
+ return UrlHelper::parse($url);
}
/**
@@ -530,10 +530,10 @@ function drupal_parse_url($url) {
* @param $path
* The Drupal path to encode.
*
- * @deprecated as of Drupal 8.0. Use Url::encodePath() instead.
+ * @deprecated as of Drupal 8.0. Use UrlHelper::encodePath() instead.
*/
function drupal_encode_path($path) {
- return Url::encodePath($path);
+ return UrlHelper::encodePath($path);
}
/**
@@ -545,10 +545,10 @@ function drupal_encode_path($path) {
* @return
* TRUE if the URL has the same domain and base path.
*
- * @deprecated as of Drupal 8.0. Use Url::externalIsLocal() instead.
+ * @deprecated as of Drupal 8.0. Use UrlHelper::externalIsLocal() instead.
*/
function _external_url_is_local($url) {
- return Url::externalIsLocal($url, base_path());
+ return UrlHelper::externalIsLocal($url, base_path());
}
/**
@@ -602,12 +602,12 @@ function valid_email_address($mail) {
* @return
* TRUE if the URL is in a valid format.
*
- * @see \Drupal\Component\Utility\Url::isValid()
+ * @see \Drupal\Component\Utility\UrlHelper::isValid()
*
- * @deprecated as of Drupal 8.0. Use Url::isValid() instead.
+ * @deprecated as of Drupal 8.0. Use UrlHelper::isValid() instead.
*/
function valid_url($url, $absolute = FALSE) {
- return Url::isValid($url, $absolute);
+ return UrlHelper::isValid($url, $absolute);
}
/**
@@ -666,10 +666,10 @@ function valid_number_step($value, $step, $offset = 0.0) {
* \Drupal\Component\Utility\String::checkPlain() being called on it. However,
* it can be passed to functions expecting plain-text strings.
*
- * @see \Drupal\Component\Utility\Url::stripDangerousProtocols()
+ * @see \Drupal\Component\Utility\UrlHelper::stripDangerousProtocols()
*/
function drupal_strip_dangerous_protocols($uri) {
- return Url::stripDangerousProtocols($uri);
+ return UrlHelper::stripDangerousProtocols($uri);
}
/**
@@ -685,13 +685,13 @@ function drupal_strip_dangerous_protocols($uri) {
* because Drupal\Core\Template\Attribute expects those values to be
* plain-text strings. To pass a filtered URI to
* Drupal\Core\Template\Attribute, call
- * \Drupal\Component\Utility\Url::stripDangerousProtocols() instead.
+ * \Drupal\Component\Utility\UrlHelper::stripDangerousProtocols() instead.
*
- * @see \Drupal\Component\Utility\Url::stripDangerousProtocols()
+ * @see \Drupal\Component\Utility\UrlHelper::stripDangerousProtocols()
* @see \Drupal\Component\Utility\String::checkPlain()
*/
function check_url($uri) {
- return String::checkPlain(Url::stripDangerousProtocols($uri));
+ return String::checkPlain(UrlHelper::stripDangerousProtocols($uri));
}
/**
@@ -757,10 +757,10 @@ function filter_xss($string, $allowed_tags = array('a', 'em', 'strong', 'cite',
* @return string
* Cleaned up and HTML-escaped version of $string.
*
- * @see \Drupal\Component\Utility\Url::filterBadProtocol()
+ * @see \Drupal\Component\Utility\UrlHelper::filterBadProtocol()
*/
function filter_xss_bad_protocol($string) {
- return Url::filterBadProtocol($string);
+ return UrlHelper::filterBadProtocol($string);
}
/**
@@ -1140,7 +1140,7 @@ function url($path = NULL, array $options = array()) {
* Boolean TRUE or FALSE, where TRUE indicates an external path.
*/
function url_is_external($path) {
- return Url::isExternal($path);
+ return UrlHelper::isExternal($path);
}
/**
@@ -3082,7 +3082,7 @@ function _drupal_bootstrap_code() {
// of allowed protocols for these cases.
$allowed_protocols = array('http', 'https');
}
- Url::setAllowedProtocols($allowed_protocols);
+ UrlHelper::setAllowedProtocols($allowed_protocols);
}
/**
diff --git a/core/includes/form.inc b/core/includes/form.inc
index 5d4a943..e41e360 100644
--- a/core/includes/form.inc
+++ b/core/includes/form.inc
@@ -8,7 +8,7 @@
use Drupal\Component\Utility\NestedArray;
use Drupal\Component\Utility\Number;
use Drupal\Component\Utility\String;
-use Drupal\Component\Utility\Url;
+use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\Database\Database;
use Drupal\Core\Language\Language;
use Drupal\Core\Template\Attribute;
@@ -2565,7 +2565,7 @@ function form_pre_render_color($element) {
function theme_form($variables) {
$element = $variables['element'];
if (isset($element['#action'])) {
- $element['#attributes']['action'] = Url::stripDangerousProtocols($element['#action']);
+ $element['#attributes']['action'] = UrlHelper::stripDangerousProtocols($element['#action']);
}
element_set_attributes($element, array('method', 'id'));
if (empty($element['#attributes']['accept-charset'])) {
diff --git a/core/includes/menu.inc b/core/includes/menu.inc
index bbf5c43..02f40b7 100644
--- a/core/includes/menu.inc
+++ b/core/includes/menu.inc
@@ -16,6 +16,7 @@
use Symfony\Cmf\Component\Routing\RouteObjectInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
+use Symfony\Component\Routing\Exception\ResourceNotFoundException;
use Symfony\Component\Routing\Route;
/**
@@ -922,7 +923,6 @@ function _menu_link_translate(&$item) {
* @return bool
* TRUE if the user has access or FALSE if the user should be presented
* with access denied.
- *
*/
function menu_item_route_access(Route $route, $href, &$map, Request $request = NULL) {
if (!isset($request)) {
@@ -937,6 +937,9 @@ function menu_item_route_access(Route $route, $href, &$map, Request $request = N
catch (NotFoundHttpException $e) {
return FALSE;
}
+ catch (ResourceNotFoundException $e) {
+ return FALSE;
+ }
// Populate the map with any matching values from the request.
$path_bits = explode('/', trim($route->getPath(), '/'));
diff --git a/core/includes/pager.inc b/core/includes/pager.inc
index 9874689..caf1044 100644
--- a/core/includes/pager.inc
+++ b/core/includes/pager.inc
@@ -6,7 +6,7 @@
*/
use Drupal\Core\Template\Attribute;
-use Drupal\Component\Utility\Url;
+use Drupal\Component\Utility\UrlHelper;
/**
* Returns the current page being requested for display within a pager.
@@ -138,7 +138,7 @@ function pager_default_initialize($total, $limit, $element = 0) {
function pager_get_query_parameters() {
$query = &drupal_static(__FUNCTION__);
if (!isset($query)) {
- $query = Url::filterQueryParameters(\Drupal::request()->query->all(), array('page'));
+ $query = UrlHelper::filterQueryParameters(\Drupal::request()->query->all(), array('page'));
}
return $query;
}
diff --git a/core/includes/tablesort.inc b/core/includes/tablesort.inc
index 1f6962b..e342e3e 100644
--- a/core/includes/tablesort.inc
+++ b/core/includes/tablesort.inc
@@ -3,7 +3,7 @@
use Drupal\Core\Database\Connection;
use Drupal\Core\Database\Query\SelectExtender;
use Drupal\Core\Database\Query\SelectInterface;
-use Drupal\Component\Utility\Url;
+use Drupal\Component\Utility\UrlHelper;
/**
* @file
@@ -101,7 +101,7 @@ function tablesort_cell($cell, $header, $ts, $i) {
* page request except for those pertaining to table sorting.
*/
function tablesort_get_query_parameters() {
- return Url::filterQueryParameters(\Drupal::request()->query->all(), array('sort', 'order'));
+ return UrlHelper::filterQueryParameters(\Drupal::request()->query->all(), array('sort', 'order'));
}
/**
diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index 96a0466..529ce90 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -9,7 +9,7 @@
*/
use Drupal\Component\Utility\String;
-use Drupal\Component\Utility\Url;
+use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\Config\Config;
use Drupal\Core\Language\Language;
use Drupal\Core\Extension\ExtensionNameLengthException;
@@ -2117,7 +2117,7 @@ function template_preprocess_html(&$variables) {
$type = theme_get_setting('favicon.mimetype');
$build['#attached']['drupal_add_html_head_link'][][] = array(
'rel' => 'shortcut icon',
- 'href' => Url::stripDangerousProtocols($favicon),
+ 'href' => UrlHelper::stripDangerousProtocols($favicon),
'type' => $type,
);
drupal_render($build);
@@ -2410,7 +2410,7 @@ function template_preprocess_maintenance_page(&$variables) {
$type = theme_get_setting('favicon.mimetype');
$build['#attached']['drupal_add_html_head_link'][][] = array(
'rel' => 'shortcut icon',
- 'href' => Url::stripDangerousProtocols($favicon),
+ 'href' => UrlHelper::stripDangerousProtocols($favicon),
'type' => $type,
);
drupal_render($build);
diff --git a/core/lib/Drupal.php b/core/lib/Drupal.php
index 0ec88d7..f98d607 100644
--- a/core/lib/Drupal.php
+++ b/core/lib/Drupal.php
@@ -5,6 +5,7 @@
* Contains Drupal.
*/
+use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
@@ -517,7 +518,13 @@ public static function linkGenerator() {
* @see \Drupal\Core\Utility\LinkGeneratorInterface::generate()
*/
public static function l($text, $route_name, array $parameters = array(), array $options = array()) {
- return static::$container->get('link_generator')->generate($text, $route_name, $parameters, $options);
+ $link_generator = static::linkGenerator();
+ if ($route_name instanceof Url) {
+ return $link_generator->generateFromUrl($text, $route_name);
+ }
+ else {
+ return $link_generator->generate($text, $route_name, $parameters, $options);
+ }
}
/**
diff --git a/core/lib/Drupal/Component/Utility/Url.php b/core/lib/Drupal/Component/Utility/UrlHelper.php
similarity index 98%
rename from core/lib/Drupal/Component/Utility/Url.php
rename to core/lib/Drupal/Component/Utility/UrlHelper.php
index c7eff3e..bf956c9 100644
--- a/core/lib/Drupal/Component/Utility/Url.php
+++ b/core/lib/Drupal/Component/Utility/UrlHelper.php
@@ -2,7 +2,7 @@
/**
* @file
- * Contains \Drupal\Component\Utility\Url.
+ * Contains \Drupal\Component\Utility\UrlHelper.
*/
namespace Drupal\Component\Utility;
@@ -10,7 +10,7 @@
/**
* Helper class URL based methods.
*/
-class Url {
+class UrlHelper {
/**
* The list of allowed protocols.
@@ -119,7 +119,7 @@ public static function filterQueryParameters(array $query, array $exclude = arra
* The returned array contains a 'path' that may be passed separately to url().
* For example:
* @code
- * $options = Url::parse(\Drupal::request()->query->get('destination'));
+ * $options = UrlHelper::parse(\Drupal::request()->query->get('destination'));
* $my_url = url($options['path'], $options);
* $my_link = l('Example link', $options['path'], $options);
* @endcode
diff --git a/core/lib/Drupal/Component/Utility/Xss.php b/core/lib/Drupal/Component/Utility/Xss.php
index 0daab37..2485f6c 100644
--- a/core/lib/Drupal/Component/Utility/Xss.php
+++ b/core/lib/Drupal/Component/Utility/Xss.php
@@ -226,7 +226,7 @@ protected static function attributes($attributes) {
case 2:
// Attribute value, a URL after href= for instance.
if (preg_match('/^"([^"]*)"(\s+|$)/', $attributes, $match)) {
- $thisval = Url::filterBadProtocol($match[1]);
+ $thisval = UrlHelper::filterBadProtocol($match[1]);
if (!$skip) {
$attributes_array[] = "$attribute_name=\"$thisval\"";
@@ -238,7 +238,7 @@ protected static function attributes($attributes) {
}
if (preg_match("/^'([^']*)'(\s+|$)/", $attributes, $match)) {
- $thisval = Url::filterBadProtocol($match[1]);
+ $thisval = UrlHelper::filterBadProtocol($match[1]);
if (!$skip) {
$attributes_array[] = "$attribute_name='$thisval'";
@@ -249,7 +249,7 @@ protected static function attributes($attributes) {
}
if (preg_match("%^([^\s\"']+)(\s+|$)%", $attributes, $match)) {
- $thisval = Url::filterBadProtocol($match[1]);
+ $thisval = UrlHelper::filterBadProtocol($match[1]);
if (!$skip) {
$attributes_array[] = "$attribute_name=\"$thisval\"";
diff --git a/core/lib/Drupal/Core/Form/ConfirmFormHelper.php b/core/lib/Drupal/Core/Form/ConfirmFormHelper.php
index f2b4f25..0475d5a 100644
--- a/core/lib/Drupal/Core/Form/ConfirmFormHelper.php
+++ b/core/lib/Drupal/Core/Form/ConfirmFormHelper.php
@@ -8,7 +8,7 @@
namespace Drupal\Core\Form;
use Drupal\Component\Utility\String;
-use Drupal\Component\Utility\Url;
+use Drupal\Component\Utility\UrlHelper;
use Symfony\Component\HttpFoundation\Request;
/**
@@ -36,7 +36,7 @@ public static function buildCancelLink(ConfirmFormInterface $form, Request $requ
$query = $request->query;
// If a destination is specified, that serves as the cancel link.
if ($query->has('destination')) {
- $options = Url::parse($query->get('destination'));
+ $options = UrlHelper::parse($query->get('destination'));
$link = array(
'#href' => $options['path'],
'#options' => $options,
diff --git a/core/lib/Drupal/Core/Form/FormBuilder.php b/core/lib/Drupal/Core/Form/FormBuilder.php
index 43d15a6..821ed61 100644
--- a/core/lib/Drupal/Core/Form/FormBuilder.php
+++ b/core/lib/Drupal/Core/Form/FormBuilder.php
@@ -10,7 +10,7 @@
use Drupal\Component\Utility\Crypt;
use Drupal\Component\Utility\NestedArray;
use Drupal\Component\Utility\Unicode;
-use Drupal\Component\Utility\Url;
+use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\Access\CsrfTokenGenerator;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\HttpKernel;
@@ -18,6 +18,7 @@
use Drupal\Core\Render\Element;
use Drupal\Core\Routing\UrlGeneratorInterface;
use Drupal\Core\StringTranslation\TranslationInterface;
+use Drupal\Core\Url;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
@@ -847,7 +848,7 @@ public function validateForm($form_id, &$form, &$form_state) {
if (isset($form['#token'])) {
if (!$this->csrfToken->validate($form_state['values']['form_token'], $form['#token'])) {
$path = $this->request->attributes->get('_system_path');
- $query = Url::filterQueryParameters($this->request->query->all());
+ $query = UrlHelper::filterQueryParameters($this->request->query->all());
$url = $this->urlGenerator->generateFromPath($path, array('query' => $query));
// Setting this error will cause the form to fail validation.
@@ -933,13 +934,17 @@ public function redirectForm($form_state) {
// Check for a route-based redirection.
if (isset($form_state['redirect_route'])) {
- $form_state['redirect_route'] += array(
- 'route_parameters' => array(),
- 'options' => array(),
- );
- $form_state['redirect_route']['options']['absolute'] = TRUE;
- $url = $this->urlGenerator->generateFromRoute($form_state['redirect_route']['route_name'], $form_state['redirect_route']['route_parameters'], $form_state['redirect_route']['options']);
- return new RedirectResponse($url);
+ // @todo Remove once all redirects are converted to Url.
+ if (!($form_state['redirect_route'] instanceof Url)) {
+ $form_state['redirect_route'] += array(
+ 'route_parameters' => array(),
+ 'options' => array(),
+ );
+ $form_state['redirect_route'] = new Url($form_state['redirect_route']['route_name'], $form_state['redirect_route']['route_parameters'], $form_state['redirect_route']['options']);
+ }
+
+ $form_state['redirect_route']->setAbsolute();
+ return new RedirectResponse($form_state['redirect_route']->toString());
}
// Only invoke a redirection if redirect value was not set to FALSE.
@@ -1318,7 +1323,7 @@ public function doBuildForm($form_id, &$element, &$form_state) {
// Special handling if we're on the top level form element.
if (isset($element['#type']) && $element['#type'] == 'form') {
if (!empty($element['#https']) && settings()->get('mixed_mode_sessions', FALSE) &&
- !Url::isExternal($element['#action'])) {
+ !UrlHelper::isExternal($element['#action'])) {
global $base_root;
// Not an external URL so ensure that it is secure.
diff --git a/core/lib/Drupal/Core/Routing/NullGenerator.php b/core/lib/Drupal/Core/Routing/NullGenerator.php
index 1430f1f..a677a60 100644
--- a/core/lib/Drupal/Core/Routing/NullGenerator.php
+++ b/core/lib/Drupal/Core/Routing/NullGenerator.php
@@ -12,7 +12,7 @@
use Symfony\Component\Routing\Route;
/**
- * No-op implementation of a Url Generator, needed for backward compatibility.
+ * No-op implementation of a UrlGenerator, needed for backward compatibility.
*/
class NullGenerator extends UrlGenerator {
diff --git a/core/lib/Drupal/Core/Routing/UrlGenerator.php b/core/lib/Drupal/Core/Routing/UrlGenerator.php
index 1bb4b53..9496e19 100644
--- a/core/lib/Drupal/Core/Routing/UrlGenerator.php
+++ b/core/lib/Drupal/Core/Routing/UrlGenerator.php
@@ -16,7 +16,7 @@
use Symfony\Cmf\Component\Routing\ProviderBasedGenerator;
use Drupal\Component\Utility\Settings;
-use Drupal\Component\Utility\Url;
+use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\Config\ConfigFactory;
use Drupal\Core\PathProcessor\OutboundPathProcessorInterface;
use Drupal\Core\RouteProcessor\OutboundRouteProcessorInterface;
@@ -92,7 +92,7 @@ public function __construct(RouteProviderInterface $provider, OutboundPathProces
$this->routeProcessor = $route_processor;
$this->mixedModeSessions = $settings->get('mixed_mode_sessions', FALSE);
$allowed_protocols = $config->get('system.filter')->get('protocols') ?: array('http', 'https');
- Url::setAllowedProtocols($allowed_protocols);
+ UrlHelper::setAllowedProtocols($allowed_protocols);
}
/**
@@ -237,12 +237,12 @@ public function generateFromPath($path = NULL, $options = array()) {
if (!isset($options['external'])) {
// Return an external link if $path contains an allowed absolute URL. Only
- // call the slow \Drupal\Component\Utility\Url::stripDangerousProtocols()
+ // call the slow \Drupal\Component\Utility\UrlHelper::stripDangerousProtocols()
// if $path contains a ':' before any / ? or #. Note: we could use
// url_is_external($path) here, but that would require another function
// call, and performance inside url() is critical.
$colonpos = strpos($path, ':');
- $options['external'] = ($colonpos !== FALSE && !preg_match('![/?#]!', substr($path, 0, $colonpos)) && Url::stripDangerousProtocols($path) == $path);
+ $options['external'] = ($colonpos !== FALSE && !preg_match('![/?#]!', substr($path, 0, $colonpos)) && UrlHelper::stripDangerousProtocols($path) == $path);
}
if (isset($options['fragment']) && $options['fragment'] !== '') {
@@ -260,7 +260,7 @@ public function generateFromPath($path = NULL, $options = array()) {
}
// Append the query.
if ($options['query']) {
- $path .= (strpos($path, '?') !== FALSE ? '&' : '?') . Url::buildQuery($options['query']);
+ $path .= (strpos($path, '?') !== FALSE ? '&' : '?') . UrlHelper::buildQuery($options['query']);
}
if (isset($options['https']) && $this->mixedModeSessions) {
if ($options['https'] === TRUE) {
@@ -303,7 +303,7 @@ public function generateFromPath($path = NULL, $options = array()) {
$prefix = empty($path) ? rtrim($options['prefix'], '/') : $options['prefix'];
$path = str_replace('%2F', '/', rawurlencode($prefix . $path));
- $query = $options['query'] ? ('?' . Url::buildQuery($options['query'])) : '';
+ $query = $options['query'] ? ('?' . UrlHelper::buildQuery($options['query'])) : '';
return $base . $options['script'] . $path . $query . $options['fragment'];
}
diff --git a/core/lib/Drupal/Core/Routing/UrlMatcher.php b/core/lib/Drupal/Core/Routing/UrlMatcher.php
index 9e973d4..c347b51 100644
--- a/core/lib/Drupal/Core/Routing/UrlMatcher.php
+++ b/core/lib/Drupal/Core/Routing/UrlMatcher.php
@@ -30,36 +30,16 @@ public function finalMatch(RouteCollection $collection, Request $request) {
$context = new RequestContext();
$context->fromRequest($request);
$this->setContext($context);
- return $this->match('/' . $request->attributes->get('_system_path'));
- }
-
- /**
- * Returns the route_name and route parameters matching a system path.
- *
- * @todo Find a better place for this method in
- * https://drupal.org/node/2153891.
- *
- * @param string $link_path
- * The link path to find a route name for.
- *
- * @return array
- * Returns an array with both the route name and parameters, or an empty
- * array if no route was matched.
- */
- public function findRouteNameParameters($link_path) {
- // Look up the route_name used for the given path.
- $request = Request::create('/' . $link_path);
- $request->attributes->set('_system_path', $link_path);
- try {
- $result = \Drupal::service('router')->matchRequest($request);
- $return = array();
- $return[] = isset($result['_route']) ? $result['_route'] : '';
- $return[] = $result['_raw_variables']->all();
- return $return;
+ if ($request->attributes->has('_system_path')) {
+ // _system_path never has leading or trailing slashes.
+ $path = '/' . $request->attributes->get('_system_path');
}
- catch (\Exception $e) {
- return array();
+ else {
+ // getPathInfo() always has leading slash, and might or might not have a
+ // trailing slash.
+ $path = rtrim($request->getPathInfo(), '/');
}
+ return $this->match($path);
}
}
diff --git a/core/lib/Drupal/Core/Url.php b/core/lib/Drupal/Core/Url.php
new file mode 100644
index 0000000..7e3886d
--- /dev/null
+++ b/core/lib/Drupal/Core/Url.php
@@ -0,0 +1,346 @@
+routeName = $route_name;
+ $this->routeParameters = $route_parameters;
+ $this->options = $options;
+ }
+
+ /**
+ * Returns the Url object matching a system path.
+ *
+ * @param string $path
+ * A system path (e.g. 'node/1').
+ *
+ * @return static
+ * An Url object.
+ *
+ * @throws \Symfony\Component\Routing\Exception\ResourceNotFoundException
+ */
+ public static function createFromPath($path) {
+ if (UrlHelper::isExternal($path)) {
+ $url = new static($path);
+ $url->setExternal();
+ return $url;
+ }
+ // Look up the route name and parameters used for the given path.
+ $result = \Drupal::service('router')->match('/' . $path);
+ return new static($result['_route'], $result['_raw_variables']->all());
+ }
+
+ /**
+ * Returns the Url object matching a request
+ *
+ * @param \Symfony\Component\HttpFoundation\Request $request
+ * A request object.
+ *
+ * @return static
+ * An Url object.
+ */
+ public static function createFromRequest(Request $request) {
+ if ($route_name = $request->attributes->get(RouteObjectInterface::ROUTE_NAME)) {
+ $route_parameters = $request->attributes->get('_raw_variables')->all();
+ return new static($route_name, $route_parameters);
+ }
+ elseif (($path = $request->attributes->get('_system_path')) && UrlHelper::isExternal($path)) {
+ $url = new static($path);
+ $url->setExternal();
+ return $url;
+ }
+ throw new \Exception('asdf');
+ }
+
+ /**
+ * Sets this Url to be external.
+ *
+ * @return $this
+ */
+ protected function setExternal() {
+ $this->external = TRUE;
+ // What was passed in as the route name is actually the path.
+ $this->path = $this->routeName;
+ $this->routeName = NULL;
+ return $this;
+ }
+
+ /**
+ * Indicates if this Url is external.
+ *
+ * @return bool
+ */
+ public function isExternal() {
+ return $this->external;
+ }
+
+ /**
+ * Returns the route name.
+ *
+ * @return string
+ */
+ public function getRouteName() {
+ if ($this->isExternal()) {
+ throw new \Exception('External URLs do not have route names.');
+ }
+ return $this->routeName;
+ }
+
+ /**
+ * Returns the route parameters.
+ *
+ * @return array
+ */
+ public function getRouteParameters() {
+ if ($this->isExternal()) {
+ throw new \Exception('External URLs do not have route parameters.');
+ }
+ return $this->routeParameters;
+ }
+
+ /**
+ * Sets the route parameters.
+ *
+ * @param array $parameters
+ * The array of parameters.
+ *
+ * @return $this
+ */
+ public function setRouteParameters($parameters) {
+ if ($this->isExternal()) {
+ throw new \Exception('External URLs do not have route parameters.');
+ }
+ $this->routeParameters = $parameters;
+ return $this;
+ }
+
+ /**
+ * Sets a specific route parameter.
+ *
+ * @param string $key
+ * The key of the route parameter.
+ * @param mixed $value
+ * The route parameter.
+ *
+ * @return $this
+ */
+ public function setRouteParameter($key, $value) {
+ if ($this->isExternal()) {
+ throw new \Exception('External URLs do not have route parameters.');
+ }
+ $this->routeParameters[$key] = $value;
+ return $this;
+ }
+
+ /**
+ * Returns the URL options.
+ *
+ * @return array
+ */
+ public function getOptions() {
+ return $this->options;
+ }
+
+ /**
+ * Sets the URL options.
+ *
+ * @param array $options
+ * The array of options.
+ *
+ * @return $this
+ */
+ public function setOptions($options) {
+ $this->options = $options;
+ return $this;
+ }
+
+ /**
+ * Sets a specific option.
+ *
+ * @param string $name
+ * The name of the option.
+ * @param mixed $value
+ * The option value.
+ *
+ * @return $this
+ */
+ public function setOption($name, $value) {
+ $this->options[$name] = $value;
+ return $this;
+ }
+
+ /**
+ * Sets the absolute value for this Url.
+ *
+ * @param bool $absolute
+ * (optional) Whether to make this Url absolute or not. Defaults to TRUE.
+ *
+ * @return $this
+ */
+ public function setAbsolute($absolute = TRUE) {
+ $this->options['absolute'] = $absolute;
+ return $this;
+ }
+
+ /**
+ * Generates the path for this Url object.
+ */
+ public function toString() {
+ if ($this->isExternal()) {
+ return $this->urlGenerator()->generateFromPath($this->path, $this->getOptions());
+ }
+
+ return $this->urlGenerator()->generateFromRoute($this->getRouteName(), $this->getRouteParameters(), $this->getOptions());
+ }
+
+ /**
+ * Returns all the information about the route.
+ *
+ * @return array
+ * An associative array containing all the properties of the route.
+ */
+ public function toArray() {
+ if ($this->isExternal()) {
+ throw new \Exception('External URLs do not have route metadata.');
+ }
+ return array(
+ 'route_name' => $this->getRouteName(),
+ 'route_parameters' => $this->getRouteParameters(),
+ 'options' => $this->getOptions(),
+ );
+ }
+
+ /**
+ * Returns the internal path for this route.
+ *
+ * This path will not include any prefixes, fragments, or query strings.
+ *
+ * @return string
+ * The internal path for this route.
+ */
+ public function getInternalPath() {
+ if ($this->isExternal()) {
+ throw new \Exception('External URLs do not have internal representations.');
+ }
+ return $this->urlGenerator()->getPathFromRoute($this->getRouteName(), $this->getRouteParameters());
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function __sleep() {
+ unset($this->urlGenerator);
+ return array_keys(get_object_vars($this));
+ }
+
+ /**
+ * Gets the URL generator.
+ *
+ * @return \Drupal\Core\Routing\UrlGeneratorInterface
+ * The URL generator.
+ */
+ protected function urlGenerator() {
+ if (!$this->urlGenerator) {
+ $this->urlGenerator = \Drupal::urlGenerator();
+ }
+ return $this->urlGenerator;
+ }
+
+ /**
+ * Sets the URL generator.
+ *
+ * @param \Drupal\Core\Routing\UrlGeneratorInterface
+ * The URL generator.
+ *
+ * @return $this
+ */
+ public function setUrlGenerator(UrlGeneratorInterface $url_generator) {
+ $this->urlGenerator = $url_generator;
+ return $this;
+ }
+
+}
diff --git a/core/lib/Drupal/Core/Utility/LinkGenerator.php b/core/lib/Drupal/Core/Utility/LinkGenerator.php
index 2874da4..5c06ab8 100644
--- a/core/lib/Drupal/Core/Utility/LinkGenerator.php
+++ b/core/lib/Drupal/Core/Utility/LinkGenerator.php
@@ -15,7 +15,7 @@
use Drupal\Core\Path\AliasManagerInterface;
use Drupal\Core\Template\Attribute;
use Drupal\Core\Routing\UrlGeneratorInterface;
-use Drupal\Core\Session\AccountInterface;
+use Drupal\Core\Url;
use Symfony\Cmf\Component\Routing\RouteObjectInterface;
use Symfony\Component\HttpFoundation\Request;
@@ -99,80 +99,88 @@ public function getActive() {
/**
* {@inheritdoc}
- *
- * For anonymous users, the "active" class will be calculated on the server,
- * because most sites serve each anonymous user the same cached page anyway.
- * For authenticated users, the "active" class will be calculated on the
- * client (through JavaScript), only data- attributes are added to links to
- * prevent breaking the render cache. The JavaScript is added in
- * system_page_build().
- *
- * @see system_page_build()
*/
- public function generate($text, $route_name, array $parameters = array(), array $options = array()) {
- // Start building a structured representation of our link to be altered later.
- $variables = array(
- // @todo Inject the service when drupal_render() is converted to one.
- 'text' => is_array($text) ? drupal_render($text) : $text,
- 'route_name' => $route_name,
- 'parameters' => $parameters,
- 'options' => $options,
- );
+ public function generateFromUrl($text, Url $url) {
+ // @todo Inject the service when drupal_render() is converted to one.
+ $text = is_array($text) ? drupal_render($text) : $text;
// Merge in default options.
- $variables['options'] += array(
+ $options = $url->getOptions();
+ $options += array(
'attributes' => array(),
'query' => array(),
'html' => FALSE,
'language' => NULL,
'set_active_class' => FALSE,
+ 'absolute' => FALSE,
);
// Add a hreflang attribute if we know the language of this link's url and
// hreflang has not already been set.
- if (!empty($variables['options']['language']) && !isset($variables['options']['attributes']['hreflang'])) {
- $variables['options']['attributes']['hreflang'] = $variables['options']['language']->id;
+ if (!empty($options['language']) && !isset($options['attributes']['hreflang'])) {
+ $options['attributes']['hreflang'] = $options['language']->id;
}
// Set the "active" class if the 'set_active_class' option is not empty.
- if (!empty($variables['options']['set_active_class'])) {
+ if (!empty($options['set_active_class'])) {
// Add a "data-drupal-link-query" attribute to let the
// drupal.active-link library know the query in a standardized manner.
- if (!empty($variables['options']['query'])) {
- $query = $variables['options']['query'];
+ if (!empty($options['query'])) {
+ $query = $options['query'];
ksort($query);
- $variables['options']['attributes']['data-drupal-link-query'] = Json::encode($query);
+ $options['attributes']['data-drupal-link-query'] = Json::encode($query);
}
// Add a "data-drupal-link-system-path" attribute to let the
// drupal.active-link library know the path in a standardized manner.
- if (!isset($variables['options']['attributes']['data-drupal-link-system-path'])) {
- $path = $this->urlGenerator->getPathFromRoute($route_name, $parameters);
- $variables['options']['attributes']['data-drupal-link-system-path'] = $this->aliasManager->getSystemPath($path);
+ if (!isset($options['attributes']['data-drupal-link-system-path'])) {
+ $options['attributes']['data-drupal-link-system-path'] = $this->aliasManager->getSystemPath($url->getInternalPath());
}
}
// Remove all HTML and PHP tags from a tooltip, calling expensive strip_tags()
// only when a quick strpos() gives suspicion tags are present.
- if (isset($variables['options']['attributes']['title']) && strpos($variables['options']['attributes']['title'], '<') !== FALSE) {
- $variables['options']['attributes']['title'] = strip_tags($variables['options']['attributes']['title']);
+ if (isset($options['attributes']['title']) && strpos($options['attributes']['title'], '<') !== FALSE) {
+ $options['attributes']['title'] = strip_tags($options['attributes']['title']);
}
+ // Update the options before allowing altering.
+ $url->setOptions($options);
+
// Allow other modules to modify the structure of the link.
- $this->moduleHandler->alter('link', $variables);
+ $this->moduleHandler->alter('link', $text, $url);
// Move attributes out of options. generateFromRoute(() doesn't need them.
- $attributes = new Attribute($variables['options']['attributes']);
- unset($variables['options']['attributes']);
+ $attributes = new Attribute($options['attributes']);
+ unset($options['attributes']);
+ $url->setOptions($options);
// The result of the url generator is a plain-text URL. Because we are using
// it here in an HTML argument context, we need to encode it properly.
- $url = String::checkPlain($this->urlGenerator->generateFromRoute($variables['route_name'], $variables['parameters'], $variables['options']));
+ $url = String::checkPlain($url->toString());
// Sanitize the link text if necessary.
- $text = $variables['options']['html'] ? $variables['text'] : String::checkPlain($variables['text']);
+ $text = $options['html'] ? $text : String::checkPlain($text);
return '' . $text . '';
}
+ /**
+ * {@inheritdoc}
+ *
+ * For anonymous users, the "active" class will be calculated on the server,
+ * because most sites serve each anonymous user the same cached page anyway.
+ * For authenticated users, the "active" class will be calculated on the
+ * client (through JavaScript), only data- attributes are added to links to
+ * prevent breaking the render cache. The JavaScript is added in
+ * system_page_build().
+ *
+ * @see system_page_build()
+ */
+ public function generate($text, $route_name, array $parameters = array(), array $options = array()) {
+ $url = new Url($route_name, $parameters, $options);
+ $url->setUrlGenerator($this->urlGenerator);
+ return $this->generateFromUrl($text, $url);
+ }
+
}
diff --git a/core/lib/Drupal/Core/Utility/LinkGeneratorInterface.php b/core/lib/Drupal/Core/Utility/LinkGeneratorInterface.php
index 02e31af..851100d 100644
--- a/core/lib/Drupal/Core/Utility/LinkGeneratorInterface.php
+++ b/core/lib/Drupal/Core/Utility/LinkGeneratorInterface.php
@@ -7,6 +7,8 @@
namespace Drupal\Core\Utility;
+use Drupal\Core\Url;
+
/**
* Defines an interface for generating links from route names and parameters.
*/
@@ -78,6 +80,19 @@
public function generate($text, $route_name, array $parameters = array(), array $options = array());
/**
+ * Renders a link to a URL.
+ *
+ * @param string $text
+ * The link text for the anchor tag as a translated string.
+ * @param \Drupal\Core\Url $url
+ * The URL object used for the link.
+ *
+ * @return string
+ * An HTML string containing a link to the given route and parameters.
+ */
+ public function generateFromUrl($text, Url $url);
+
+ /**
* Returns information for the currently active route.
*
* @return array
diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Form/OpmlFeedAdd.php b/core/modules/aggregator/lib/Drupal/aggregator/Form/OpmlFeedAdd.php
index b370063..f26b395 100644
--- a/core/modules/aggregator/lib/Drupal/aggregator/Form/OpmlFeedAdd.php
+++ b/core/modules/aggregator/lib/Drupal/aggregator/Form/OpmlFeedAdd.php
@@ -8,7 +8,7 @@
namespace Drupal\aggregator\Form;
use Drupal\aggregator\FeedStorageControllerInterface;
-use Drupal\Component\Utility\Url;
+use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\Entity\Query\QueryFactory;
use Drupal\Core\Form\FormBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -158,7 +158,7 @@ public function submitForm(array &$form, array &$form_state) {
// @todo Move this functionality to a processor.
foreach ($feeds as $feed) {
// Ensure URL is valid.
- if (!Url::isValid($feed['url'], TRUE)) {
+ if (!UrlHelper::isValid($feed['url'], TRUE)) {
drupal_set_message($this->t('The URL %url is invalid.', array('%url' => $feed['url'])), 'warning');
continue;
}
diff --git a/core/modules/contextual/contextual.module b/core/modules/contextual/contextual.module
index 3fd2cb9..77e240f 100644
--- a/core/modules/contextual/contextual.module
+++ b/core/modules/contextual/contextual.module
@@ -5,7 +5,7 @@
* Adds contextual links to perform actions related to elements on a page.
*/
-use Drupal\Component\Utility\Url;
+use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\Template\Attribute;
/**
@@ -329,8 +329,8 @@ function contextual_contextual_links_view_alter(&$element, $items) {
function _contextual_links_to_id($contextual_links) {
$ids = array();
foreach ($contextual_links as $group => $args) {
- $route_parameters = Url::buildQuery($args['route_parameters']);
- $metadata = Url::buildQuery((isset($args['metadata'])) ? $args['metadata'] : array());
+ $route_parameters = UrlHelper::buildQuery($args['route_parameters']);
+ $metadata = UrlHelper::buildQuery((isset($args['metadata'])) ? $args['metadata'] : array());
$ids[] = "{$group}:{$route_parameters}:{$metadata}";
}
return implode('|', $ids);
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/FieldUI.php b/core/modules/field_ui/lib/Drupal/field_ui/FieldUI.php
index c0ed669..d6d2a2d 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/FieldUI.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldUI.php
@@ -7,7 +7,7 @@
namespace Drupal\field_ui;
-use Drupal\Component\Utility\Url;
+use Drupal\Component\Utility\UrlHelper;
/**
* Static service container wrapper for Field UI.
@@ -59,7 +59,7 @@ public static function getNextDestination(array $destinations) {
$next_destination['options']['query']['destinations'] = $destinations;
}
else {
- $options = Url::parse($next_destination);
+ $options = UrlHelper::parse($next_destination);
if ($destinations) {
$options['query']['destinations'] = $destinations;
}
diff --git a/core/modules/image/lib/Drupal/image/Entity/ImageStyle.php b/core/modules/image/lib/Drupal/image/Entity/ImageStyle.php
index 57869d4..286f1e8 100644
--- a/core/modules/image/lib/Drupal/image/Entity/ImageStyle.php
+++ b/core/modules/image/lib/Drupal/image/Entity/ImageStyle.php
@@ -13,7 +13,7 @@
use Drupal\image\ImageEffectInterface;
use Drupal\image\ImageStyleInterface;
use Drupal\Component\Utility\Crypt;
-use Drupal\Component\Utility\Url;
+use Drupal\Component\Utility\UrlHelper;
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
/**
@@ -225,7 +225,7 @@ public function buildUrl($path, $clean_urls = NULL) {
$file_url = file_create_url($uri);
// Append the query string with the token, if necessary.
if ($token_query) {
- $file_url .= (strpos($file_url, '?') !== FALSE ? '&' : '?') . Url::buildQuery($token_query);
+ $file_url .= (strpos($file_url, '?') !== FALSE ? '&' : '?') . UrlHelper::buildQuery($token_query);
}
return $file_url;
diff --git a/core/modules/link/lib/Drupal/link/Plugin/Field/FieldFormatter/LinkFormatter.php b/core/modules/link/lib/Drupal/link/Plugin/Field/FieldFormatter/LinkFormatter.php
index ef8db96..ef86eaf 100644
--- a/core/modules/link/lib/Drupal/link/Plugin/Field/FieldFormatter/LinkFormatter.php
+++ b/core/modules/link/lib/Drupal/link/Plugin/Field/FieldFormatter/LinkFormatter.php
@@ -7,7 +7,7 @@
namespace Drupal\link\Plugin\Field\FieldFormatter;
-use Drupal\Component\Utility\Url;
+use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\FieldItemInterface;
use Drupal\Core\Field\FormatterBase;
@@ -169,7 +169,7 @@ protected function buildLink(FieldItemInterface $item) {
$settings = $this->getSettings();
// Split out the link into the parts required for url(): path and options.
- $parsed_url = Url::parse($item->url);
+ $parsed_url = UrlHelper::parse($item->url);
$result = array(
'path' => $parsed_url['path'],
'options' => array(
diff --git a/core/modules/menu_link/lib/Drupal/menu_link/Entity/MenuLink.php b/core/modules/menu_link/lib/Drupal/menu_link/Entity/MenuLink.php
index 6d70014..d5d358b 100644
--- a/core/modules/menu_link/lib/Drupal/menu_link/Entity/MenuLink.php
+++ b/core/modules/menu_link/lib/Drupal/menu_link/Entity/MenuLink.php
@@ -9,7 +9,9 @@
use Drupal\Core\Entity\Entity;
use Drupal\Core\Entity\EntityStorageControllerInterface;
+use Drupal\Core\Url;
use Drupal\menu_link\MenuLinkInterface;
+use Symfony\Component\Routing\Exception\ResourceNotFoundException;
use Symfony\Component\Routing\Route;
/**
@@ -461,6 +463,10 @@ public function preSave(EntityStorageControllerInterface $storage_controller) {
// This is the easiest way to handle the unique internal path '',
// since a path marked as external does not need to match a route.
$this->external = (url_is_external($this->link_path) || $this->link_path == '') ? 1 : 0;
+ if ($this->link_path == '') {
+ $this->route_name = '';
+ $this->route_parameters = array();
+ }
// Try to find a parent link. If found, assign it and derive its menu.
$parent = $this->findParent($storage_controller);
@@ -505,13 +511,20 @@ public function preSave(EntityStorageControllerInterface $storage_controller) {
// Find the route_name.
if (!isset($this->route_name)) {
- if (!$this->external && $result = \Drupal::service('router.matcher.final_matcher')->findRouteNameParameters($this->link_path)) {
- list($this->route_name, $this->route_parameters) = $result;
- }
- else {
- $this->route_name = '';
- $this->route_parameters = array();
+ $route_name = '';
+ $route_parameters = array();
+ if (!$this->external) {
+ try {
+ $url = Url::createFromPath($this->link_path);
+ $route_name = $url->getRouteName();
+ $route_parameters = $url->getRouteParameters();
+ }
+ catch (ResourceNotFoundException $e) {
+ }
}
+
+ $this->route_name = $route_name;
+ $this->route_parameters = $route_parameters;
}
elseif (empty($this->link_path)) {
$this->link_path = \Drupal::urlGenerator()->getPathFromRoute($this->route_name, $this->route_parameters);
diff --git a/core/modules/shortcut/lib/Drupal/shortcut/Entity/Shortcut.php b/core/modules/shortcut/lib/Drupal/shortcut/Entity/Shortcut.php
index 59f8287..6784bd0 100644
--- a/core/modules/shortcut/lib/Drupal/shortcut/Entity/Shortcut.php
+++ b/core/modules/shortcut/lib/Drupal/shortcut/Entity/Shortcut.php
@@ -11,7 +11,9 @@
use Drupal\Core\Entity\EntityStorageControllerInterface;
use Drupal\Core\Field\FieldDefinition;
use Drupal\Core\Routing\UrlMatcher;
+use Drupal\Core\Url;
use Drupal\shortcut\ShortcutInterface;
+use Symfony\Component\Routing\Exception\ResourceNotFoundException;
/**
* Defines the shortcut entity class.
@@ -124,9 +126,12 @@ public static function preCreate(EntityStorageControllerInterface $storage_contr
public function preSave(EntityStorageControllerInterface $storage_controller) {
parent::preSave($storage_controller);
- if ($route_info = \Drupal::service('router.matcher.final_matcher')->findRouteNameParameters($this->path->value)) {
- $this->setRouteName($route_info[0]);
- $this->setRouteParams($route_info[1]);
+ try {
+ $url = Url::createFromPath($this->path->value);
+ $this->setRouteName($url->getRouteName());
+ $this->setRouteParams($url->getRouteParameters());
+ }
+ catch (ResourceNotFoundException $e) {
}
}
diff --git a/core/modules/shortcut/shortcut.module b/core/modules/shortcut/shortcut.module
index a988cf4..381ec2b 100644
--- a/core/modules/shortcut/shortcut.module
+++ b/core/modules/shortcut/shortcut.module
@@ -5,7 +5,7 @@
* Allows users to manage customizable lists of shortcut links.
*/
-use Drupal\Core\Routing\UrlMatcher;
+use Drupal\Core\Url;
use Drupal\shortcut\ShortcutSetInterface;
use Symfony\Component\HttpFoundation\Request;
@@ -389,7 +389,7 @@ function shortcut_preprocess_page(&$variables) {
// pages).
if (shortcut_set_edit_access() && ($item = menu_get_item()) && $item['access']) {
$link = current_path();
- if (!($route_info = \Drupal::service('router.matcher.final_matcher')->findRouteNameParameters($link))) {
+ if (!($url = Url::createFromPath($link))) {
// Bail out early if we couldn't find a matching route.
return;
}
@@ -405,7 +405,7 @@ function shortcut_preprocess_page(&$variables) {
// Check if $link is already a shortcut and set $link_mode accordingly.
$shortcuts = \Drupal::entityManager()->getStorageController('shortcut')->loadByProperties(array('shortcut_set' => $shortcut_set->id()));
foreach ($shortcuts as $shortcut) {
- if ($shortcut->getRouteName() == $route_info[0] && $shortcut->getRouteParams() == $route_info[1]) {
+ if ($shortcut->getRouteName() == $url->getRouteName() && $shortcut->getRouteParams() == $url->getRouteParameters()) {
$shortcut_id = $shortcut->id();
break;
}
diff --git a/core/modules/system/lib/Drupal/system/Tests/Common/XssUnitTest.php b/core/modules/system/lib/Drupal/system/Tests/Common/XssUnitTest.php
index bcafe30..0f47192 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Common/XssUnitTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Common/XssUnitTest.php
@@ -7,7 +7,7 @@
namespace Drupal\system\Tests\Common;
-use Drupal\Component\Utility\Url;
+use Drupal\Component\Utility\UrlHelper;
use Drupal\simpletest\DrupalUnitTestBase;
/**
@@ -54,12 +54,12 @@ function testT() {
*/
function testBadProtocolStripping() {
// Ensure that check_url() strips out harmful protocols, and encodes for
- // HTML. Ensure \Drupal\Component\Utility\Url::stripDangerousProtocols() can
+ // HTML. Ensure \Drupal\Component\Utility\UrlHelper::stripDangerousProtocols() can
// be used to return a plain-text string stripped of harmful protocols.
$url = 'javascript:http://www.example.com/?x=1&y=2';
$expected_plain = 'http://www.example.com/?x=1&y=2';
$expected_html = 'http://www.example.com/?x=1&y=2';
$this->assertIdentical(check_url($url), $expected_html, 'check_url() filters a URL and encodes it for HTML.');
- $this->assertIdentical(Url::stripDangerousProtocols($url), $expected_plain, '\Drupal\Component\Utility\Url::stripDangerousProtocols() filters a URL and returns plain text.');
+ $this->assertIdentical(UrlHelper::stripDangerousProtocols($url), $expected_plain, '\Drupal\Component\Utility\UrlHelper::stripDangerousProtocols() filters a URL and returns plain text.');
}
}
diff --git a/core/modules/system/lib/Drupal/system/Tests/Routing/RouterPermissionTest.php b/core/modules/system/lib/Drupal/system/Tests/Routing/RouterPermissionTest.php
index 060303a..3f3a1d8 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Routing/RouterPermissionTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Routing/RouterPermissionTest.php
@@ -37,17 +37,10 @@ public function testPermissionAccess() {
$path = 'router_test/test7';
$this->drupalGet($path);
$this->assertResponse(403, "Access denied for a route where we don't have a permission");
- // An invalid path should throw an exception.
+
$map = array();
$route = \Drupal::service('router.route_provider')->getRouteByName('router_test.7');
- try {
- menu_item_route_access($route, $path . 'invalid', $map);
- $exception = FALSE;
- }
- catch (ResourceNotFoundException $e) {
- $exception = TRUE;
- }
- $this->assertTrue($exception, 'A ResourceNotFoundException was thrown while checking access for an invalid route.');
+ $this->assertFalse(menu_item_route_access($route, $path . 'invalid', $map));
$this->drupalGet('router_test/test8');
$this->assertResponse(403, 'Access denied by default if no access specified');
diff --git a/core/modules/system/system.api.php b/core/modules/system/system.api.php
index 6c83611..42159d6 100644
--- a/core/modules/system/system.api.php
+++ b/core/modules/system/system.api.php
@@ -5,6 +5,7 @@
* Hooks provided by Drupal core and the System module.
*/
+use Drupal\Core\Url;
use Drupal\Core\Utility\UpdateException;
/**
@@ -3157,50 +3158,35 @@ function hook_filetransfer_info_alter(&$filetransfer_info) {
/**
* Alter the parameters for links.
*
- * @param array $variables
- * An associative array of variables defining a link. The link may be either a
- * "route link" using \Drupal\Core\Utility\LinkGenerator::link(), which is
- * exposed as the 'link_generator' service or a link generated by l(). If the
- * link is a "route link", 'route_name' will be set, otherwise 'path' will be
- * set. The following keys can be altered:
- * - text: The link text for the anchor tag as a translated string.
- * - url_is_active: Whether or not the link points to the currently active
- * URL.
- * - path: If this link is being generated by l(), this system path, relative
- * path, or external URL will be passed to url() to generate the href
- * attribute for this link.
- * - route_name: The name of the route to use to generate the link, if
- * this is a "route link".
- * - parameters: Any parameters needed to render the route path pattern, if
- * this is a "route link".
- * - options: An associative array of additional options that will be passed
- * to either \Drupal\Core\Routing\UrlGenerator::generateFromPath() or
- * \Drupal\Core\Routing\UrlGenerator::generateFromRoute() to generate the
- * href attribute for this link, and also used when generating the link.
- * Defaults to an empty array. It may contain the following elements:
- * - 'query': An array of query key/value-pairs (without any URL-encoding) to
- * append to the URL.
- * - absolute: Whether to force the output to be an absolute link (beginning
- * with http:). Useful for links that will be displayed outside the site,
- * such as in an RSS feed. Defaults to FALSE.
- * - language: An optional language object. May affect the rendering of
- * the anchor tag, such as by adding a language prefix to the path.
- * - attributes: An associative array of HTML attributes to apply to the
- * anchor tag. If element 'class' is included, it must be an array; 'title'
- * must be a string; other elements are more flexible, as they just need
- * to work as an argument for the constructor of the class
- * Drupal\Core\Template\Attribute($options['attributes']).
- * - html: Whether or not HTML should be allowed as the link text. If FALSE,
- * the text will be run through
- * \Drupal\Component\Utility\String::checkPlain() before being output.
+ * @param string $text
+ * The link text for the anchor tag as a translated string.
+ * @param \Drupal\Core\Url $url
+ * The URL object used for the link. Url::getOptions() can contain many
+ * keys, but the following are guaranteed to exist:
+ * - query: An array of query key/value-pairs (without any URL-encoding) to
+ * append to the URL.
+ * - absolute: Whether to force the output to be an absolute link (beginning
+ * with http:). Useful for links that will be displayed outside the site,
+ * such as in an RSS feed. Defaults to FALSE.
+ * - language: An optional language object. May affect the rendering of the
+ * anchor tag, such as by adding a language prefix to the path.
+ * - attributes: An associative array of HTML attributes to apply to the
+ * anchor tag. If element 'class' is included, it must be an array; 'title'
+ * must be a string; other elements are more flexible, as they just need
+ * to work as an argument for the constructor of the class
+ * \Drupal\Core\Template\Attribute($options['attributes']).
+ * - html: Whether or not HTML should be allowed as the link text. If FALSE,
+ * the text will be run through
+ * \Drupal\Component\Utility\String::checkPlain() before being output.
+ * - set_active_class: Whether to set the 'active' class or not.
*
* @see \Drupal\Core\Routing\UrlGenerator::generateFromPath()
* @see \Drupal\Core\Routing\UrlGenerator::generateFromRoute()
*/
-function hook_link_alter(&$variables) {
+function hook_link_alter(&$text, Url $url) {
// Add a warning to the end of route links to the admin section.
- if (isset($variables['route_name']) && strpos($variables['route_name'], 'admin') !== FALSE) {
- $variables['text'] .= ' (Warning!)';
+ if (strpos($url->getRouteName(), 'admin') !== FALSE) {
+ $text .= ' (Warning!)';
}
}
diff --git a/core/modules/system/system.install b/core/modules/system/system.install
index 25f75c7..6ad4f6c 100644
--- a/core/modules/system/system.install
+++ b/core/modules/system/system.install
@@ -1761,7 +1761,7 @@ function system_update_8034() {
* Move filter_allowed_protocols variable to config.
*
* This config is provided now by the system module because it is used by
- * \Drupal\Component\Utility\Url::stripDangerousProtocols() and must to be
+ * \Drupal\Component\Utility\UrlHelper::stripDangerousProtocols() and must to be
* available before the filter module be installed.
*
* @ingroup config_upgrade
diff --git a/core/modules/views/lib/Drupal/views/Controller/ViewAjaxController.php b/core/modules/views/lib/Drupal/views/Controller/ViewAjaxController.php
index 307d63f..8df3017 100644
--- a/core/modules/views/lib/Drupal/views/Controller/ViewAjaxController.php
+++ b/core/modules/views/lib/Drupal/views/Controller/ViewAjaxController.php
@@ -7,7 +7,7 @@
namespace Drupal\views\Controller;
-use Drupal\Component\Utility\Url;
+use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\Ajax\ReplaceCommand;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityStorageControllerInterface;
@@ -115,7 +115,7 @@ public function ajaxView(Request $request) {
// Overwrite the destination.
// @see drupal_get_destination()
$origin_destination = $path;
- $query = Url::buildQuery($request->query->all());
+ $query = UrlHelper::buildQuery($request->query->all());
if ($query != '') {
$origin_destination .= '?' . $query;
}
diff --git a/core/modules/views/lib/Drupal/views/Form/ViewsForm.php b/core/modules/views/lib/Drupal/views/Form/ViewsForm.php
index 3e409f7..cc01f8d 100644
--- a/core/modules/views/lib/Drupal/views/Form/ViewsForm.php
+++ b/core/modules/views/lib/Drupal/views/Form/ViewsForm.php
@@ -7,7 +7,7 @@
namespace Drupal\views\Form;
-use Drupal\Component\Utility\Url;
+use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\Controller\ControllerResolverInterface;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\DependencyInjection\DependencySerialization;
@@ -126,7 +126,7 @@ public function buildForm(array $form, array &$form_state, ViewExecutable $view
$form = array();
$query = $this->request->query->all();
- $query = Url::filterQueryParameters($query, array(), '');
+ $query = UrlHelper::filterQueryParameters($query, array(), '');
$form['#action'] = $this->urlGenerator->generateFromPath($view->getUrl(), array('query' => $query));
// Tell the preprocessor whether it should hide the header, footer, pager...
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/HandlerBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/HandlerBase.php
index 1b8c4ce..1d3e9c7 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/HandlerBase.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/HandlerBase.php
@@ -9,7 +9,7 @@
use Drupal\Component\Utility\String;
use Drupal\Component\Utility\Unicode;
-use Drupal\Component\Utility\Url;
+use Drupal\Component\Utility\UrlHelper;
use Drupal\Component\Utility\Xss;
use Drupal\Core\Session\AccountInterface;
use Drupal\views\Plugin\views\display\DisplayPluginBase;
@@ -230,7 +230,7 @@ public function sanitizeValue($value, $type = NULL) {
$value = Xss::filterAdmin($value);
break;
case 'url':
- $value = String::checkPlain(Url::stripDangerousProtocols($value));
+ $value = String::checkPlain(UrlHelper::stripDangerousProtocols($value));
break;
default:
$value = String::checkPlain($value);
diff --git a/core/modules/views_ui/lib/Drupal/views_ui/ViewEditFormController.php b/core/modules/views_ui/lib/Drupal/views_ui/ViewEditFormController.php
index 05c11cc..2bf6b69 100644
--- a/core/modules/views_ui/lib/Drupal/views_ui/ViewEditFormController.php
+++ b/core/modules/views_ui/lib/Drupal/views_ui/ViewEditFormController.php
@@ -11,6 +11,7 @@
use Drupal\Core\Ajax\HtmlCommand;
use Drupal\Core\Ajax\ReplaceCommand;
use Drupal\Component\Utility\NestedArray;
+use Drupal\Core\Url;
use Drupal\user\TempStoreFactory;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -271,10 +272,10 @@ public function submit(array $form, array &$form_state) {
unset($displays[$id]);
// Redirect the user to the renamed display to be sure that the page itself exists and doesn't throw errors.
- $form_state['redirect_route'] = array(
- 'route_name' => 'views_ui.edit_display',
- 'route_parameters' => array('view' => $view->id(), 'display_id' => $new_id),
- );
+ $form_state['redirect_route'] = new Url('views_ui.edit_display', array(
+ 'view' => $view->id(),
+ 'display_id' => $new_id,
+ ));
}
}
$view->set('display', $displays);
@@ -321,7 +322,7 @@ public function cancel(array $form, array &$form_state) {
// Remove this view from cache so edits will be lost.
$view = $this->entity;
$this->tempStore->delete($view->id());
- $form_state['redirect_route']['route_name'] = 'views_ui.list';
+ $form_state['redirect_route'] = new Url('views_ui.list');
}
/**
@@ -568,10 +569,10 @@ public function submitDisplayUndoDelete($form, &$form_state) {
$view->cacheSet();
// Redirect to the top-level edit page.
- $form_state['redirect_route'] = array(
- 'route_name' => 'views_ui.edit_display',
- 'route_parameters' => array('view' => $view->id(), 'display_id' => $id),
- );
+ $form_state['redirect_route'] = new Url('views_ui.edit_display', array(
+ 'view' => $view->id(),
+ 'display_id' => $id,
+ ));
}
/**
@@ -587,10 +588,10 @@ public function submitDisplayEnable($form, &$form_state) {
$view->cacheSet();
// Redirect to the top-level edit page.
- $form_state['redirect_route'] = array(
- 'route_name' => 'views_ui.edit_display',
- 'route_parameters' => array('view' => $view->id(), 'display_id' => $id),
- );
+ $form_state['redirect_route'] = new Url('views_ui.edit_display', array(
+ 'view' => $view->id(),
+ 'display_id' => $id,
+ ));
}
/**
@@ -605,10 +606,10 @@ public function submitDisplayDisable($form, &$form_state) {
$view->cacheSet();
// Redirect to the top-level edit page.
- $form_state['redirect_route'] = array(
- 'route_name' => 'views_ui.edit_display',
- 'route_parameters' => array('view' => $view->id(), 'display_id' => $id),
- );
+ $form_state['redirect_route'] = new Url('views_ui.edit_display', array(
+ 'view' => $view->id(),
+ 'display_id' => $id,
+ ));
}
/**
@@ -626,10 +627,9 @@ public function submitDisplayDelete($form, &$form_state) {
// Redirect to the top-level edit page. The first remaining display will
// become the active display.
- $form_state['redirect_route'] = array(
- 'route_name' => 'views_ui.edit',
- 'route_parameters' => array('view' => $view->id()),
- );
+ $form_state['redirect_route'] = new Url('views_ui.edit', array(
+ 'view' => $view->id(),
+ ));
}
/**
@@ -802,10 +802,10 @@ public function submitDisplayDuplicate($form, &$form_state) {
$view->cacheSet();
// Redirect to the new display's edit page.
- $form_state['redirect_route'] = array(
- 'route_name' => 'views_ui.edit_display',
- 'route_parameters' => array('view' => $view->id(), 'display_id' => $new_display_id),
- );
+ $form_state['redirect_route'] = new Url('views_ui.edit_display', array(
+ 'view' => $view->id(),
+ 'display_id' => $new_display_id,
+ ));
}
/**
@@ -824,10 +824,10 @@ public function submitDisplayAdd($form, &$form_state) {
$view->cacheSet();
// Redirect to the new display's edit page.
- $form_state['redirect_route'] = array(
- 'route_name' => 'views_ui.edit_display',
- 'route_parameters' => array('view' => $view->id(), 'display_id' => $display_id),
- );
+ $form_state['redirect_route'] = new Url('views_ui.edit_display', array(
+ 'view' => $view->id(),
+ 'display_id' => $display_id,
+ ));
}
/**
@@ -860,10 +860,10 @@ public function submitCloneDisplayAsType($form, &$form_state) {
$view->cacheSet();
// Redirect to the new display's edit page.
- $form_state['redirect_route'] = array(
- 'route_name' => 'views_ui.edit_display',
- 'route_parameters' => array('view' => $view->id(), 'display_id' => $new_display_id),
- );
+ $form_state['redirect_route'] = new Url('views_ui.edit_display', array(
+ 'view' => $view->id(),
+ 'display_id' => $new_display_id,
+ ));
}
/**
diff --git a/core/tests/Drupal/Tests/Component/Utility/UrlTest.php b/core/tests/Drupal/Tests/Component/Utility/UrlHelperTest.php
similarity index 89%
rename from core/tests/Drupal/Tests/Component/Utility/UrlTest.php
rename to core/tests/Drupal/Tests/Component/Utility/UrlHelperTest.php
index 4dec865..df970aa 100644
--- a/core/tests/Drupal/Tests/Component/Utility/UrlTest.php
+++ b/core/tests/Drupal/Tests/Component/Utility/UrlHelperTest.php
@@ -2,13 +2,12 @@
/**
* @file
- * Contains \Drupal\Tests\Component\Utility\UrlTest.
+ * Contains \Drupal\Tests\Component\Utility\UrlHelperTest.
*/
namespace Drupal\Tests\Component\Utility;
-
-use Drupal\Component\Utility\Url;
+use Drupal\Component\Utility\UrlHelper;
use Drupal\Component\Utility\String;
use Drupal\Tests\UnitTestCase;
@@ -17,12 +16,12 @@
*
* @see \Drupal\Component\Utility\Url
*/
-class UrlTest extends UnitTestCase {
+class UrlHelperTest extends UnitTestCase {
public static function getInfo() {
return array(
- 'name' => t('Url Tests'),
- 'description' => t('Tests the Url utility class.'),
+ 'name' => t('UrlHelper Tests'),
+ 'description' => t('Tests the UrlHelper utility class.'),
'group' => t('Path API'),
);
}
@@ -43,7 +42,7 @@ public function providerTestBuildQuery() {
}
/**
- * Tests Url::buildQuery().
+ * Tests UrlHelper::buildQuery().
*
* @param array $query
* The array of query parameters.
@@ -55,7 +54,7 @@ public function providerTestBuildQuery() {
* @dataProvider providerTestBuildQuery
*/
public function testBuildQuery($query, $expected, $message) {
- $this->assertEquals(Url::buildQuery($query), $expected, $message);
+ $this->assertEquals(UrlHelper::buildQuery($query), $expected, $message);
}
/**
@@ -100,7 +99,7 @@ public function providerTestValidAbsoluteData() {
*/
public function testValidAbsolute($url, $scheme) {
$test_url = $scheme . '://' . $url;
- $valid_url = Url::isValid($test_url, TRUE);
+ $valid_url = UrlHelper::isValid($test_url, TRUE);
$this->assertTrue($valid_url, String::format('@url is a valid URL.', array('@url' => $test_url)));
}
@@ -130,7 +129,7 @@ public function providerTestInvalidAbsolute() {
*/
public function testInvalidAbsolute($url, $scheme) {
$test_url = $scheme . '://' . $url;
- $valid_url = Url::isValid($test_url, TRUE);
+ $valid_url = UrlHelper::isValid($test_url, TRUE);
$this->assertFalse($valid_url, String::format('@url is NOT a valid URL.', array('@url' => $test_url)));
}
@@ -163,7 +162,7 @@ public function providerTestValidRelativeData() {
*/
public function testValidRelative($url, $prefix) {
$test_url = $prefix . $url;
- $valid_url = Url::isValid($test_url);
+ $valid_url = UrlHelper::isValid($test_url);
$this->assertTrue($valid_url, String::format('@url is a valid URL.', array('@url' => $test_url)));
}
@@ -193,7 +192,7 @@ public function providerTestInvalidRelativeData() {
*/
public function testInvalidRelative($url, $prefix) {
$test_url = $prefix . $url;
- $valid_url = Url::isValid($test_url);
+ $valid_url = UrlHelper::isValid($test_url);
$this->assertFalse($valid_url, String::format('@url is NOT a valid URL.', array('@url' => $test_url)));
}
@@ -210,10 +209,10 @@ public function testInvalidRelative($url, $prefix) {
*
* @dataProvider providerTestFilterQueryParameters
*
- * @see \Drupal\Component\Utility\Url::filterQueryParameters().
+ * @see \Drupal\Component\Utility\UrlHelper::filterQueryParameters().
*/
public function testFilterQueryParameters($query, $exclude, $expected) {
- $filtered = Url::filterQueryParameters($query, $exclude);
+ $filtered = UrlHelper::filterQueryParameters($query, $exclude);
$this->assertEquals($expected, $filtered, 'The query was not properly filtered.');
}
@@ -249,10 +248,10 @@ public static function providerTestFilterQueryParameters() {
*
* @dataProvider providerTestParse
*
- * @see \Drupal\Component\Utility\Url::parse()
+ * @see \Drupal\Component\Utility\UrlHelper::parse()
*/
public function testParse($url, $expected) {
- $parsed = Url::parse($url);
+ $parsed = UrlHelper::parse($url);
$this->assertEquals($expected, $parsed, 'The url was not properly parsed.');
}
@@ -302,12 +301,12 @@ public static function providerTestParse() {
* @param string $expected
* The expected encoded path.
*
- * @see \Drupal\Component\Utility\Url::encodePath().
+ * @see \Drupal\Component\Utility\UrlHelper::encodePath().
*
* @dataProvider providerTestEncodePath
*/
public function testEncodePath($path, $expected) {
- $encoded = Url::encodePath($path);
+ $encoded = UrlHelper::encodePath($path);
$this->assertEquals($expected, $encoded);
}
@@ -331,12 +330,12 @@ public static function providerTestEncodePath() {
* @param bool $expected
* Expected result.
*
- * @see \Drupal\Component\Utility\Url::isExternal()
+ * @see \Drupal\Component\Utility\UrlHelper::isExternal()
*
* @dataProvider providerTestIsExternal
*/
public function testIsExternal($path, $expected) {
- $isExternal = Url::isExternal($path);
+ $isExternal = UrlHelper::isExternal($path);
$this->assertEquals($expected, $isExternal);
}
@@ -366,8 +365,8 @@ public static function providerTestIsExternal() {
* @dataProvider providerTestFilterBadProtocol
*/
public function testFilterBadProtocol($uri, $expected, $protocols) {
- Url::setAllowedProtocols($protocols);
- $filtered = Url::filterBadProtocol($uri);
+ UrlHelper::setAllowedProtocols($protocols);
+ $filtered = UrlHelper::filterBadProtocol($uri);
$this->assertEquals($expected, $filtered);
}
@@ -398,13 +397,13 @@ public static function providerTestFilterBadProtocol() {
* @param array $protocols
* Protocols to allow.
*
- * @see \Drupal\Component\Utility\Url::stripDangerousProtocols()
+ * @see \Drupal\Component\Utility\UrlHelper::stripDangerousProtocols()
*
* @dataProvider providerTestStripDangerousProtocols
*/
public function testStripDangerousProtocols($uri, $expected, $protocols) {
- Url::setAllowedProtocols($protocols);
- $stripped = Url::stripDangerousProtocols($uri);
+ UrlHelper::setAllowedProtocols($protocols);
+ $stripped = UrlHelper::stripDangerousProtocols($uri);
$this->assertEquals($expected, $stripped);
}
diff --git a/core/tests/Drupal/Tests/Component/Utility/XssTest.php b/core/tests/Drupal/Tests/Component/Utility/XssTest.php
index 2614c5d..f58e353 100644
--- a/core/tests/Drupal/Tests/Component/Utility/XssTest.php
+++ b/core/tests/Drupal/Tests/Component/Utility/XssTest.php
@@ -8,7 +8,7 @@
namespace Drupal\Tests\Component\Utility;
use Drupal\Component\Utility\String;
-use Drupal\Component\Utility\Url;
+use Drupal\Component\Utility\UrlHelper;
use Drupal\Component\Utility\Xss;
use Drupal\Tests\UnitTestCase;
@@ -53,7 +53,7 @@ protected function setUp() {
'webcal',
'rtsp',
);
- Url::setAllowedProtocols($allowed_protocols);
+ UrlHelper::setAllowedProtocols($allowed_protocols);
}
/**
diff --git a/core/tests/Drupal/Tests/Core/DrupalTest.php b/core/tests/Drupal/Tests/Core/DrupalTest.php
index b37010f..2a9e764 100644
--- a/core/tests/Drupal/Tests/Core/DrupalTest.php
+++ b/core/tests/Drupal/Tests/Core/DrupalTest.php
@@ -7,6 +7,7 @@
namespace Drupal\Tests\Core;
+use Drupal\Core\Url;
use Drupal\Tests\UnitTestCase;
/**
@@ -296,7 +297,30 @@ public function testL() {
->will($this->returnValue('link_html_string'));
$this->setMockContainerService('link_generator', $generator);
- $this->assertInternalType('string', \Drupal::l('Test title', 'test_route', $route_parameters, $options));
+ $link = \Drupal::l('Test title', 'test_route', $route_parameters, $options);
+ $this->assertSame('link_html_string', $link);
+ $this->assertInternalType('string', $link);
+ }
+
+ /**
+ * Tests the l() method.
+ *
+ * @see \Drupal\Core\Utility\LinkGeneratorInterface::generateFromUrl()
+ */
+ public function testLWithUrl() {
+ $route_parameters = array('test_parameter' => 'test');
+ $options = array('test_option' => 'test');
+ $url = new Url('test_route', $route_parameters, $options);
+ $generator = $this->getMock('Drupal\Core\Utility\LinkGeneratorInterface');
+ $generator->expects($this->once())
+ ->method('generateFromUrl')
+ ->with('Test title', $url)
+ ->will($this->returnValue('link_html_string'));
+ $this->setMockContainerService('link_generator', $generator);
+
+ $link = \Drupal::l('Test title', $url);
+ $this->assertSame('link_html_string', $link);
+ $this->assertInternalType('string', $link);
}
/**
diff --git a/core/tests/Drupal/Tests/Core/ExternalUrlTest.php b/core/tests/Drupal/Tests/Core/ExternalUrlTest.php
new file mode 100644
index 0000000..8dd02d3
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/ExternalUrlTest.php
@@ -0,0 +1,191 @@
+ 'Url object (external)',
+ 'description' => 'Tests the \Drupal\Core\Url class with external paths.',
+ 'group' => 'Routing',
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function setUp() {
+ parent::setUp();
+
+ $this->urlGenerator = $this->getMock('Drupal\Core\Routing\UrlGeneratorInterface');
+ $this->urlGenerator->expects($this->any())
+ ->method('generateFromPath')
+ ->will($this->returnCallback(function ($path) {
+ return $path;
+ }));
+
+ $container = new ContainerBuilder();
+ $container->set('url_generator', $this->urlGenerator);
+ \Drupal::setContainer($container);
+ }
+
+ /**
+ * Tests the createFromPath method.
+ *
+ * @covers ::createFromPath()
+ * @covers ::setExternal()
+ */
+ public function testCreateFromPath() {
+ $url = Url::createFromPath($this->path);
+ $this->assertInstanceOf('Drupal\Core\Url', $url);
+ $this->assertTrue($url->isExternal());
+ return $url;
+ }
+
+ /**
+ * Tests the createFromRequest method.
+ *
+ * @covers ::createFromRequest()
+ */
+ public function testCreateFromRequest() {
+ $request = new Request(array(), array(), array('_system_path' => $this->path));
+ $url = Url::createFromRequest($request);
+ $this->assertInstanceOf('Drupal\Core\Url', $url);
+ $this->assertTrue($url->isExternal());
+ }
+
+ /**
+ * Tests the createFromRequest method.
+ *
+ * @covers ::createFromRequest()
+ *
+ * @expectedException \Exception
+ */
+ public function testCreateFromRequestWithoutSystemPath() {
+ $request = new Request();
+ $url = \Drupal\Core\Url::createFromRequest($request);
+ $this->assertNull($url);
+ }
+
+ /**
+ * Tests the isExternal() method.
+ *
+ * @depends testCreateFromPath
+ *
+ * @covers ::isExternal()
+ */
+ public function testIsExternal(\Drupal\Core\Url $url) {
+ $this->assertTrue($url->isExternal());
+ }
+
+ /**
+ * Tests the toString() method.
+ *
+ * @depends testCreateFromPath
+ *
+ * @covers ::toString()
+ */
+ public function testToString(Url $url) {
+ $this->assertSame($this->path, $url->toString());
+ }
+
+ /**
+ * Tests the toArray() method.
+ *
+ * @depends testCreateFromPath
+ *
+ * @covers ::toArray()
+ *
+ * @expectedException \Exception
+ */
+ public function testToArray(Url $url) {
+ $this->assertNull($url->toArray());
+ }
+
+ /**
+ * Tests the getRouteName() method.
+ *
+ * @depends testCreateFromPath
+ *
+ * @covers ::getRouteName()
+ *
+ * @expectedException \Exception
+ */
+ public function testGetRouteName(Url $url) {
+ $this->assertNull($url->getRouteName());
+ }
+
+ /**
+ * Tests the getRouteParameters() method.
+ *
+ * @depends testCreateFromPath
+ *
+ * @covers ::getRouteParameters()
+ *
+ * @expectedException \Exception
+ */
+ public function testGetRouteParameters(Url $url) {
+ $this->assertNull($url->getRouteParameters());
+ }
+
+ /**
+ * Tests the getInternalPath() method.
+ *
+ * @depends testCreateFromPath
+ *
+ * @covers ::getInternalPath()
+ *
+ * @expectedException \Exception
+ */
+ public function testGetInternalPath(\Drupal\Core\Url $url) {
+ $this->assertNull($url->getInternalPath());
+ }
+
+ /**
+ * Tests the getOptions() method.
+ *
+ * @depends testCreateFromPath
+ *
+ * @covers ::getOptions()
+ */
+ public function testGetOptions(\Drupal\Core\Url $url) {
+ $this->assertInternalType('array', $url->getOptions());
+ }
+
+}
diff --git a/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php b/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php
index 0b52a75..4537b6e 100644
--- a/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php
+++ b/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php
@@ -7,8 +7,10 @@
namespace Drupal\Tests\Core\Form {
+use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Form\FormInterface;
+use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
@@ -32,6 +34,17 @@ public static function getInfo() {
}
/**
+ * {@inheritdoc}
+ */
+ public function setUp() {
+ parent::setUp();
+
+ $container = new ContainerBuilder();
+ $container->set('url_generator', $this->urlGenerator);
+ \Drupal::setContainer($container);
+ }
+
+ /**
* Tests the getFormId() method with a string based form ID.
*/
public function testGetFormIdWithString() {
@@ -225,6 +238,7 @@ public function providerTestRedirectWithRouteWithResult() {
return array(
array(array('redirect_route' => array('route_name' => 'test_route_a')), 'test-route'),
array(array('redirect_route' => array('route_name' => 'test_route_b', 'route_parameters' => array('key' => 'value'))), 'test-route/value'),
+ array(array('redirect_route' => new Url('test_route_b', array('key' => 'value'))), 'test-route/value'),
);
}
diff --git a/core/tests/Drupal/Tests/Core/Routing/UrlMatcherTest.php b/core/tests/Drupal/Tests/Core/Routing/UrlMatcherTest.php
deleted file mode 100644
index 450ae85..0000000
--- a/core/tests/Drupal/Tests/Core/Routing/UrlMatcherTest.php
+++ /dev/null
@@ -1,89 +0,0 @@
- 'UrlMatcher',
- 'description' => 'Confirm that the UrlMatcher is functioning properly.',
- 'group' => 'Routing',
- );
- }
-
- /**
- * {@inheritdoc}
- */
- protected function setUp() {
- $this->matcher = new UrlMatcher();
- }
-
- /**
- * Tests the findRouteNameParameters method.
- *
- * @see \Drupal\Core\Routing\UrlMatcher::findRouteNameParameters()
- */
- public function testFindRouteNameParameters() {
- $router = $this->getMock('Symfony\Component\Routing\Matcher\RequestMatcherInterface');
- $container = new ContainerBuilder();
- $container->set('router', $router);
- \Drupal::setContainer($container);
-
- $router->expects($this->at(0))
- ->method('matchRequest')
- ->will($this->returnValue(array(
- RouteObjectInterface::ROUTE_NAME => 'view.frontpage.page_1',
- '_raw_variables' => new ParameterBag(),
- )));
- $router->expects($this->at(1))
- ->method('matchRequest')
- ->will($this->returnValue(array(
- RouteObjectInterface::ROUTE_NAME => 'node_view',
- '_raw_variables' => new ParameterBag(array('node' => '1')),
- )));
- $router->expects($this->at(2))
- ->method('matchRequest')
- ->will($this->returnValue(array(
- RouteObjectInterface::ROUTE_NAME => 'node_edit',
- '_raw_variables' => new ParameterBag(array('node' => '2')),
- )));
- $router->expects($this->at(3))
- ->method('matchRequest')
- ->will($this->throwException(new ResourceNotFoundException()));
-
- $this->assertEquals(array('view.frontpage.page_1', array()), $this->matcher->findRouteNameParameters('node'));
- $this->assertEquals(array('node_view', array('node' => '1')), $this->matcher->findRouteNameParameters('node/1'));
- $this->assertEquals(array('node_edit', array('node' => '2')), $this->matcher->findRouteNameParameters('node/2/edit'));
-
- $this->assertEquals(array(), $this->matcher->findRouteNameParameters('non-existing'));
- }
-
-}
diff --git a/core/tests/Drupal/Tests/Core/UrlTest.php b/core/tests/Drupal/Tests/Core/UrlTest.php
new file mode 100644
index 0000000..8719fd1
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/UrlTest.php
@@ -0,0 +1,250 @@
+ 'Url object (internal)',
+ 'description' => 'Tests the \Drupal\Core\Url class.',
+ 'group' => 'Routing',
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function setUp() {
+ parent::setUp();
+
+ $map = array();
+ $map[] = array('view.frontpage.page_1', array(), array(), '/node');
+ $map[] = array('node_view', array('node' => '1'), array(), '/node/1');
+ $map[] = array('node_edit', array('node' => '2'), array(), '/node/2/edit');
+ $this->map = $map;
+
+ $this->urlGenerator = $this->getMock('Drupal\Core\Routing\UrlGeneratorInterface');
+ $this->urlGenerator->expects($this->any())
+ ->method('generateFromRoute')
+ ->will($this->returnValueMap($this->map));
+
+ $this->router = $this->getMock('Symfony\Component\Routing\RouterInterface');
+ $container = new ContainerBuilder();
+ $container->set('router', $this->router);
+ $container->set('url_generator', $this->urlGenerator);
+ \Drupal::setContainer($container);
+ }
+
+ /**
+ * Tests the createFromPath method.
+ *
+ * @covers ::createFromPath()
+ */
+ public function testCreateFromPath() {
+ $this->router->expects($this->exactly(3))
+ ->method('match')
+ ->will($this->returnValueMap(array(
+ array('/node', array(
+ RouteObjectInterface::ROUTE_NAME => 'view.frontpage.page_1',
+ '_raw_variables' => new ParameterBag(),
+ )),
+ array('/node/1', array(
+ RouteObjectInterface::ROUTE_NAME => 'node_view',
+ '_raw_variables' => new ParameterBag(array('node' => '1')),
+ )),
+ array('/node/2/edit', array(
+ RouteObjectInterface::ROUTE_NAME => 'node_edit',
+ '_raw_variables' => new ParameterBag(array('node' => '2')),
+ )),
+ )));
+
+ $urls = array();
+ foreach ($this->map as $index => $values) {
+ $path = trim(array_pop($values), '/');
+ $url = Url::createFromPath($path);
+ $this->assertSame($values, array_values($url->toArray()));
+ $urls[$index] = $url;
+ }
+ return $urls;
+ }
+
+ /**
+ * Tests that an invalid path will thrown an exception.
+ *
+ * @covers ::createFromPath()
+ *
+ * @expectedException \Symfony\Component\Routing\Exception\ResourceNotFoundException
+ */
+ public function testCreateFromPathInvalid() {
+ $this->router->expects($this->once())
+ ->method('match')
+ ->with('/non-existent')
+ ->will($this->throwException(new ResourceNotFoundException()));
+
+ Url::createFromPath('non-existent');
+ }
+
+ /**
+ * Tests the createFromRequest method.
+ *
+ * @covers ::createFromRequest()
+ */
+ public function testCreateFromRequest() {
+ $request = new Request(array(), array(), array(
+ '_raw_variables' => new ParameterBag(array(
+ 'color' => 'chartreuse',
+ )),
+ RouteObjectInterface::ROUTE_NAME => 'the_route_name',
+ ));
+
+ $url = Url::createFromRequest($request);
+ $expected = new Url('the_route_name', array('color' => 'chartreuse'));
+ $this->assertEquals($expected, $url);
+ }
+
+ /**
+ * Tests the isExternal() method.
+ *
+ * @depends testCreateFromPath
+ *
+ * @covers ::isExternal()
+ */
+ public function testIsExternal($urls) {
+ foreach ($urls as $url) {
+ $this->assertFalse($url->isExternal());
+ }
+ }
+
+ /**
+ * Tests the toString() method.
+ *
+ * @param \Drupal\Core\Url[] $urls
+ * An array of Url objects.
+ *
+ * @depends testCreateFromPath
+ *
+ * @covers ::toString()
+ */
+ public function testToString($urls) {
+ foreach ($urls as $index => $url) {
+ $path = array_pop($this->map[$index]);
+ $this->assertSame($path, $url->toString());
+ }
+ }
+
+ /**
+ * Tests the toArray() method.
+ *
+ * @param \Drupal\Core\Url[] $urls
+ * An array of Url objects.
+ *
+ * @depends testCreateFromPath
+ *
+ * @covers ::toArray()
+ */
+ public function testToArray($urls) {
+ foreach ($urls as $index => $url) {
+ $expected = array(
+ 'route_name' => $this->map[$index][0],
+ 'route_parameters' => $this->map[$index][1],
+ 'options' => $this->map[$index][2],
+ );
+ $this->assertSame($expected, $url->toArray());
+ }
+ }
+
+ /**
+ * Tests the getRouteName() method.
+ *
+ * @param \Drupal\Core\Url[] $urls
+ * An array of Url objects.
+ *
+ * @depends testCreateFromPath
+ *
+ * @covers ::getRouteName()
+ */
+ public function testGetRouteName($urls) {
+ foreach ($urls as $index => $url) {
+ $this->assertSame($this->map[$index][0], $url->getRouteName());
+ }
+ }
+
+ /**
+ * Tests the getRouteParameters() method.
+ *
+ * @param \Drupal\Core\Url[] $urls
+ * An array of Url objects.
+ *
+ * @depends testCreateFromPath
+ *
+ * @covers ::getRouteParameters()
+ */
+ public function testGetRouteParameters($urls) {
+ foreach ($urls as $index => $url) {
+ $this->assertSame($this->map[$index][1], $url->getRouteParameters());
+ }
+ }
+
+ /**
+ * Tests the getOptions() method.
+ *
+ * @param \Drupal\Core\Url[] $urls
+ * An array of Url objects.
+ *
+ * @depends testCreateFromPath
+ *
+ * @covers ::getOptions()
+ */
+ public function testGetOptions($urls) {
+ foreach ($urls as $index => $url) {
+ $this->assertSame($this->map[$index][2], $url->getOptions());
+ }
+ }
+
+}
diff --git a/core/tests/Drupal/Tests/Core/Utility/LinkGeneratorTest.php b/core/tests/Drupal/Tests/Core/Utility/LinkGeneratorTest.php
index 80d9d58..23dd3ee 100644
--- a/core/tests/Drupal/Tests/Core/Utility/LinkGeneratorTest.php
+++ b/core/tests/Drupal/Tests/Core/Utility/LinkGeneratorTest.php
@@ -64,6 +64,7 @@ class LinkGeneratorTest extends UnitTestCase {
'html' => FALSE,
'language' => NULL,
'set_active_class' => FALSE,
+ 'absolute' => FALSE,
);
/**