Issue #2054011 by amateescu, pwolanin, dawehner, YesCT, tim.plunkett, blueminds, Berdir, das-peter, effulgentsia: Implement built-in support for internal URLs.
parent
4e5b0480f4
commit
bf4a582850
|
@ -309,7 +309,7 @@ services:
|
|||
- [setContext, ['@?router.request_context']]
|
||||
link_generator:
|
||||
class: Drupal\Core\Utility\LinkGenerator
|
||||
arguments: ['@url_generator', '@module_handler', '@path.alias_manager.cached']
|
||||
arguments: ['@url_generator', '@module_handler']
|
||||
router.dynamic:
|
||||
class: Symfony\Cmf\Component\Routing\DynamicRouter
|
||||
arguments: ['@router.request_context', '@router.matcher', '@url_generator']
|
||||
|
|
|
@ -83,7 +83,7 @@ interface UrlGeneratorInterface extends VersatileGeneratorInterface {
|
|||
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.
|
||||
|
|
|
@ -169,7 +169,7 @@ class Url extends DependencySerialization {
|
|||
$this->path = $this->routeName;
|
||||
|
||||
// Set empty route name and parameters.
|
||||
$this->routeName = '';
|
||||
$this->routeName = NULL;
|
||||
$this->routeParameters = array();
|
||||
|
||||
return $this;
|
||||
|
@ -188,8 +188,15 @@ class Url extends DependencySerialization {
|
|||
* Returns the route name.
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws \UnexpectedValueException.
|
||||
* If this is an external URL with no corresponding route.
|
||||
*/
|
||||
public function getRouteName() {
|
||||
if ($this->isExternal()) {
|
||||
throw new \UnexpectedValueException('External URLs do not have an internal route name.');
|
||||
}
|
||||
|
||||
return $this->routeName;
|
||||
}
|
||||
|
||||
|
@ -197,8 +204,15 @@ class Url extends DependencySerialization {
|
|||
* Returns the route parameters.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \UnexpectedValueException.
|
||||
* If this is an external URL with no corresponding route.
|
||||
*/
|
||||
public function getRouteParameters() {
|
||||
if ($this->isExternal()) {
|
||||
throw new \UnexpectedValueException('External URLs do not have internal route parameters.');
|
||||
}
|
||||
|
||||
return $this->routeParameters;
|
||||
}
|
||||
|
||||
|
@ -290,6 +304,25 @@ class Url extends DependencySerialization {
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the external path of the URL.
|
||||
*
|
||||
* Only to be used if self::$external is TRUE.
|
||||
*
|
||||
* @return string
|
||||
* The external path.
|
||||
*
|
||||
* @throws \UnexpectedValueException
|
||||
* Thrown when the path was requested for an internal URL.
|
||||
*/
|
||||
public function getPath() {
|
||||
if (!$this->isExternal()) {
|
||||
throw new \UnexpectedValueException('Internal URLs do not have external paths.');
|
||||
}
|
||||
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the absolute value for this Url.
|
||||
*
|
||||
|
@ -308,7 +341,7 @@ class Url extends DependencySerialization {
|
|||
*/
|
||||
public function toString() {
|
||||
if ($this->isExternal()) {
|
||||
return $this->urlGenerator()->generateFromPath($this->path, $this->getOptions());
|
||||
return $this->urlGenerator()->generateFromPath($this->getPath(), $this->getOptions());
|
||||
}
|
||||
|
||||
return $this->urlGenerator()->generateFromRoute($this->getRouteName(), $this->getRouteParameters(), $this->getOptions());
|
||||
|
@ -321,11 +354,19 @@ class Url extends DependencySerialization {
|
|||
* An associative array containing all the properties of the route.
|
||||
*/
|
||||
public function toArray() {
|
||||
return array(
|
||||
'route_name' => $this->getRouteName(),
|
||||
'route_parameters' => $this->getRouteParameters(),
|
||||
'options' => $this->getOptions(),
|
||||
);
|
||||
if ($this->isExternal()) {
|
||||
return array(
|
||||
'path' => $this->getPath(),
|
||||
'options' => $this->getOptions(),
|
||||
);
|
||||
}
|
||||
else {
|
||||
return array(
|
||||
'route_name' => $this->getRouteName(),
|
||||
'route_parameters' => $this->getRouteParameters(),
|
||||
'options' => $this->getOptions(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -335,24 +376,38 @@ class Url extends DependencySerialization {
|
|||
* An associative array suitable for a render array.
|
||||
*/
|
||||
public function toRenderArray() {
|
||||
return array(
|
||||
'#route_name' => $this->getRouteName(),
|
||||
'#route_parameters' => $this->getRouteParameters(),
|
||||
'#options' => $this->getOptions(),
|
||||
);
|
||||
if ($this->isExternal()) {
|
||||
return array(
|
||||
'#href' => $this->getPath(),
|
||||
'#options' => $this->getOptions(),
|
||||
);
|
||||
}
|
||||
else {
|
||||
return array(
|
||||
'#route_name' => $this->getRouteName(),
|
||||
'#route_parameters' => $this->getRouteParameters(),
|
||||
'#options' => $this->getOptions(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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());
|
||||
}
|
||||
|
|
|
@ -34,13 +34,6 @@ class LinkGenerator implements LinkGeneratorInterface {
|
|||
*/
|
||||
protected $moduleHandler;
|
||||
|
||||
/**
|
||||
* The path alias manager.
|
||||
*
|
||||
* @var \Drupal\Core\Path\AliasManagerInterface
|
||||
*/
|
||||
protected $aliasManager;
|
||||
|
||||
/**
|
||||
* Constructs a LinkGenerator instance.
|
||||
*
|
||||
|
@ -48,13 +41,10 @@ class LinkGenerator implements LinkGeneratorInterface {
|
|||
* The url generator.
|
||||
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
|
||||
* The module handler.
|
||||
* @param \Drupal\Core\Path\AliasManagerInterface $alias_manager
|
||||
* The path alias manager.
|
||||
*/
|
||||
public function __construct(UrlGeneratorInterface $url_generator, ModuleHandlerInterface $module_handler, AliasManagerInterface $alias_manager) {
|
||||
public function __construct(UrlGeneratorInterface $url_generator, ModuleHandlerInterface $module_handler) {
|
||||
$this->urlGenerator = $url_generator;
|
||||
$this->moduleHandler = $module_handler;
|
||||
$this->aliasManager = $alias_manager;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -107,8 +97,8 @@ class LinkGenerator implements LinkGeneratorInterface {
|
|||
// 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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\link\LinkItemInterface.
|
||||
*/
|
||||
|
||||
namespace Drupal\link;
|
||||
|
||||
use Drupal\Core\Field\FieldItemInterface;
|
||||
|
||||
/**
|
||||
* Defines an interface for the link field item.
|
||||
*/
|
||||
interface LinkItemInterface extends FieldItemInterface {
|
||||
|
||||
/**
|
||||
* Specifies whether the field supports only internal URLs.
|
||||
*/
|
||||
const LINK_INTERNAL = 0x01;
|
||||
|
||||
/**
|
||||
* Specifies whether the field supports only external URLs.
|
||||
*/
|
||||
const LINK_EXTERNAL = 0x10;
|
||||
|
||||
/**
|
||||
* Specifies whether the field supports both internal and external URLs.
|
||||
*/
|
||||
const LINK_GENERIC = 0x11;
|
||||
|
||||
/**
|
||||
* Determines if a link is external.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the link is external, FALSE otherwise.
|
||||
*/
|
||||
public function isExternal();
|
||||
|
||||
}
|
|
@ -7,11 +7,11 @@
|
|||
|
||||
namespace Drupal\link\Plugin\Field\FieldFormatter;
|
||||
|
||||
use Drupal\Component\Utility\UrlHelper;
|
||||
use Drupal\Component\Utility\String;
|
||||
use Drupal\Core\Field\FieldItemListInterface;
|
||||
use Drupal\Core\Field\FieldItemInterface;
|
||||
use Drupal\Core\Field\FormatterBase;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\link\LinkItemInterface;
|
||||
|
||||
/**
|
||||
* Plugin implementation of the 'link' formatter.
|
||||
|
@ -128,7 +128,8 @@ class LinkFormatter extends FormatterBase {
|
|||
|
||||
foreach ($items as $delta => $item) {
|
||||
// By default use the full URL as the link text.
|
||||
$link_title = $item->url;
|
||||
$url = $this->buildUrl($item);
|
||||
$link_title = $url->toString();
|
||||
|
||||
// If the title field value is available, use it for the link text.
|
||||
if (empty($settings['url_only']) && !empty($item->title)) {
|
||||
|
@ -148,13 +149,18 @@ class LinkFormatter extends FormatterBase {
|
|||
);
|
||||
}
|
||||
else {
|
||||
$link = $this->buildLink($item);
|
||||
$element[$delta] = array(
|
||||
'#type' => 'link',
|
||||
'#title' => $link_title,
|
||||
'#href' => $link['path'],
|
||||
'#options' => $link['options'],
|
||||
'#options' => $url->getOptions(),
|
||||
);
|
||||
if ($url->isExternal()) {
|
||||
$element[$delta]['#href'] = $url->getPath();
|
||||
}
|
||||
else {
|
||||
$element[$delta]['#route_name'] = $url->getRouteName();
|
||||
$element[$delta]['#route_parameters'] = $url->getRouteParameters();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -162,41 +168,36 @@ class LinkFormatter extends FormatterBase {
|
|||
}
|
||||
|
||||
/**
|
||||
* Builds the link information for a link field item.
|
||||
* Builds the \Drupal\Core\Url object for a link field item.
|
||||
*
|
||||
* @param \Drupal\Core\Field\FieldItemInterface $item
|
||||
* @param \Drupal\link\LinkItemInterface $item
|
||||
* The link field item being rendered.
|
||||
*
|
||||
* @return array
|
||||
* An array with the following key/value pairs:
|
||||
* - 'path': a string suitable for the $path parameter in l().
|
||||
* - 'options': an array suitable for the $options parameter in l().
|
||||
* @return \Drupal\Core\Url
|
||||
* An Url object.
|
||||
*/
|
||||
protected function buildLink(FieldItemInterface $item) {
|
||||
protected function buildUrl(LinkItemInterface $item) {
|
||||
$settings = $this->getSettings();
|
||||
|
||||
// Split out the link into the parts required for url(): path and options.
|
||||
$parsed_url = UrlHelper::parse($item->url);
|
||||
$result = array(
|
||||
'path' => $parsed_url['path'],
|
||||
'options' => array(
|
||||
'query' => $parsed_url['query'],
|
||||
'fragment' => $parsed_url['fragment'],
|
||||
'attributes' => $item->attributes,
|
||||
),
|
||||
);
|
||||
$options = $item->options;
|
||||
|
||||
// Add optional 'rel' attribute to link options.
|
||||
if (!empty($settings['rel'])) {
|
||||
$result['options']['attributes']['rel'] = $settings['rel'];
|
||||
$options['attributes']['rel'] = $settings['rel'];
|
||||
}
|
||||
// Add optional 'target' attribute to link options.
|
||||
if (!empty($settings['target'])) {
|
||||
$result['options']['attributes']['target'] = $settings['target'];
|
||||
$options['attributes']['target'] = $settings['target'];
|
||||
}
|
||||
|
||||
return $result;
|
||||
if ($item->isExternal()) {
|
||||
$url = Url::createFromPath($item->url);
|
||||
$url->setOptions($options);
|
||||
}
|
||||
else {
|
||||
$url = new Url($item->route_name, (array) $item->route_parameters, (array) $options);
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,8 @@ class LinkSeparateFormatter extends LinkFormatter {
|
|||
|
||||
foreach ($items as $delta => $item) {
|
||||
// By default use the full URL as the link text.
|
||||
$link_title = $item->url;
|
||||
$url = $this->buildUrl($item);
|
||||
$link_title = $url->toString();
|
||||
|
||||
// If the link text field value is available, use it for the text.
|
||||
if (empty($settings['url_only']) && !empty($item->title)) {
|
||||
|
@ -64,19 +65,17 @@ class LinkSeparateFormatter extends LinkFormatter {
|
|||
if (empty($item->title)) {
|
||||
$link_title = NULL;
|
||||
}
|
||||
$url_title = $item->url;
|
||||
$url_title = $url->toString();
|
||||
if (!empty($settings['trim_length'])) {
|
||||
$link_title = truncate_utf8($link_title, $settings['trim_length'], FALSE, TRUE);
|
||||
$url_title = truncate_utf8($item->url, $settings['trim_length'], FALSE, TRUE);
|
||||
$url_title = truncate_utf8($url_title, $settings['trim_length'], FALSE, TRUE);
|
||||
}
|
||||
|
||||
$link = $this->buildLink($item);
|
||||
$element[$delta] = array(
|
||||
'#theme' => 'link_formatter_link_separate',
|
||||
'#title' => $link_title,
|
||||
'#url_title' => $url_title,
|
||||
'#href' => $link['path'],
|
||||
'#options' => $link['options'],
|
||||
'#url' => $url,
|
||||
);
|
||||
}
|
||||
return $element;
|
||||
|
|
|
@ -11,6 +11,7 @@ use Drupal\Core\Field\FieldItemBase;
|
|||
use Drupal\Core\Field\FieldDefinitionInterface;
|
||||
use Drupal\Core\TypedData\DataDefinition;
|
||||
use Drupal\Core\TypedData\MapDataDefinition;
|
||||
use Drupal\link\LinkItemInterface;
|
||||
|
||||
/**
|
||||
* Plugin implementation of the 'link' field type.
|
||||
|
@ -20,17 +21,19 @@ use Drupal\Core\TypedData\MapDataDefinition;
|
|||
* label = @Translation("Link"),
|
||||
* description = @Translation("Stores a URL string, optional varchar link text, and optional blob of attributes to assemble a link."),
|
||||
* default_widget = "link_default",
|
||||
* default_formatter = "link"
|
||||
* default_formatter = "link",
|
||||
* constraints = {"LinkType" = {}}
|
||||
* )
|
||||
*/
|
||||
class LinkItem extends FieldItemBase {
|
||||
class LinkItem extends FieldItemBase implements LinkItemInterface {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function defaultInstanceSettings() {
|
||||
return array(
|
||||
'title' => 1,
|
||||
'title' => DRUPAL_OPTIONAL,
|
||||
'link_type' => LinkItemInterface::LINK_GENERIC
|
||||
) + parent::defaultInstanceSettings();
|
||||
}
|
||||
|
||||
|
@ -38,14 +41,20 @@ class LinkItem extends FieldItemBase {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public static function propertyDefinitions(FieldDefinitionInterface $field_definition) {
|
||||
$properties['url'] = DataDefinition::create('uri')
|
||||
$properties['url'] = DataDefinition::create('string')
|
||||
->setLabel(t('URL'));
|
||||
|
||||
$properties['title'] = DataDefinition::create('string')
|
||||
->setLabel(t('Link text'));
|
||||
|
||||
$properties['attributes'] = MapDataDefinition::create()
|
||||
->setLabel(t('Attributes'));
|
||||
$properties['route_name'] = DataDefinition::create('string')
|
||||
->setLabel(t('Route name'));
|
||||
|
||||
$properties['route_parameters'] = MapDataDefinition::create()
|
||||
->setLabel(t('Route parameters'));
|
||||
|
||||
$properties['options'] = MapDataDefinition::create()
|
||||
->setLabel(t('Options'));
|
||||
|
||||
return $properties;
|
||||
}
|
||||
|
@ -68,8 +77,21 @@ class LinkItem extends FieldItemBase {
|
|||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
),
|
||||
'attributes' => array(
|
||||
'description' => 'Serialized array of attributes for the link.',
|
||||
'route_name' => array(
|
||||
'description' => 'The machine name of a defined Route this link represents.',
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
),
|
||||
'route_parameters' => array(
|
||||
'description' => 'Serialized array of route parameters of the link.',
|
||||
'type' => 'blob',
|
||||
'size' => 'big',
|
||||
'not null' => FALSE,
|
||||
'serialize' => TRUE,
|
||||
),
|
||||
'options' => array(
|
||||
'description' => 'Serialized array of options for the link.',
|
||||
'type' => 'blob',
|
||||
'size' => 'big',
|
||||
'not null' => FALSE,
|
||||
|
@ -85,6 +107,17 @@ class LinkItem extends FieldItemBase {
|
|||
public function instanceSettingsForm(array $form, array &$form_state) {
|
||||
$element = array();
|
||||
|
||||
$element['link_type'] = array(
|
||||
'#type' => 'radios',
|
||||
'#title' => t('Allowed link type'),
|
||||
'#default_value' => $this->getSetting('link_type'),
|
||||
'#options' => array(
|
||||
static::LINK_INTERNAL => t('Internal links only'),
|
||||
static::LINK_EXTERNAL => t('External links only'),
|
||||
static::LINK_GENERIC => t('Both internal and external links'),
|
||||
),
|
||||
);
|
||||
|
||||
$element['title'] = array(
|
||||
'#type' => 'radios',
|
||||
'#title' => t('Allow link text'),
|
||||
|
@ -99,15 +132,6 @@ class LinkItem extends FieldItemBase {
|
|||
return $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function preSave() {
|
||||
// Trim any spaces around the URL and link text.
|
||||
$this->url = trim($this->url);
|
||||
$this->title = trim($this->title);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -116,4 +140,11 @@ class LinkItem extends FieldItemBase {
|
|||
return $value === NULL || $value === '';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isExternal() {
|
||||
// External links don't have a route_name value.
|
||||
return empty($this->route_name);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,8 +7,14 @@
|
|||
|
||||
namespace Drupal\link\Plugin\Field\FieldWidget;
|
||||
|
||||
use Drupal\Component\Utility\UrlHelper;
|
||||
use Drupal\Core\Field\FieldItemListInterface;
|
||||
use Drupal\Core\Field\WidgetBase;
|
||||
use Drupal\Core\ParamConverter\ParamNotConvertedException;
|
||||
use Drupal\Core\Routing\MatchingRouteNotFoundException;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\link\LinkItemInterface;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
/**
|
||||
* Plugin implementation of the 'link' widget.
|
||||
|
@ -37,17 +43,42 @@ class LinkWidget extends WidgetBase {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
|
||||
|
||||
$default_url_value = NULL;
|
||||
if (isset($items[$delta]->url)) {
|
||||
$url = Url::createFromPath($items[$delta]->url);
|
||||
$url->setOptions($items[$delta]->options);
|
||||
$default_url_value = ltrim($url->toString(), '/');
|
||||
}
|
||||
$element['url'] = array(
|
||||
'#type' => 'url',
|
||||
'#title' => t('URL'),
|
||||
'#title' => $this->t('URL'),
|
||||
'#placeholder' => $this->getSetting('placeholder_url'),
|
||||
'#default_value' => isset($items[$delta]->url) ? $items[$delta]->url : NULL,
|
||||
'#default_value' => $default_url_value,
|
||||
'#maxlength' => 2048,
|
||||
'#required' => $element['#required'],
|
||||
);
|
||||
|
||||
// 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 ($this->supportsInternalLinks()) {
|
||||
$element['url']['#type'] = 'textfield';
|
||||
}
|
||||
|
||||
// If the field is configured to allow only internal links, add a useful
|
||||
// element prefix.
|
||||
if (!$this->supportsExternalLinks()) {
|
||||
$element['url']['#field_prefix'] = \Drupal::url('<front>', array(), array('absolute' => TRUE));
|
||||
}
|
||||
// If the field is configured to allow both internal and external links,
|
||||
// show a useful description.
|
||||
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' => '<front>', '%add-node' => 'node/add', '%drupal' => 'http://drupal.org'));
|
||||
}
|
||||
|
||||
$element['title'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('Link text'),
|
||||
'#title' => $this->t('Link text'),
|
||||
'#placeholder' => $this->getSetting('placeholder_title'),
|
||||
'#default_value' => isset($items[$delta]->title) ? $items[$delta]->title : NULL,
|
||||
'#maxlength' => 255,
|
||||
|
@ -58,7 +89,7 @@ class LinkWidget extends WidgetBase {
|
|||
// settings cannot be saved otherwise.
|
||||
$is_field_edit_form = ($element['#entity'] === NULL);
|
||||
if (!$is_field_edit_form && $this->getFieldSetting('title') == DRUPAL_REQUIRED) {
|
||||
$element['#element_validate'] = array(array($this, 'validateTitle'));
|
||||
$element['#element_validate'][] = array($this, 'validateTitle');
|
||||
}
|
||||
|
||||
// Exposing the attributes array in the widget is left for alternate and more
|
||||
|
@ -66,7 +97,7 @@ class LinkWidget extends WidgetBase {
|
|||
$element['attributes'] = array(
|
||||
'#type' => 'value',
|
||||
'#tree' => TRUE,
|
||||
'#value' => !empty($items[$delta]->attributes) ? $items[$delta]->attributes : array(),
|
||||
'#value' => !empty($items[$delta]->options['attributes']) ? $items[$delta]->options['attributes'] : array(),
|
||||
'#attributes' => array('class' => array('link-field-widget-attributes')),
|
||||
);
|
||||
|
||||
|
@ -81,6 +112,30 @@ class LinkWidget extends WidgetBase {
|
|||
return $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates enabled support for link to routes.
|
||||
*
|
||||
* @return bool
|
||||
* Returns TRUE if the LinkItem field is configured to support links to
|
||||
* routes, otherwise FALSE.
|
||||
*/
|
||||
protected function supportsInternalLinks() {
|
||||
$link_type = $this->getFieldSetting('link_type');
|
||||
return (bool) ($link_type & LinkItemInterface::LINK_INTERNAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates enabled support for link to external URLs.
|
||||
*
|
||||
* @return bool
|
||||
* Returns TRUE if the LinkItem field is configured to support links to
|
||||
* external URLs, otherwise FALSE.
|
||||
*/
|
||||
protected function supportsExternalLinks() {
|
||||
$link_type = $this->getFieldSetting('link_type');
|
||||
return (bool) ($link_type & LinkItemInterface::LINK_EXTERNAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -89,15 +144,15 @@ class LinkWidget extends WidgetBase {
|
|||
|
||||
$elements['placeholder_url'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('Placeholder for URL'),
|
||||
'#title' => $this->t('Placeholder for URL'),
|
||||
'#default_value' => $this->getSetting('placeholder_url'),
|
||||
'#description' => t('Text that will be shown inside the field until a value is entered. This hint is usually a sample value or a brief description of the expected format.'),
|
||||
'#description' => $this->t('Text that will be shown inside the field until a value is entered. This hint is usually a sample value or a brief description of the expected format.'),
|
||||
);
|
||||
$elements['placeholder_title'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('Placeholder for link text'),
|
||||
'#title' => $this->t('Placeholder for link text'),
|
||||
'#default_value' => $this->getSetting('placeholder_title'),
|
||||
'#description' => t('Text that will be shown inside the field until a value is entered. This hint is usually a sample value or a brief description of the expected format.'),
|
||||
'#description' => $this->t('Text that will be shown inside the field until a value is entered. This hint is usually a sample value or a brief description of the expected format.'),
|
||||
'#states' => array(
|
||||
'invisible' => array(
|
||||
':input[name="instance[settings][title]"]' => array('value' => DRUPAL_DISABLED),
|
||||
|
@ -117,31 +172,62 @@ class LinkWidget extends WidgetBase {
|
|||
$placeholder_title = $this->getSetting('placeholder_title');
|
||||
$placeholder_url = $this->getSetting('placeholder_url');
|
||||
if (empty($placeholder_title) && empty($placeholder_url)) {
|
||||
$summary[] = t('No placeholders');
|
||||
$summary[] = $this->t('No placeholders');
|
||||
}
|
||||
else {
|
||||
if (!empty($placeholder_title)) {
|
||||
$summary[] = t('Title placeholder: @placeholder_title', array('@placeholder_title' => $placeholder_title));
|
||||
$summary[] = $this->t('Title placeholder: @placeholder_title', array('@placeholder_title' => $placeholder_title));
|
||||
}
|
||||
if (!empty($placeholder_url)) {
|
||||
$summary[] = t('URL placeholder: @placeholder_url', array('@placeholder_url' => $placeholder_url));
|
||||
$summary[] = $this->t('URL placeholder: @placeholder_url', array('@placeholder_url' => $placeholder_url));
|
||||
}
|
||||
}
|
||||
|
||||
return $summary;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Form element validation handler for link_field_widget_form().
|
||||
* Form element validation handler; Validates the title property.
|
||||
*
|
||||
* Conditionally requires the link title if a URL value was filled in.
|
||||
*/
|
||||
function validateTitle(&$element, &$form_state, $form) {
|
||||
public function validateTitle(&$element, &$form_state, $form) {
|
||||
if ($element['url']['#value'] !== '' && $element['title']['#value'] === '') {
|
||||
$element['title']['#required'] = TRUE;
|
||||
form_error($element['title'], $form_state, t('!name field is required.', array('!name' => $element['title']['#title'])));
|
||||
\Drupal::formBuilder()->setError($element['title'], $form_state, $this->t('!name field is required.', array('!name' => $element['title']['#title'])));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function massageFormValues(array $values, array $form, array &$form_state) {
|
||||
foreach ($values as &$value) {
|
||||
if (!empty($value['url'])) {
|
||||
try {
|
||||
$parsed_url = UrlHelper::parse($value['url']);
|
||||
|
||||
$url = Url::createFromPath($parsed_url['path']);
|
||||
$url->setOption('query', $parsed_url['query']);
|
||||
$url->setOption('fragment', $parsed_url['fragment']);
|
||||
$url->setOption('attributes', $value['attributes']);
|
||||
|
||||
$value += $url->toArray();
|
||||
// Reset the URL value to contain only the path.
|
||||
$value['url'] = $parsed_url['path'];
|
||||
}
|
||||
catch (NotFoundHttpException $e) {
|
||||
// Nothing to do here, LinkTypeConstraintValidator emits errors.
|
||||
}
|
||||
catch (MatchingRouteNotFoundException $e) {
|
||||
// Nothing to do here, LinkTypeConstraintValidator emits errors.
|
||||
}
|
||||
catch (ParamNotConvertedException $e) {
|
||||
// Nothing to do here, LinkTypeConstraintValidator emits errors.
|
||||
}
|
||||
}
|
||||
}
|
||||
return $values;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\link\Plugin\Validation\Constraint\LinkTypeConstraint.
|
||||
*/
|
||||
|
||||
namespace Drupal\link\Plugin\Validation\Constraint;
|
||||
|
||||
use Drupal\link\LinkItemInterface;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\Core\Routing\MatchingRouteNotFoundException;
|
||||
use Drupal\Core\ParamConverter\ParamNotConvertedException;
|
||||
use Drupal\Component\Utility\UrlHelper;
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
use Symfony\Component\Validator\ConstraintValidatorInterface;
|
||||
use Symfony\Component\Validator\ExecutionContextInterface;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
/**
|
||||
* Validation constraint for links receiving data allowed by its settings.
|
||||
*
|
||||
* @Plugin(
|
||||
* id = "LinkType",
|
||||
* label = @Translation("Link data valid for link type.", context = "Validation"),
|
||||
* )
|
||||
*/
|
||||
class LinkTypeConstraint extends Constraint implements ConstraintValidatorInterface {
|
||||
|
||||
public $message = 'The URL %url is not valid.';
|
||||
|
||||
/**
|
||||
* @var \Symfony\Component\Validator\ExecutionContextInterface
|
||||
*/
|
||||
protected $context;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function initialize(ExecutionContextInterface $context) {
|
||||
$this->context = $context;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validatedBy() {
|
||||
return get_class($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validate($value, Constraint $constraint) {
|
||||
if (isset($value)) {
|
||||
$url_is_valid = TRUE;
|
||||
/** @var $link_item \Drupal\link\LinkItemInterface */
|
||||
$link_item = $value;
|
||||
$link_type = $link_item->getFieldDefinition()->getSetting('link_type');
|
||||
$url_string = $link_item->url;
|
||||
// Validate the url property.
|
||||
if ($url_string !== '') {
|
||||
try {
|
||||
// @todo This shouldn't be needed, but massageFormValues() may not
|
||||
// run.
|
||||
$parsed_url = UrlHelper::parse($url_string);
|
||||
|
||||
$url = Url::createFromPath($parsed_url['path']);
|
||||
|
||||
if ($url->isExternal() && !UrlHelper::isValid($url_string, TRUE)) {
|
||||
$url_is_valid = FALSE;
|
||||
}
|
||||
elseif ($url->isExternal() && !($link_type & LinkItemInterface::LINK_EXTERNAL)) {
|
||||
$url_is_valid = FALSE;
|
||||
}
|
||||
}
|
||||
catch (NotFoundHttpException $e) {
|
||||
$url_is_valid = FALSE;
|
||||
}
|
||||
catch (MatchingRouteNotFoundException $e) {
|
||||
$url_is_valid = FALSE;
|
||||
}
|
||||
catch (ParamNotConvertedException $e) {
|
||||
$url_is_valid = FALSE;
|
||||
}
|
||||
}
|
||||
if (!$url_is_valid) {
|
||||
$this->context->addViolation($this->message, array('%url' => $url_string));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,8 +7,9 @@
|
|||
|
||||
namespace Drupal\link\Tests;
|
||||
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
use Drupal\Component\Utility\String;
|
||||
use Drupal\link\LinkItemInterface;
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
|
||||
/**
|
||||
* Tests link field widgets and formatters.
|
||||
|
@ -73,14 +74,16 @@ class LinkFieldTest extends WebTestBase {
|
|||
'type' => 'link',
|
||||
));
|
||||
$this->field->save();
|
||||
entity_create('field_instance_config', array(
|
||||
$this->instance = entity_create('field_instance_config', array(
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => 'entity_test',
|
||||
'bundle' => 'entity_test',
|
||||
'settings' => array(
|
||||
'title' => DRUPAL_DISABLED,
|
||||
'link_type' => LinkItemInterface::LINK_GENERIC,
|
||||
),
|
||||
))->save();
|
||||
));
|
||||
$this->instance->save();
|
||||
entity_get_form_display('entity_test', 'entity_test', 'default')
|
||||
->setComponent($field_name, array(
|
||||
'type' => 'link_default',
|
||||
|
@ -100,21 +103,16 @@ class LinkFieldTest extends WebTestBase {
|
|||
$this->assertFieldByName("{$field_name}[0][url]", '', 'Link URL field is displayed');
|
||||
$this->assertRaw('placeholder="http://example.com"');
|
||||
|
||||
// Verify that a valid URL can be submitted.
|
||||
$value = 'http://www.example.com/';
|
||||
$edit = array(
|
||||
'user_id' => 1,
|
||||
'name' => $this->randomName(),
|
||||
"{$field_name}[0][url]" => $value,
|
||||
// Define some valid URLs.
|
||||
$valid_external_entries = array(
|
||||
'http://www.example.com/',
|
||||
);
|
||||
$valid_internal_entries = array(
|
||||
'entity_test/add',
|
||||
);
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
preg_match('|entity_test/manage/(\d+)|', $this->url, $match);
|
||||
$id = $match[1];
|
||||
$this->assertText(t('entity_test @id has been created.', array('@id' => $id)));
|
||||
$this->assertRaw($value);
|
||||
|
||||
// Verify that invalid URLs cannot be submitted.
|
||||
$wrong_entries = array(
|
||||
// Define some invalid URLs.
|
||||
$invalid_external_entries = array(
|
||||
// Missing protcol
|
||||
'not-an-url',
|
||||
// Invalid protocol
|
||||
|
@ -122,14 +120,66 @@ class LinkFieldTest extends WebTestBase {
|
|||
// Missing host name
|
||||
'http://',
|
||||
);
|
||||
$this->drupalGet('entity_test/add');
|
||||
foreach ($wrong_entries as $invalid_value) {
|
||||
$invalid_internal_entries = array(
|
||||
'non/existing/path',
|
||||
);
|
||||
|
||||
// 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 '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 '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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that valid URLs can be submitted.
|
||||
*
|
||||
* @param string $field_name
|
||||
* The field name.
|
||||
* @param array $valid_entries
|
||||
* An array of valid URL entries.
|
||||
*/
|
||||
protected function assertValidEntries($field_name, array $valid_entries) {
|
||||
foreach ($valid_entries as $value) {
|
||||
$edit = array(
|
||||
'user_id' => 1,
|
||||
'name' => $this->randomName(),
|
||||
"{$field_name}[0][url]" => $value,
|
||||
);
|
||||
$this->drupalPostForm('entity_test/add', $edit, t('Save'));
|
||||
preg_match('|entity_test/manage/(\d+)|', $this->url, $match);
|
||||
$id = $match[1];
|
||||
$this->assertText(t('entity_test @id has been created.', array('@id' => $id)));
|
||||
$this->assertRaw($value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that invalid URLs cannot be submitted.
|
||||
*
|
||||
* @param string $field_name
|
||||
* The field name.
|
||||
* @param array $invalid_entries
|
||||
* An array of invalid URL entries.
|
||||
*/
|
||||
protected function assertInvalidEntries($field_name, array $invalid_entries) {
|
||||
foreach ($invalid_entries as $invalid_value) {
|
||||
$edit = array(
|
||||
'user_id' => 1,
|
||||
'name' => $this->randomName(),
|
||||
"{$field_name}[0][url]" => $invalid_value,
|
||||
);
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
$this->drupalPostForm('entity_test/add', $edit, t('Save'));
|
||||
$this->assertText(t('The URL @url is not valid.', array('@url' => $invalid_value)));
|
||||
}
|
||||
}
|
||||
|
@ -153,6 +203,7 @@ class LinkFieldTest extends WebTestBase {
|
|||
'label' => 'Read more about this entity',
|
||||
'settings' => array(
|
||||
'title' => DRUPAL_OPTIONAL,
|
||||
'link_type' => LinkItemInterface::LINK_GENERIC,
|
||||
),
|
||||
));
|
||||
$this->instance->save();
|
||||
|
@ -272,6 +323,7 @@ class LinkFieldTest extends WebTestBase {
|
|||
'bundle' => 'entity_test',
|
||||
'settings' => array(
|
||||
'title' => DRUPAL_OPTIONAL,
|
||||
'link_type' => LinkItemInterface::LINK_GENERIC,
|
||||
),
|
||||
))->save();
|
||||
entity_get_form_display('entity_test', 'entity_test', 'default')
|
||||
|
@ -413,6 +465,7 @@ class LinkFieldTest extends WebTestBase {
|
|||
'bundle' => 'entity_test',
|
||||
'settings' => array(
|
||||
'title' => DRUPAL_OPTIONAL,
|
||||
'link_type' => LinkItemInterface::LINK_GENERIC,
|
||||
),
|
||||
))->save();
|
||||
$display_options = array(
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
namespace Drupal\link\Tests;
|
||||
|
||||
use Drupal\Component\Utility\UrlHelper;
|
||||
use Drupal\Core\Field\FieldItemListInterface;
|
||||
use Drupal\Core\Field\FieldItemInterface;
|
||||
use Drupal\field\Tests\FieldUnitTestBase;
|
||||
|
@ -53,12 +54,14 @@ class LinkItemTest extends FieldUnitTestBase {
|
|||
public function testLinkItem() {
|
||||
// Create entity.
|
||||
$entity = entity_create('entity_test');
|
||||
$url = 'http://www.drupal.org';
|
||||
$url = 'http://www.drupal.org?test_param=test_value';
|
||||
$parsed_url = UrlHelper::parse($url);
|
||||
$title = $this->randomName();
|
||||
$class = $this->randomName();
|
||||
$entity->field_test->url = $url;
|
||||
$entity->field_test->url = $parsed_url['path'];
|
||||
$entity->field_test->title = $title;
|
||||
$entity->field_test->first()->get('attributes')->set('class', $class);
|
||||
$entity->field_test->first()->get('options')->set('query', $parsed_url['query']);
|
||||
$entity->field_test->first()->get('options')->set('attributes', array('class' => $class));
|
||||
$entity->name->value = $this->randomName();
|
||||
$entity->save();
|
||||
|
||||
|
@ -67,11 +70,22 @@ class LinkItemTest extends FieldUnitTestBase {
|
|||
$entity = entity_load('entity_test', $id);
|
||||
$this->assertTrue($entity->field_test instanceof FieldItemListInterface, 'Field implements interface.');
|
||||
$this->assertTrue($entity->field_test[0] instanceof FieldItemInterface, 'Field item implements interface.');
|
||||
$this->assertEqual($entity->field_test->url, $url);
|
||||
$this->assertEqual($entity->field_test[0]->url, $url);
|
||||
$this->assertEqual($entity->field_test->url, $parsed_url['path']);
|
||||
$this->assertEqual($entity->field_test[0]->url, $parsed_url['path']);
|
||||
$this->assertEqual($entity->field_test->title, $title);
|
||||
$this->assertEqual($entity->field_test[0]->title, $title);
|
||||
$this->assertEqual($entity->field_test->attributes['class'], $class);
|
||||
$this->assertEqual($entity->field_test->options['attributes']['class'], $class);
|
||||
$this->assertEqual($entity->field_test->options['query'], $parsed_url['query']);
|
||||
|
||||
// Update only the entity name property to check if the link field data will
|
||||
// remain intact.
|
||||
$entity->name->value = $this->randomName();
|
||||
$entity->save();
|
||||
$id = $entity->id();
|
||||
$entity = entity_load('entity_test', $id);
|
||||
$this->assertEqual($entity->field_test->url, $parsed_url['path']);
|
||||
$this->assertEqual($entity->field_test->options['attributes']['class'], $class);
|
||||
$this->assertEqual($entity->field_test->options['query'], $parsed_url['query']);
|
||||
|
||||
// Verify changing the field value.
|
||||
$new_url = 'http://drupal.org';
|
||||
|
@ -79,17 +93,19 @@ class LinkItemTest extends FieldUnitTestBase {
|
|||
$new_class = $this->randomName();
|
||||
$entity->field_test->url = $new_url;
|
||||
$entity->field_test->title = $new_title;
|
||||
$entity->field_test->first()->get('attributes')->set('class', $new_class);
|
||||
$entity->field_test->first()->get('options')->set('query', NULL);
|
||||
$entity->field_test->first()->get('options')->set('attributes', array('class' => $new_class));
|
||||
$this->assertEqual($entity->field_test->url, $new_url);
|
||||
$this->assertEqual($entity->field_test->title, $new_title);
|
||||
$this->assertEqual($entity->field_test->attributes['class'], $new_class);
|
||||
$this->assertEqual($entity->field_test->options['attributes']['class'], $new_class);
|
||||
$this->assertNull($entity->field_test->options['query']);
|
||||
|
||||
// Read changed entity and assert changed values.
|
||||
$entity->save();
|
||||
$entity = entity_load('entity_test', $id);
|
||||
$this->assertEqual($entity->field_test->url, $new_url);
|
||||
$this->assertEqual($entity->field_test->title, $new_title);
|
||||
$this->assertEqual($entity->field_test->attributes['class'], $new_class);
|
||||
$this->assertEqual($entity->field_test->options['attributes']['class'], $new_class);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ function link_help($path, $arg) {
|
|||
case 'admin/help#link':
|
||||
$output = '';
|
||||
$output .= '<h3>' . t('About') . '</h3>';
|
||||
$output .= '<p>' . t('The Link module allows you to create fields that contain external URLs and optional link text. See the <a href="!field">Field module help</a> and the <a href="!field_ui">Field UI help</a> pages for general information on fields and how to create and manage them. For more information, see the <a href="!link_documentation">online documentation for the Link module</a>.', array('!field' => \Drupal::url('help.page', array('name' => 'field')), '!field_ui' => \Drupal::url('help.page', array('name' => 'field_ui')), '!link_documentation' => 'https://drupal.org/documentation/modules/link')) . '</p>';
|
||||
$output .= '<p>' . t('The Link module allows you to create fields that contain internal or external URLs and optional link text. See the <a href="!field">Field module help</a> and the <a href="!field_ui">Field UI help</a> pages for general information on fields and how to create and manage them. For more information, see the <a href="!link_documentation">online documentation for the Link module</a>.', array('!field' => \Drupal::url('help.page', array('name' => 'field')), '!field_ui' => \Drupal::url('help.page', array('name' => 'field_ui')), '!link_documentation' => 'https://drupal.org/documentation/modules/link')) . '</p>';
|
||||
$output .= '<h3>' . t('Uses') . '</h3>';
|
||||
$output .= '<dl>';
|
||||
$output .= '<dt>' . t('Managing and displaying link fields') . '</dt>';
|
||||
|
@ -27,7 +27,7 @@ function link_help($path, $arg) {
|
|||
$output .= '<dt>' . t('Adding attributes to links') . '</dt>';
|
||||
$output .= '<dd>' . t('You can add attributes to links, by changing the <em>Format settings</em> in the <em>Manage display</em> page. Adding <em>rel="nofollow"</em> notifies search engines that links should not be followed.') . '</dd>';
|
||||
$output .= '<dt>' . t('Validating URLs') . '</dt>';
|
||||
$output .= '<dd>' . t('All links are validated after a link field is filled in. They can include anchors or query strings. Links need to start with either the scheme name <em>http</em> or <em>https</em>; other scheme names (for example ftp or git) are not supported.') . '</dd>';
|
||||
$output .= '<dd>' . t('All links are validated after a link field is filled in. They can include anchors or query strings.') . '</dd>';
|
||||
$output .= '</dl>';
|
||||
return $output;
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ function link_help($path, $arg) {
|
|||
function link_theme() {
|
||||
return array(
|
||||
'link_formatter_link_separate' => array(
|
||||
'variables' => array('title' => NULL, 'url_title' => NULL, 'href' => NULL, 'options' => array()),
|
||||
'variables' => array('title' => NULL, 'url_title' => NULL, 'url' => NULL),
|
||||
'template' => 'link-formatter-link-separate',
|
||||
),
|
||||
);
|
||||
|
@ -57,12 +57,17 @@ function link_theme() {
|
|||
* - title: (optional) A descriptive or alternate title for the link, which
|
||||
* may be different than the actual link text.
|
||||
* - url_title: The anchor text for the link.
|
||||
* - href: The link URL.
|
||||
* - options: (optional) An array of options to pass to l().
|
||||
* - url: A \Drupal\Core\Url object.
|
||||
*/
|
||||
function template_preprocess_link_formatter_link_separate(&$variables) {
|
||||
if (!empty($variables['title'])) {
|
||||
$variables['title'] = String::checkPlain($variables['title']);
|
||||
}
|
||||
$variables['link'] = l($variables['url_title'], $variables['href'], $variables['options']);
|
||||
|
||||
if (!$variables['url']->isExternal()) {
|
||||
$variables['link'] = \Drupal::linkGenerator()->generateFromUrl($variables['url_title'], $variables['url']);
|
||||
}
|
||||
else {
|
||||
$variables['link'] = l($variables['url_title'], $variables['url']->getPath(), $variables['url']->getOptions());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -142,8 +142,7 @@ class ExternalUrlTest extends UnitTestCase {
|
|||
*/
|
||||
public function testToArray(Url $url) {
|
||||
$expected = array(
|
||||
'route_name' => '',
|
||||
'route_parameters' => array(),
|
||||
'path' => $this->path,
|
||||
'options' => array(),
|
||||
);
|
||||
$this->assertSame($expected, $url->toArray());
|
||||
|
@ -154,10 +153,12 @@ class ExternalUrlTest extends UnitTestCase {
|
|||
*
|
||||
* @depends testCreateFromPath
|
||||
*
|
||||
* @expectedException \UnexpectedValueException
|
||||
*
|
||||
* @covers ::getRouteName()
|
||||
*/
|
||||
public function testGetRouteName(Url $url) {
|
||||
$this->assertSame('', $url->getRouteName());
|
||||
$url->getRouteName();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -165,10 +166,12 @@ class ExternalUrlTest extends UnitTestCase {
|
|||
*
|
||||
* @depends testCreateFromPath
|
||||
*
|
||||
* @expectedException \UnexpectedValueException
|
||||
*
|
||||
* @covers ::getRouteParameters()
|
||||
*/
|
||||
public function testGetRouteParameters(Url $url) {
|
||||
$this->assertSame(array(), $url->getRouteParameters());
|
||||
$url->getRouteParameters();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -184,6 +187,17 @@ class ExternalUrlTest extends UnitTestCase {
|
|||
$this->assertNull($url->getInternalPath());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the getPath() method.
|
||||
*
|
||||
* @depends testCreateFromPath
|
||||
*
|
||||
* @covers ::getPath()
|
||||
*/
|
||||
public function testGetPath(Url $url) {
|
||||
$this->assertNotNull($url->getPath());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the getOptions() method.
|
||||
*
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
namespace Drupal\Tests\Core;
|
||||
|
||||
use Drupal\Component\Utility\UrlHelper;
|
||||
use Drupal\Core\DependencyInjection\ContainerBuilder;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
@ -201,6 +202,31 @@ class UrlTest extends UnitTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the getPath() method for internal URLs.
|
||||
*
|
||||
* @depends testCreateFromPath
|
||||
*
|
||||
* @expectedException \UnexpectedValueException
|
||||
*
|
||||
* @covers ::getPath()
|
||||
*/
|
||||
public function testGetPathForInternalUrl($urls) {
|
||||
foreach ($urls as $url) {
|
||||
$url->getPath();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the getPath() method for external URLs.
|
||||
*
|
||||
* @covers ::getPath
|
||||
*/
|
||||
public function testGetPathForExternalUrl() {
|
||||
$url = Url::createFromPath('http://example.com/test');
|
||||
$this->assertEquals('http://example.com/test', $url->getPath());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the toString() method.
|
||||
*
|
||||
|
@ -255,6 +281,17 @@ class UrlTest extends UnitTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the getRouteName() with an external URL.
|
||||
*
|
||||
* @covers ::getRouteName
|
||||
* @expectedException \UnexpectedValueException
|
||||
*/
|
||||
public function testGetRouteNameWithExternalUrl() {
|
||||
$url = Url::createFromPath('http://example.com');
|
||||
$url->getRouteName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the getRouteParameters() method.
|
||||
*
|
||||
|
@ -271,6 +308,17 @@ class UrlTest extends UnitTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the getRouteParameter() with an external URL.
|
||||
*
|
||||
* @covers ::getRouteParameter
|
||||
* @expectedException \UnexpectedValueException
|
||||
*/
|
||||
public function testGetRouteParametersWithExternalUrl() {
|
||||
$url = Url::createFromPath('http://example.com');
|
||||
$url->getRouteParameters();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the getOptions() method.
|
||||
*
|
||||
|
|
|
@ -42,13 +42,6 @@ class LinkGeneratorTest extends UnitTestCase {
|
|||
*/
|
||||
protected $moduleHandler;
|
||||
|
||||
/**
|
||||
* The mocked path alias manager.
|
||||
*
|
||||
* @var \Drupal\Core\Path\AliasManagerInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $aliasManager;
|
||||
|
||||
/**
|
||||
* Contains the LinkGenerator default options.
|
||||
*/
|
||||
|
@ -80,9 +73,8 @@ class LinkGeneratorTest extends UnitTestCase {
|
|||
|
||||
$this->urlGenerator = $this->getMock('\Drupal\Core\Routing\UrlGenerator', array(), array(), '', FALSE);
|
||||
$this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface');
|
||||
$this->aliasManager = $this->getMock('\Drupal\Core\Path\AliasManagerInterface');
|
||||
|
||||
$this->linkGenerator = new LinkGenerator($this->urlGenerator, $this->moduleHandler, $this->aliasManager);
|
||||
$this->linkGenerator = new LinkGenerator($this->urlGenerator, $this->moduleHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -344,14 +336,6 @@ class LinkGeneratorTest extends UnitTestCase {
|
|||
array('test_route_4', array('object' => '1'), 'test-route-4/1'),
|
||||
)));
|
||||
|
||||
$this->aliasManager->expects($this->exactly(7))
|
||||
->method('getSystemPath')
|
||||
->will($this->returnValueMap(array(
|
||||
array('test-route-1', NULL, 'test-route-1'),
|
||||
array('test-route-3', NULL, 'test-route-3'),
|
||||
array('test-route-4/1', NULL, 'test-route-4/1'),
|
||||
)));
|
||||
|
||||
$this->moduleHandler->expects($this->exactly(8))
|
||||
->method('alter');
|
||||
|
||||
|
|
Loading…
Reference in New Issue