diff --git a/core/lib/Drupal/Core/Routing/UrlGeneratorInterface.php b/core/lib/Drupal/Core/Routing/UrlGeneratorInterface.php index 9903fe3..686f0d3 100644 --- a/core/lib/Drupal/Core/Routing/UrlGeneratorInterface.php +++ b/core/lib/Drupal/Core/Routing/UrlGeneratorInterface.php @@ -83,7 +83,7 @@ public function generateFromPath($path = NULL, $options = array()); /** - * Gets the internal path of a route. + * Gets the internal path (system path) of a route. * * @param string $name * The route name. diff --git a/core/lib/Drupal/Core/Url.php b/core/lib/Drupal/Core/Url.php index 2abadb2..c463022 100644 --- a/core/lib/Drupal/Core/Url.php +++ b/core/lib/Drupal/Core/Url.php @@ -188,6 +188,9 @@ public function isExternal() { * Returns the route name. * * @return string + * + * @throws \UnexpectedValueException. + * If this is an external URL with no corresponding route. */ public function getRouteName() { if ($this->isExternal()) { @@ -201,6 +204,9 @@ public function getRouteName() { * Returns the route parameters. * * @return array + * + * @throws \UnexpectedValueException. + * If this is an external URL with no corresponding route. */ public function getRouteParameters() { if ($this->isExternal()) { @@ -364,38 +370,47 @@ public function toArray() { } /** - * Returns the route information for a render array. + * Returns a link type render array. + * + * @param string $link_title + * The title to be used in the render array. * * @return array - * An associative array suitable for a render array. + * A link render array. */ - public function toRenderArray() { + public function toLinkRenderArray($link_title = '') { + $build = array( + '#type' => 'link', + '#title' => $link_title, + '#options' => $this->getOptions(), + ); if ($this->isExternal()) { - return array( - '#href' => $this->getPath(), - '#options' => $this->getOptions(), - ); + $build['#href'] = $this->getPath(); } else { - return array( - '#route_name' => $this->getRouteName(), - '#route_parameters' => $this->getRouteParameters(), - '#options' => $this->getOptions(), - ); + $build['#route_name'] = $this->getRouteName(); + $build['#route_parameters'] = $this->getRouteParameters(); } + return $build; } /** - * Returns the internal path for this route. + * Returns the internal path (system path) for this route. * * This path will not include any prefixes, fragments, or query strings. * * @return string * The internal path for this route. + * + * @throws \UnexpectedValueException. + * If this is an external URL with no corresponding system path. + * + * @deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0. + * System paths should not be used - use route names and parameters. */ public function getInternalPath() { if ($this->isExternal()) { - throw new \Exception('External URLs do not have internal representations.'); + throw new \UnexpectedValueException('External URLs do not have internal representations.'); } return $this->urlGenerator()->getPathFromRoute($this->getRouteName(), $this->getRouteParameters()); } diff --git a/core/lib/Drupal/Core/Utility/LinkGenerator.php b/core/lib/Drupal/Core/Utility/LinkGenerator.php index 1ebc5bf..551fc56 100644 --- a/core/lib/Drupal/Core/Utility/LinkGenerator.php +++ b/core/lib/Drupal/Core/Utility/LinkGenerator.php @@ -107,8 +107,8 @@ public function generateFromUrl($text, Url $url) { // 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 = $url->getInternalPath(); - $variables['options']['attributes']['data-drupal-link-system-path'] = $this->aliasManager->getSystemPath($path); + // @todo System path is deprecated - use the route name and parameters. + $variables['options']['attributes']['data-drupal-link-system-path'] = $url->getInternalPath(); } } 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 01052db..63fbdb3 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 @@ -143,10 +143,7 @@ public function viewElements(FieldItemListInterface $items) { ); } else { - $element[$delta] = array( - '#type' => 'link', - '#title' => $link_title, - ) + $url->toRenderArray(); + $element[$delta] = $url->toLinkRenderArray($link_title); } } diff --git a/core/modules/link/lib/Drupal/link/Plugin/Field/FieldType/LinkItem.php b/core/modules/link/lib/Drupal/link/Plugin/Field/FieldType/LinkItem.php index 907a057..03df369 100644 --- a/core/modules/link/lib/Drupal/link/Plugin/Field/FieldType/LinkItem.php +++ b/core/modules/link/lib/Drupal/link/Plugin/Field/FieldType/LinkItem.php @@ -22,7 +22,7 @@ * label = @Translation("Link"), * description = @Translation("Stores a URL string for external links or route name and parameters for internal links, an optional varchar link text and an optional blob of options to assemble a link."), * instance_settings = { - * "url_type" = \Drupal\link\LinkItemInterface::LINK_GENERIC, + * "link_type" = \Drupal\link\LinkItemInterface::LINK_GENERIC, * "title" = "1" * }, * default_widget = "link_default", @@ -101,14 +101,14 @@ public static function schema(FieldDefinitionInterface $field_definition) { public function instanceSettingsForm(array $form, array &$form_state) { $element = array(); - $element['url_type'] = array( + $element['link_type'] = array( '#type' => 'radios', '#title' => t('Allowed url type'), - '#default_value' => $this->getSetting('url_type'), + '#default_value' => $this->getSetting('link_type'), '#options' => array( - static::LINK_INTERNAL => t('Internal URLs only'), - static::LINK_EXTERNAL => t('External URLs only'), - static::LINK_GENERIC => t('Both internal and external URLs'), + static::LINK_INTERNAL => t('Internal links only'), + static::LINK_EXTERNAL => t('External links only'), + static::LINK_GENERIC => t('Both internal and external links'), ), ); diff --git a/core/modules/link/lib/Drupal/link/Plugin/Field/FieldWidget/LinkWidget.php b/core/modules/link/lib/Drupal/link/Plugin/Field/FieldWidget/LinkWidget.php index 8225d8f..a19dbfb 100644 --- a/core/modules/link/lib/Drupal/link/Plugin/Field/FieldWidget/LinkWidget.php +++ b/core/modules/link/lib/Drupal/link/Plugin/Field/FieldWidget/LinkWidget.php @@ -37,7 +37,6 @@ class LinkWidget extends WidgetBase { * {@inheritdoc} */ public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) { - $url_type = $this->getFieldSetting('url_type'); $default_url_value = NULL; if (isset($items[$delta]->url)) { @@ -54,21 +53,21 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen '#required' => $element['#required'], ); - // If the field is configured to allow internal paths, it cannot use the + // If the field is configured to support internal links, it cannot use the // 'url' form element and we have to do the validation ourselves. - if ($url_type & LinkItemInterface::LINK_INTERNAL) { + if ($this->supportsInternalLinks()) { $element['url']['#type'] = 'textfield'; $element['#element_validate'][] = array($this, 'validateUrl'); } - // If the field is configured to allow only internal paths, add a useful + // If the field is configured to allow only internal links, add a useful // element prefix. - if ($url_type == LinkItemInterface::LINK_INTERNAL) { + if (!$this->supportsExternalLinks()) { $element['url']['#field_prefix'] = \Drupal::url('', array(), array('absolute' => TRUE)); } - // If the field is configured to allow both internal and external paths, + // If the field is configured to allow both internal and external links, // show a useful description. - elseif ($url_type == LinkItemInterface::LINK_GENERIC) { + elseif ($this->supportsExternalLinks() && $this->supportsInternalLinks()) { $element['url']['#description'] = $this->t('This can be an internal Drupal path such as %add-node or an external URL such as %drupal. Enter %front to link to the front page.', array('%front' => '', '%add-node' => 'node/add', '%drupal' => 'http://drupal.org')); } @@ -109,6 +108,22 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen } /** + * Is the LinkItem field definition configured to support links to routes? + */ + protected function supportsInternalLinks() { + $link_type = $this->getFieldSetting('link_type'); + return (bool) ($link_type & LinkItemInterface::LINK_INTERNAL); + } + + /** + * Is the LinkItem field definition configured to support external URLs? + */ + protected function supportsExternalLinks() { + $link_type = $this->getFieldSetting('link_type'); + return (bool) ($link_type & LinkItemInterface::LINK_EXTERNAL); + } + + /** * {@inheritdoc} */ public function settingsForm(array $form, array &$form_state) { @@ -174,7 +189,6 @@ public function validateTitle(&$element, &$form_state, $form) { * Form element validation handler; Validates the url property. */ public function validateUrl(&$element, &$form_state, $form) { - $url_type = $this->getFieldSetting('url_type'); $url_is_valid = TRUE; // Validate the 'url' element. @@ -185,7 +199,7 @@ public function validateUrl(&$element, &$form_state, $form) { if ($url->isExternal() && !UrlHelper::isValid($element['url']['#value'], TRUE)) { $url_is_valid = FALSE; } - elseif ($url->isExternal() && $url_type == LinkItemInterface::LINK_INTERNAL) { + elseif ($url->isExternal() && !$this->supportsExternalLinks()) { $url_is_valid = FALSE; } } diff --git a/core/modules/link/lib/Drupal/link/Tests/LinkFieldTest.php b/core/modules/link/lib/Drupal/link/Tests/LinkFieldTest.php index d2b0cc7..e186145 100644 --- a/core/modules/link/lib/Drupal/link/Tests/LinkFieldTest.php +++ b/core/modules/link/lib/Drupal/link/Tests/LinkFieldTest.php @@ -80,7 +80,7 @@ function testURLValidation() { 'bundle' => 'entity_test', 'settings' => array( 'title' => DRUPAL_DISABLED, - 'url_type' => LinkItemInterface::LINK_GENERIC, + 'link_type' => LinkItemInterface::LINK_GENERIC, ), )); $this->instance->save(); @@ -124,18 +124,18 @@ function testURLValidation() { 'non/existing/path', ); - // Test external and internal URLs for 'url_type' = LinkItemInterface::LINK_GENERIC. + // Test external and internal URLs for 'link_type' = LinkItemInterface::LINK_GENERIC. $this->assertValidEntries($field_name, $valid_external_entries + $valid_internal_entries); $this->assertInvalidEntries($field_name, $invalid_external_entries + $invalid_internal_entries); - // Test external URLs for 'url_type' = LinkItemInterface::LINK_EXTERNAL. - $this->instance->settings['url_type'] = LinkItemInterface::LINK_EXTERNAL; + // Test external URLs for 'link_type' = LinkItemInterface::LINK_EXTERNAL. + $this->instance->settings['link_type'] = LinkItemInterface::LINK_EXTERNAL; $this->instance->save(); $this->assertValidEntries($field_name, $valid_external_entries); $this->assertInvalidEntries($field_name, $valid_internal_entries + $invalid_external_entries); - // Test external URLs for 'url_type' = LinkItemInterface::LINK_INTERNAL. - $this->instance->settings['url_type'] = LinkItemInterface::LINK_INTERNAL; + // Test external URLs for 'link_type' = LinkItemInterface::LINK_INTERNAL. + $this->instance->settings['link_type'] = LinkItemInterface::LINK_INTERNAL; $this->instance->save(); $this->assertValidEntries($field_name, $valid_internal_entries); $this->assertInvalidEntries($field_name, $valid_external_entries + $invalid_internal_entries);