diff --git a/core/core.services.yml b/core/core.services.yml index 91a2c2b..ca67ffd 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -489,6 +489,9 @@ services: arguments: ['@router.route_provider', '@path_processor_manager', '@route_processor_manager', '@config.factory', '@settings', '@logger.channel.default', '@request_stack'] calls: - [setContext, ['@?router.request_context']] + url_builder: + class: Drupal\Core\Routing\UrlBuilder + arguments: ['@request_stack', '@config.factory' ] link_generator: class: Drupal\Core\Utility\LinkGenerator arguments: ['@url_generator', '@module_handler'] diff --git a/core/includes/common.inc b/core/includes/common.inc index 1379b4e..f46c9a9 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc @@ -639,6 +639,9 @@ function _format_date_callback(array $matches = NULL, $new_langcode = NULL) { * alternative than url(). * * @see \Drupal\Core\Routing\UrlGeneratorInterface::generateFromPath(). + * + * @deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0. + * System paths should not be used - use route names and parameters. */ function url($path = NULL, array $options = array()) { return \Drupal::urlGenerator()->generateFromPath($path, $options); diff --git a/core/lib/Drupal/Core/Routing/UrlBuilder.php b/core/lib/Drupal/Core/Routing/UrlBuilder.php new file mode 100644 index 0000000..4d273cd --- /dev/null +++ b/core/lib/Drupal/Core/Routing/UrlBuilder.php @@ -0,0 +1,131 @@ +get('system.filter')->get('protocols') ?: array('http', 'https'); + UrlHelper::setAllowedProtocols($allowed_protocols); + $this->requestStack = $request_stack; + } + + /** + * {@inheritdoc} + */ + public function buildFromPath($path, array $options = array()) { + // Note that UrlHelper::isExternal will return FALSE if the $path has a + // disallowed protocol. This is later made safe since we always add at + // least a leading slash. + if (strpos($path, 'base://') !== 0 && UrlHelper::isExternal($path)) { + return $this->buildExternalUrl($path, $options); + } + return $this->buildLocalUrl($path, $options); + } + + /** + * {@inheritdoc} + */ + public function buildExternalUrl($path, array $options = array()) { + $this->addOptionDefaults($options); + // Split off the fragment. + if (strpos($path, '#') !== FALSE) { + list($path, $old_fragment) = explode('#', $path, 2); + // If $options contains no fragment, take it over from the path. + if (isset($old_fragment) && !$options['fragment']) { + $options['fragment'] = '#' . $old_fragment; + } + } + // Append the query. + if ($options['query']) { + $path .= (strpos($path, '?') !== FALSE ? '&' : '?') . UrlHelper::buildQuery($options['query']); + } + // Reassemble. + return $path . $options['fragment']; + } + + /** + * {@inheritdoc} + */ + public function buildLocalUrl($path, array $options = array()) { + $this->addOptionDefaults($options); + $request = $this->requestStack->getCurrentRequest(); + if (strpos($path, 'base://') === 0) { + // Remove the scheme. + $path = substr($path, 7); + // Add any subdirectory where Drupal is installed. + $current_base_path = $request->getBasePath() . '/'; + } + else { + $current_base_path = '/'; + } + + if ($options['absolute']) { + $current_base_url = $request->getSchemeAndHttpHost() . $current_base_path; + if (isset($options['https'])) { + if ($options['https'] === TRUE) { + $base = str_replace('http://', 'https://', $current_base_url); + $options['absolute'] = TRUE; + } + elseif ($options['https'] === FALSE) { + $base = str_replace('https://', 'http://', $current_base_url); + $options['absolute'] = TRUE; + } + } + else { + $base = $current_base_url; + } + } + else { + $base = $current_base_path; + } + + $prefix = empty($path) ? rtrim($options['prefix'], '/') : $options['prefix']; + + $path = str_replace('%2F', '/', rawurlencode($prefix . $path)); + $query = $options['query'] ? ('?' . UrlHelper::buildQuery($options['query'])) : ''; + return $base . $options['script'] . $path . $query . $options['fragment']; + } + + protected function addOptionDefaults(&$options) { + // Merge in defaults. + $options += array( + 'fragment' => '', + 'query' => array(), + 'absolute' => FALSE, + 'prefix' => '', + 'script' => '', + ); + + if (isset($options['fragment']) && $options['fragment'] !== '') { + $options['fragment'] = '#' . $options['fragment']; + } + } +} diff --git a/core/lib/Drupal/Core/Routing/UrlBuilderInterface.php b/core/lib/Drupal/Core/Routing/UrlBuilderInterface.php new file mode 100644 index 0000000..cb35413 --- /dev/null +++ b/core/lib/Drupal/Core/Routing/UrlBuilderInterface.php @@ -0,0 +1,115 @@ +isExternal()) { - return $this->urlGenerator()->generateFromPath($this->getPath(), $this->getOptions()); + return $this->urlBuilder()->buildExternalUrl($this->getPath(), $this->getOptions()); } return $this->urlGenerator()->generateFromRoute($this->getRouteName(), $this->getRouteParameters(), $this->getOptions()); @@ -473,6 +480,19 @@ protected function urlGenerator() { } /** + * Gets the URL builder for non-Drupal URLs. + * + * @return \Drupal\Core\Routing\UrlBuilderInterface + * The URL builder. + */ + protected function urlBuilder() { + if (!$this->urlBuilder) { + $this->urlBuilder = \Drupal::service('url_builder'); + } + return $this->urlBuilder; + } + + /** * Sets the URL generator. * * @param \Drupal\Core\Routing\UrlGeneratorInterface diff --git a/core/modules/update/update.report.inc b/core/modules/update/update.report.inc index 9ee4dbf..a5b55d0 100644 --- a/core/modules/update/update.report.inc +++ b/core/modules/update/update.report.inc @@ -135,7 +135,7 @@ function template_preprocess_update_project_status(&$variables) { // Set the project title and URL. $variables['title'] = (isset($project['title'])) ? $project['title'] : $project['name']; - $variables['url'] = (isset($project['link'])) ? url($project['link']) : NULL; + $variables['url'] = (isset($project['link'])) ? \Drupal::service('url_builder')->buildFromPath($project['link']) : NULL; $variables['install_type'] = $project['install_type']; if ($project['install_type'] == 'dev' && !empty($project['datestamp'])) { diff --git a/core/modules/user/user.module b/core/modules/user/user.module index e33cd28..3dfdd44 100644 --- a/core/modules/user/user.module +++ b/core/modules/user/user.module @@ -592,7 +592,7 @@ function template_preprocess_username(&$variables) { } // We have a link path, so we should generate a link using url(). if (isset($variables['link_path'])) { - $variables['attributes']['href'] = url($variables['link_path'], $variables['link_options']); + $variables['attributes']['href'] = \Drupal::service('url_builder')->buildFromPath($variables['link_path'], $variables['link_options']); } }