Commit 31022924 authored by alexpott's avatar alexpott

Issue #2343759 by pwolanin, larowlan, dawehner, tim.plunkett, effulgentsia,...

Issue #2343759 by pwolanin, larowlan, dawehner, tim.plunkett, effulgentsia, xjm, Wim Leers: Provide an API function to replace url()/l() for external urls.
parent 5fdcfc74
...@@ -452,11 +452,18 @@ function _batch_finished() { ...@@ -452,11 +452,18 @@ function _batch_finished() {
if ($_batch['form_state']->getRedirect() === NULL) { if ($_batch['form_state']->getRedirect() === NULL) {
$redirect = $_batch['batch_redirect'] ?: $_batch['source_url']; $redirect = $_batch['batch_redirect'] ?: $_batch['source_url'];
$options = UrlHelper::parse($redirect); $options = UrlHelper::parse($redirect);
if (!UrlHelper::isExternal($options['path'])) { // Any path with a scheme does not correspond to a route.
$options['path'] = $GLOBALS['base_url'] . '/' . $options['path']; if (parse_url($options['path'], PHP_URL_SCHEME)) {
$redirect = Url::fromUri($options['path'], $options);
}
else {
$redirect = \Drupal::pathValidator()->getUrlIfValid($options['path']);
if (!$redirect) {
// Stay on the same page if the redirect was invalid.
$redirect = Url::fromRoute('<current>');
}
$redirect->setOptions($options);
} }
$redirect = Url::createFromPath($options['path']);
$redirect->setOptions($options);
$_batch['form_state']->setRedirectUrl($redirect); $_batch['form_state']->setRedirectUrl($redirect);
} }
......
...@@ -543,7 +543,10 @@ function install_run_task($task, &$install_state) { ...@@ -543,7 +543,10 @@ function install_run_task($task, &$install_state) {
} }
// Process the batch. For progressive batches, this will redirect. // Process the batch. For progressive batches, this will redirect.
// Otherwise, the batch will complete. // Otherwise, the batch will complete.
$response = batch_process(install_redirect_url($install_state), install_full_redirect_url($install_state)); // install_redirect_url() returns core/install.php, so let's ensure to
// drop it from it and use base:// as batch_process() is using the
// unrouted URL assembler, which requires base://.
$response = batch_process(preg_replace('@^core/@', 'base://', install_redirect_url($install_state)), install_full_redirect_url($install_state));
if ($response instanceof Response) { if ($response instanceof Response) {
// Save $_SESSION data from batch. // Save $_SESSION data from batch.
\Drupal::service('session_manager')->save(); \Drupal::service('session_manager')->save();
......
...@@ -141,9 +141,7 @@ public function getUrlObject($title_attribute = TRUE) { ...@@ -141,9 +141,7 @@ public function getUrlObject($title_attribute = TRUE) {
return new Url($this->pluginDefinition['route_name'], $this->pluginDefinition['route_parameters'], $options); return new Url($this->pluginDefinition['route_name'], $this->pluginDefinition['route_parameters'], $options);
} }
else { else {
$url = Url::createFromPath($this->pluginDefinition['url']); return Url::fromUri($this->pluginDefinition['url'], $options);
$url->setOptions($options);
return $url;
} }
} }
......
...@@ -99,7 +99,7 @@ public function getUrlIfValid($path) { ...@@ -99,7 +99,7 @@ public function getUrlIfValid($path) {
if (empty($parsed_url['path'])) { if (empty($parsed_url['path'])) {
return FALSE; return FALSE;
} }
return Url::createFromPath($path); return Url::fromUri($path);
} }
$path = ltrim($path, '/'); $path = ltrim($path, '/');
......
...@@ -88,6 +88,7 @@ public static function preRenderLink($element) { ...@@ -88,6 +88,7 @@ public static function preRenderLink($element) {
$element['#markup'] = \Drupal::l($element['#title'], new UrlObject($element['#route_name'], $element['#route_parameters'], $element['#options'])); $element['#markup'] = \Drupal::l($element['#title'], new UrlObject($element['#route_name'], $element['#route_parameters'], $element['#options']));
} }
else { else {
// @todo Convert to \Drupal::l(): https://www.drupal.org/node/2347045.
$element['#markup'] = l($element['#title'], $element['#href'], $element['#options']); $element['#markup'] = l($element['#title'], $element['#href'], $element['#options']);
} }
return $element; return $element;
......
This diff is collapsed.
...@@ -56,7 +56,7 @@ public function assemble($uri, array $options = []) { ...@@ -56,7 +56,7 @@ public function assemble($uri, array $options = []) {
// UrlHelper::isExternal() only returns true for safe protocols. // UrlHelper::isExternal() only returns true for safe protocols.
return $this->buildExternalUrl($uri, $options); return $this->buildExternalUrl($uri, $options);
} }
throw new \InvalidArgumentException('You must use a valid URI scheme. Use base:// for a path e.g. to a Drupal file that needs the base path.'); throw new \InvalidArgumentException('You must use a valid URI scheme. Use base:// for a path e.g. to a Drupal file that needs the base path.');
} }
/** /**
......
...@@ -12,23 +12,24 @@ ...@@ -12,23 +12,24 @@
interface UnroutedUrlAssemblerInterface { interface UnroutedUrlAssemblerInterface {
/** /**
* Builds a domain-local or external URL from a path or URL. * Builds a domain-local or external URL from a URI.
* *
* For actual implementations the logic probably has to be split up between * For actual implementations the logic probably has to be split up between
* domain-local and external URLs. * domain-local URIs and external URLs.
* *
* @param string $uri * @param string $uri
* A path on the same domain or external URL being linked to, such as "foo" * A local URI or an external URL being linked to, such as "base://foo"
* or "http://example.com/foo". * or "http://example.com/foo".
* - If you provide a full URL, it will be considered an external URL as * - If you provide a full URL, it will be considered an external URL as
* long as it has an allowed protocol. * long as it has an allowed protocol.
* - If you provide only a path (e.g. "foo"), it will be * - If you provide only a local URI (e.g. "base://foo"), it will be
* considered a URL local to the same domain. Additional query * considered a path local to Drupal, but not handled by the routing
* arguments for local paths must be supplied in $options['query'], not * system. The base path (the subdirectory where the front controller
* included in $path. * is found) will be added to the path. Additional query arguments for
* local paths must be supplied in $options['query'], not part of $uri.
* - If your external URL contains a query (e.g. http://example.com/foo?a=b), * - If your external URL contains a query (e.g. http://example.com/foo?a=b),
* then you can either URL encode the query keys and values yourself and * then you can either URL encode the query keys and values yourself and
* include them in $path, or use $options['query'] to let this method * include them in $uri, or use $options['query'] to let this method
* URL encode them. * URL encode them.
* *
* @param array $options * @param array $options
...@@ -48,6 +49,9 @@ interface UnroutedUrlAssemblerInterface { ...@@ -48,6 +49,9 @@ interface UnroutedUrlAssemblerInterface {
* *
* @return * @return
* A string containing a relative or absolute URL. * A string containing a relative or absolute URL.
*
* @throws \InvalidArgumentException
* Thrown when the passed in path has no scheme.
*/ */
public function assemble($uri, array $options = array()); public function assemble($uri, array $options = array());
......
...@@ -26,6 +26,7 @@ function aggregator_help($route_name, RouteMatchInterface $route_match) { ...@@ -26,6 +26,7 @@ function aggregator_help($route_name, RouteMatchInterface $route_match) {
$output .= '<p>' . t('The Aggregator module is an on-site syndicator and news reader that gathers and displays fresh content from RSS-, RDF-, and Atom-based feeds made available across the web. Thousands of sites (particularly news sites and blogs) publish their latest headlines in feeds, using a number of standardized XML-based formats. For more information, see the <a href="!aggregator-module">online documentation for the Aggregator module</a>.', array('!aggregator-module' => 'https://drupal.org/documentation/modules/aggregator')) . '</p>'; $output .= '<p>' . t('The Aggregator module is an on-site syndicator and news reader that gathers and displays fresh content from RSS-, RDF-, and Atom-based feeds made available across the web. Thousands of sites (particularly news sites and blogs) publish their latest headlines in feeds, using a number of standardized XML-based formats. For more information, see the <a href="!aggregator-module">online documentation for the Aggregator module</a>.', array('!aggregator-module' => 'https://drupal.org/documentation/modules/aggregator')) . '</p>';
$output .= '<h3>' . t('Uses') . '</h3>'; $output .= '<h3>' . t('Uses') . '</h3>';
$output .= '<dl>'; $output .= '<dl>';
// Check if the aggregator sources View is enabled.
if ($url = $path_validator->getUrlIfValid('aggregator/sources')) { if ($url = $path_validator->getUrlIfValid('aggregator/sources')) {
$output .= '<dt>' . t('Viewing feeds') . '</dt>'; $output .= '<dt>' . t('Viewing feeds') . '</dt>';
$output .= '<dd>' . t('Users view feed content in the <a href="!aggregator">main aggregator display</a>, or by <a href="!aggregator-sources">their source</a> (usually via an RSS feed reader). The most recent content in a feed can be displayed as a block through the <a href="!admin-block">Blocks administration page</a>.', array('!aggregator' => \Drupal::url('aggregator.page_last'), '!aggregator-sources' => $url->toString(), '!admin-block' => \Drupal::url('block.admin_display'))) . '</dd>'; $output .= '<dd>' . t('Users view feed content in the <a href="!aggregator">main aggregator display</a>, or by <a href="!aggregator-sources">their source</a> (usually via an RSS feed reader). The most recent content in a feed can be displayed as a block through the <a href="!admin-block">Blocks administration page</a>.', array('!aggregator' => \Drupal::url('aggregator.page_last'), '!aggregator-sources' => $url->toString(), '!admin-block' => \Drupal::url('block.admin_display'))) . '</dd>';
...@@ -33,6 +34,7 @@ function aggregator_help($route_name, RouteMatchInterface $route_match) { ...@@ -33,6 +34,7 @@ function aggregator_help($route_name, RouteMatchInterface $route_match) {
$output .= '<dt>' . t('Adding, editing, and deleting feeds') . '</dt>'; $output .= '<dt>' . t('Adding, editing, and deleting feeds') . '</dt>';
$output .= '<dd>' . t('Administrators can add, edit, and delete feeds, and choose how often to check each feed for newly updated items on the <a href="!feededit">Feed aggregator administration page</a>.', array('!feededit' => \Drupal::url('aggregator.admin_overview'))) . '</dd>'; $output .= '<dd>' . t('Administrators can add, edit, and delete feeds, and choose how often to check each feed for newly updated items on the <a href="!feededit">Feed aggregator administration page</a>.', array('!feededit' => \Drupal::url('aggregator.admin_overview'))) . '</dd>';
$output .= '<dt>' . t('<abbr title="Outline Processor Markup Language">OPML</abbr> integration') . '</dt>'; $output .= '<dt>' . t('<abbr title="Outline Processor Markup Language">OPML</abbr> integration') . '</dt>';
// Check if the aggregator opml View is enabled.
if ($url = $path_validator->getUrlIfValid('aggregator/opml')) { if ($url = $path_validator->getUrlIfValid('aggregator/opml')) {
$output .= '<dd>' . t('A <a href="!aggregator-opml">machine-readable OPML file</a> of all feeds is available. OPML is an XML-based file format used to share outline-structured information such as a list of RSS feeds. Feeds can also be <a href="!import-opml">imported via an OPML file</a>.', array('!aggregator-opml' => $url->toString(), '!import-opml' => \Drupal::url('aggregator.opml_add'))) . '</dd>'; $output .= '<dd>' . t('A <a href="!aggregator-opml">machine-readable OPML file</a> of all feeds is available. OPML is an XML-based file format used to share outline-structured information such as a list of RSS feeds. Feeds can also be <a href="!import-opml">imported via an OPML file</a>.', array('!aggregator-opml' => $url->toString(), '!import-opml' => \Drupal::url('aggregator.opml_add'))) . '</dd>';
} }
......
...@@ -244,7 +244,7 @@ public function getListCacheTags() { ...@@ -244,7 +244,7 @@ public function getListCacheTags() {
* Entity URI callback. * Entity URI callback.
*/ */
public static function buildUri(ItemInterface $item) { public static function buildUri(ItemInterface $item) {
return Url::createFromPath($item->getLink()); return Url::fromUri($item->getLink());
} }
} }
...@@ -51,15 +51,15 @@ public static function getNextDestination(array $destinations) { ...@@ -51,15 +51,15 @@ public static function getNextDestination(array $destinations) {
$next_destination += array( $next_destination += array(
'route_parameters' => array(), 'route_parameters' => array(),
); );
$next_destination = new Url($next_destination['route_name'], $next_destination['route_parameters'], $next_destination['options']); $next_destination = Url::fromRoute($next_destination['route_name'], $next_destination['route_parameters'], $next_destination['options']);
} }
else { else {
$options = UrlHelper::parse($next_destination); $options = UrlHelper::parse($next_destination);
if ($destinations) { if ($destinations) {
$options['query']['destinations'] = $destinations; $options['query']['destinations'] = $destinations;
} }
$next_destination = Url::createFromPath($options['path']); // Redirect to any given path within the same domain.
$next_destination->setOptions($options); $next_destination = Url::fromUri('base://' . $options['path']);
} }
return $next_destination; return $next_destination;
} }
......
...@@ -69,6 +69,6 @@ function template_preprocess_link_formatter_link_separate(&$variables) { ...@@ -69,6 +69,6 @@ function template_preprocess_link_formatter_link_separate(&$variables) {
$variables['link'] = \Drupal::l($variables['url_title'], $variables['url']); $variables['link'] = \Drupal::l($variables['url_title'], $variables['url']);
} }
else { else {
$variables['link'] = l($variables['url_title'], $variables['url']->getPath(), $variables['url']->getOptions()); $variables['link'] = l($variables['url_title'], $variables['url']->getUri(), $variables['url']->getOptions());
} }
} }
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url; use Drupal\Core\Url;
use Drupal\link\LinkItemInterface; use Drupal\link\LinkItemInterface;
use Symfony\Component\HttpFoundation\Request;
/** /**
* Plugin implementation of the 'link' formatter. * Plugin implementation of the 'link' formatter.
...@@ -163,7 +164,7 @@ public function viewElements(FieldItemListInterface $items) { ...@@ -163,7 +164,7 @@ public function viewElements(FieldItemListInterface $items) {
'#options' => $url->getOptions(), '#options' => $url->getOptions(),
); );
if ($url->isExternal()) { if ($url->isExternal()) {
$element[$delta]['#href'] = $url->getPath(); $element[$delta]['#href'] = $url->getUri();
} }
else { else {
$element[$delta]['#route_name'] = $url->getRouteName(); $element[$delta]['#route_name'] = $url->getRouteName();
...@@ -206,11 +207,10 @@ protected function buildUrl(LinkItemInterface $item) { ...@@ -206,11 +207,10 @@ protected function buildUrl(LinkItemInterface $item) {
} }
if ($item->isExternal()) { if ($item->isExternal()) {
$url = Url::createFromPath($item->url); $url = Url::fromUri($item->url, $options);
$url->setOptions($options);
} }
else { else {
$url = new Url($item->route_name, (array) $item->route_parameters, (array) $options); $url = Url::fromRoute($item->route_name, (array) $item->route_parameters, (array) $options);
} }
return $url; return $url;
......
...@@ -107,7 +107,7 @@ public function getUrlObject() { ...@@ -107,7 +107,7 @@ public function getUrlObject() {
else { else {
$path = $this->getUrl(); $path = $this->getUrl();
if (isset($path)) { if (isset($path)) {
$url = Url::createFromPath($path); $url = Url::fromUri($path);
} }
else { else {
$url = new Url('<front>'); $url = new Url('<front>');
......
...@@ -198,7 +198,7 @@ public function extractFormValues(array &$form, FormStateInterface $form_state) ...@@ -198,7 +198,7 @@ public function extractFormValues(array &$form, FormStateInterface $form_state)
if ($extracted) { if ($extracted) {
if ($extracted->isExternal()) { if ($extracted->isExternal()) {
$new_definition['url'] = $extracted->getPath(); $new_definition['url'] = $extracted->getUri();
} }
else { else {
$new_definition['route_name'] = $extracted->getRouteName(); $new_definition['route_name'] = $extracted->getRouteName();
......
...@@ -75,7 +75,8 @@ public function testAllFormattersInternal() { ...@@ -75,7 +75,8 @@ public function testAllFormattersInternal() {
// Set up test values. // Set up test values.
$this->testValue = 'admin'; $this->testValue = 'admin';
$this->entity = entity_create('entity_test', array()); $this->entity = entity_create('entity_test', array());
$this->entity->{$this->fieldName}->url = $this->testValue; $this->entity->{$this->fieldName}->route_name = 'system.admin';
$this->entity->{$this->fieldName}->url = 'admin';
// Set up the expected result. // Set up the expected result.
// AssertFormatterRdfa looks for a full path. // AssertFormatterRdfa looks for a full path.
...@@ -94,7 +95,8 @@ public function testAllFormattersFront() { ...@@ -94,7 +95,8 @@ public function testAllFormattersFront() {
// Set up test values. // Set up test values.
$this->testValue = '<front>'; $this->testValue = '<front>';
$this->entity = entity_create('entity_test', array()); $this->entity = entity_create('entity_test', array());
$this->entity->{$this->fieldName}->url = $this->testValue; $this->entity->{$this->fieldName}->route_name = $this->testValue;
$this->entity->{$this->fieldName}->url = '<front>';
// Set up the expected result. // Set up the expected result.
$expected_rdf = array( $expected_rdf = array(
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
use Drupal\Core\Field\BaseFieldDefinition; use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Url; use Drupal\Core\Url;
use Drupal\shortcut\ShortcutInterface; use Drupal\shortcut\ShortcutInterface;
use Symfony\Component\HttpFoundation\Request;
/** /**
* Defines the shortcut entity class. * Defines the shortcut entity class.
...@@ -134,7 +135,15 @@ public static function preCreate(EntityStorageInterface $storage, array &$values ...@@ -134,7 +135,15 @@ public static function preCreate(EntityStorageInterface $storage, array &$values
public function preSave(EntityStorageInterface $storage) { public function preSave(EntityStorageInterface $storage) {
parent::preSave($storage); parent::preSave($storage);
$url = Url::createFromPath($this->path->value); // @todo fix PathValidatorInterface::getUrlIfValid() so we can use it
// here. The problem is that we need an exception, not a FALSE
// return value. https://www.drupal.org/node/2346695
if ($this->path->value == '<front>') {
$url = new Url($this->path->value);
}
else {
$url = Url::createFromRequest(Request::create("/{$this->path->value}"));
}
$this->setRouteName($url->getRouteName()); $this->setRouteName($url->getRouteName());
$this->setRouteParams($url->getRouteParameters()); $this->setRouteParams($url->getRouteParameters());
} }
......
...@@ -457,7 +457,7 @@ function system_authorized_get_url(array $options = array()) { ...@@ -457,7 +457,7 @@ function system_authorized_get_url(array $options = array()) {
// Force HTTPS if available, regardless of what the caller specifies. // Force HTTPS if available, regardless of what the caller specifies.
$options['https'] = TRUE; $options['https'] = TRUE;
// Prefix with $base_url so url() treats it as an external link. // Prefix with $base_url so url() treats it as an external link.
$url = Url::createFromPath($base_url . '/core/authorize.php'); $url = Url::fromUri('base://core/authorize.php');
$url_options = $url->getOptions(); $url_options = $url->getOptions();
$url->setOptions($options + $url_options); $url->setOptions($options + $url_options);
return $url; return $url;
......
...@@ -54,7 +54,7 @@ public function buildForm(array $form, FormStateInterface $form_state) { ...@@ -54,7 +54,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
public function submitForm(array &$form, FormStateInterface $form_state) { public function submitForm(array &$form, FormStateInterface $form_state) {
if (!$form_state->isValueEmpty('redirection')) { if (!$form_state->isValueEmpty('redirection')) {
if (!$form_state->isValueEmpty('destination')) { if (!$form_state->isValueEmpty('destination')) {
$form_state->setRedirectUrl(Url::createFromPath($GLOBALS['base_url'] . '/' . $form_state->getValue('destination'))); $form_state->setRedirectUrl(Url::fromUri('base://' . $form_state->getValue('destination')));
} }
} }
else { else {
......
...@@ -298,7 +298,7 @@ function toolbar_menu_navigation_links(array $tree) { ...@@ -298,7 +298,7 @@ function toolbar_menu_navigation_links(array $tree) {
$url = $link->getUrlObject(); $url = $link->getUrlObject();
if ($url->isExternal()) { if ($url->isExternal()) {
// This is an unusual case, so just get a distinct, safe string. // This is an unusual case, so just get a distinct, safe string.
$id = substr(Crypt::hashBase64($url->getPath()), 0, 16); $id = substr(Crypt::hashBase64($url->getUri()), 0, 16);
} }
else { else {
$id = str_replace(array('.', '<', '>'), array('-', '', ''), $url->getRouteName()); $id = str_replace(array('.', '<', '>'), array('-', '', ''), $url->getRouteName());
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
*/ */
use Drupal\Core\Template\Attribute; use Drupal\Core\Template\Attribute;
use Drupal\Core\Url;
/** /**
* Prepares variables for project status report templates. * Prepares variables for project status report templates.
...@@ -135,7 +136,7 @@ function template_preprocess_update_project_status(&$variables) { ...@@ -135,7 +136,7 @@ function template_preprocess_update_project_status(&$variables) {
// Set the project title and URL. // Set the project title and URL.
$variables['title'] = (isset($project['title'])) ? $project['title'] : $project['name']; $variables['title'] = (isset($project['title'])) ? $project['title'] : $project['name'];
$variables['url'] = (isset($project['link'])) ? url($project['link']) : NULL; $variables['url'] = (isset($project['link'])) ? Url::fromUri($project['link'])->toString() : NULL;
$variables['install_type'] = $project['install_type']; $variables['install_type'] = $project['install_type'];
if ($project['install_type'] == 'dev' && !empty($project['datestamp'])) { if ($project['install_type'] == 'dev' && !empty($project['datestamp'])) {
......
...@@ -576,6 +576,7 @@ function template_preprocess_username(&$variables) { ...@@ -576,6 +576,7 @@ function template_preprocess_username(&$variables) {
$variables['name'] = String::checkPlain($name); $variables['name'] = String::checkPlain($name);
$variables['profile_access'] = \Drupal::currentUser()->hasPermission('access user profiles'); $variables['profile_access'] = \Drupal::currentUser()->hasPermission('access user profiles');
$external = FALSE;
// Populate link path and attributes if appropriate. // Populate link path and attributes if appropriate.
if ($variables['uid'] && $variables['profile_access']) { if ($variables['uid'] && $variables['profile_access']) {
// We are linking to a local user. // We are linking to a local user.
...@@ -589,10 +590,19 @@ function template_preprocess_username(&$variables) { ...@@ -589,10 +590,19 @@ function template_preprocess_username(&$variables) {
$variables['attributes']['rel'] = 'nofollow'; $variables['attributes']['rel'] = 'nofollow';
$variables['link_path'] = $account->homepage; $variables['link_path'] = $account->homepage;
$variables['homepage'] = $account->homepage; $variables['homepage'] = $account->homepage;
$external = TRUE;
} }
// We have a link path, so we should generate a link using url(). // We have a link path, so we should generate a URL.
if (isset($variables['link_path'])) { if (isset($variables['link_path'])) {
$variables['attributes']['href'] = url($variables['link_path'], $variables['link_options']); if ($external) {
$variables['attributes']['href'] = Url::fromUri($variables['link_path'], $variables['link_options'])
->toString();
}
else {
$variables['attributes']['href'] = Url::fromRoute('entity.user.canonical', array(
'user' => $variables['uid'],
))->toString();
}
} }
} }
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
use Drupal\Core\Url; use Drupal\Core\Url;
use Drupal\user\TempStoreFactory; use Drupal\user\TempStoreFactory;
use Drupal\views\Views; use Drupal\views\Views;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\ContainerInterface;
...@@ -322,13 +323,11 @@ public function save(array $form, FormStateInterface $form_state) { ...@@ -322,13 +323,11 @@ public function save(array $form, FormStateInterface $form_state) {
$query->remove('destination'); $query->remove('destination');
} }
} }
if (!UrlHelper::isExternal($destination)) { $form_state->setRedirectUrl(Url::fromUri("base://$destination"));
$destination = $GLOBALS['base_url'] . '/' . $destination;
}
$form_state->setRedirectUrl(Url::createFromPath($destination));
} }
$view->save(); $view->save();
drupal_set_message($this->t('The view %name has been saved.', array('%name' => $view->label()))); drupal_set_message($this->t('The view %name has been saved.', array('%name' => $view->label())));
// Remove this view from cache so we can edit it properly. // Remove this view from cache so we can edit it properly.
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
/** /**
* @file * @file
* Contains \Drupal\Tests\Core\ExternalUrlTest. * Contains \Drupal\Tests\Core\UnroutedUrlTest.
*/ */
namespace Drupal\Tests\Core; namespace Drupal\Tests\Core;
...@@ -15,16 +15,16 @@ ...@@ -15,16 +15,16 @@
/** /**
* @coversDefaultClass \Drupal\Core\Url * @coversDefaultClass \Drupal\Core\Url
* @group ExternalUrlTest * @group UrlTest
*/ */
class ExternalUrlTest extends UnitTestCase { class UnroutedUrlTest extends UnitTestCase {
/** /**
* The URL generator * The URL assembler
* *
* @var \Drupal\Core\Routing\UrlGeneratorInterface|\PHPUnit_Framework_MockObject_MockObject * @var \Drupal\Core\Utility\UnroutedUrlAssemblerInterface|\PHPUnit_Framework_MockObject_MockObject
*/ */
protected $urlGenerator; protected $urlAssembler;
/** /**
* The router. * The router.
...@@ -34,11 +34,18 @@ class ExternalUrlTest extends UnitTestCase { ...@@ -34,11 +34,18 @@ class ExternalUrlTest extends UnitTestCase {
protected $router; protected $router;
/** /**
* An external URL to test. * An unrouted, external URL to test.
* *
* @var string * @var string
*/ */
protected $path = 'http://drupal.org'; protected $unroutedExternal = 'http://drupal.org';
/**
* An unrouted, internal URL to test.
*
* @var string
*/
protected $unroutedInternal = 'base://robots.txt';
/** /**
* {@inheritdoc} * {@inheritdoc}
...@@ -46,35 +53,42 @@ class ExternalUrlTest extends UnitTestCase { ...@@ -46,35 +53,42 @@ class ExternalUrlTest extends UnitTestCase {
protected function setUp() { protected function setUp() {
parent::setUp();