diff --git a/core/includes/batch.inc b/core/includes/batch.inc index d1902e0..fe34cc6 100644 --- a/core/includes/batch.inc +++ b/core/includes/batch.inc @@ -156,7 +156,9 @@ function _batch_progress_page() { $batch['url_options']['query']['id'] = $batch['id']; $batch['url_options']['query']['op'] = $new_op; - $url = _url($batch['url'], $batch['url_options']); + // Normally, the batch is from from the batch route, except in the case of + // some special cases, like the installer. + $url = Url::fromPath($batch['url'], $batch['url_options'])->toString(); $build = array( '#theme' => 'progress_bar', diff --git a/core/includes/form.inc b/core/includes/form.inc index 69c970f..57af95d 100644 --- a/core/includes/form.inc +++ b/core/includes/form.inc @@ -793,7 +793,7 @@ function batch_process($redirect = NULL, $url = 'batch', $redirect_callback = NU if ($batch['progressive']) { // Now that we have a batch id, we can generate the redirection link in // the generic error message. - $batch['error_message'] = t('Please continue to the error page', array('@error_url' => _url($url, array('query' => array('id' => $batch['id'], 'op' => 'finished'))))); + $batch['error_message'] = t('Please continue to the error page', array('@error_url' => Url::fromPath($url, array('query' => array('id' => $batch['id'], 'op' => 'finished')))->toString())); // Clear the way for the redirection to the batch processing page, by // saving and unsetting the 'destination', if there is any. @@ -821,7 +821,7 @@ function batch_process($redirect = NULL, $url = 'batch', $redirect_callback = NU } else { $options['absolute'] = TRUE; - return new RedirectResponse(_url($batch['url'], $options)); + return new RedirectResponse(Url::fromPath($batch['url'], $options)->toString()); } } else { diff --git a/core/lib/Drupal/Core/Render/Element/RenderElement.php b/core/lib/Drupal/Core/Render/Element/RenderElement.php index c0c982a..b6b3ebe 100644 --- a/core/lib/Drupal/Core/Render/Element/RenderElement.php +++ b/core/lib/Drupal/Core/Render/Element/RenderElement.php @@ -292,7 +292,7 @@ public static function preRenderAjaxForm($element) { } // Change progress path to a full URL. if (isset($settings['progress']['path'])) { - $settings['progress']['url'] = _url($settings['progress']['path']); + $settings['progress']['url'] = Url::fromPath($settings['progress']['path'])->toString(); unset($settings['progress']['path']); } diff --git a/core/lib/Drupal/Core/Url.php b/core/lib/Drupal/Core/Url.php index 999f447..2637ced 100644 --- a/core/lib/Drupal/Core/Url.php +++ b/core/lib/Drupal/Core/Url.php @@ -8,6 +8,7 @@ namespace Drupal\Core; use Drupal\Component\Utility\String; +use Drupal\Component\Utility\UrlHelper; use Drupal\Core\DependencyInjection\DependencySerializationTrait; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Routing\UrlGeneratorInterface; @@ -236,6 +237,59 @@ public static function fromUri($uri, $options = array()) { } /** + * Creates a new Url object for a path, which may be a Drupal route, an + * unroutable local path, or an external URL. + * + * This method is to be used for generating URLs where the exact source or + * type of the path is unknown, such as one coming from user input. In + * general, this method should be avoided in favor of Url::fromRoute() or + * Url::fromUri(). + * + * SECURITY NOTE: Drupal route checking will bypass the access check, as + * the logic will revert to generating an unroutable Url object if the + * path validator is used with the access check. + * + * @param string $path + * The path to be converted. + * @param array $options + * (optional) An associative array of additional URL options, with the + * following elements: + * - 'query': An array of query key/value-pairs (without any URL-encoding) + * to append to the URL. Merged with the parameters array. + * - 'fragment': A fragment identifier (named anchor) to append to the URL. + * Do not include the leading '#' character. + * - 'absolute': Defaults to FALSE. 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. + * - 'language': An optional language object used to look up the alias + * for the URL. If $options['language'] is omitted, it defaults to the + * current language for the language type LanguageInterface::TYPE_URL. + * - 'https': Whether this URL should point to a secure location. If not + * defined, the current scheme is used, so the user stays on HTTP or HTTPS + * respectively. TRUE enforces HTTPS and FALSE enforces HTTP. + * + * @return \Drupal\Core\Url + * A new Url object for the path. + * + * @see static::fromRoute() + * @see static::fromUri() + */ + public static function fromPath($path, $options = array()) { + if (UrlHelper::isExternal($path) && UrlHelper::isValid($path)) { + return static::fromUri($path, $options); + } + + $url = \Drupal::pathValidator()->getUrlIfValidWithoutAccessCheck($path); + if ($url === FALSE) { + return static::fromUri('base://' . $path, $options); + } + + $url->setOptions($options); + + return $url; + } + + /** * Returns the Url object matching a request. * * SECURITY NOTE: The request path is not checked to be valid and accessible