protected function FieldPluginBase::renderAsLink in Drupal 9
Same name and namespace in other branches
- 8 core/modules/views/src/Plugin/views/field/FieldPluginBase.php \Drupal\views\Plugin\views\field\FieldPluginBase::renderAsLink()
Render this field as a link, with the info from a fieldset set by the user.
1 call to FieldPluginBase::renderAsLink()
- FieldPluginBase::renderText in core/
modules/ views/ src/ Plugin/ views/ field/ FieldPluginBase.php - Performs an advanced text render for the item.
File
- core/
modules/ views/ src/ Plugin/ views/ field/ FieldPluginBase.php, line 1387
Class
- FieldPluginBase
- Base class for views fields.
Namespace
Drupal\views\Plugin\views\fieldCode
protected function renderAsLink($alter, $text, $tokens) {
$options = [
'absolute' => !empty($alter['absolute']) ? TRUE : FALSE,
'alias' => FALSE,
'entity' => NULL,
'entity_type' => NULL,
'fragment' => NULL,
'language' => NULL,
'query' => [],
];
$alter += [
'path' => NULL,
];
$path = $alter['path'];
// strip_tags() and viewsTokenReplace remove <front>, so check whether it's
// different to front.
if ($path != '<front>') {
// Use strip_tags as there should never be HTML in the path.
// However, we need to preserve special characters like " that were
// removed by Html::escape().
$path = Html::decodeEntities($this
->viewsTokenReplace($alter['path'], $tokens));
// Tokens might contain <front>, so check for <front> again.
if ($path != '<front>') {
$path = strip_tags($path);
}
// Tokens might have resolved URL's, as is the case for tokens provided by
// Link fields, so all internal paths will be prefixed by base_path(). For
// proper further handling reset this to internal:/.
if (strpos($path, base_path()) === 0) {
$path = 'internal:/' . substr($path, strlen(base_path()));
}
// If we have no $path and no $alter['url'], we have nothing to work with,
// so we just return the text.
if (empty($path) && empty($alter['url'])) {
return $text;
}
// If no scheme is provided in the $path, assign the default 'http://'.
// This allows a url of 'www.example.com' to be converted to
// 'http://www.example.com'.
// Only do this when flag for external has been set, $path doesn't contain
// a scheme and $path doesn't have a leading /.
if ($alter['external'] && !parse_url($path, PHP_URL_SCHEME) && strpos($path, '/') !== 0) {
// There is no scheme, add the default 'http://' to the $path.
$path = "http://" . $path;
}
}
if (empty($alter['url'])) {
if (!parse_url($path, PHP_URL_SCHEME)) {
// @todo Views should expect and store a leading /. See
// https://www.drupal.org/node/2423913.
$alter['url'] = CoreUrl::fromUserInput('/' . ltrim($path, '/'));
}
else {
$alter['url'] = CoreUrl::fromUri($path);
}
}
$options = $alter['url']
->getOptions() + $options;
$path = $alter['url']
->setOptions($options)
->toUriString();
if (!empty($alter['path_case']) && $alter['path_case'] != 'none' && !$alter['url']
->isRouted()) {
$path = str_replace($alter['path'], $this
->caseTransform($alter['path'], $this->options['alter']['path_case']), $path);
}
if (!empty($alter['replace_spaces'])) {
$path = str_replace(' ', '-', $path);
}
// Parse the URL and move any query and fragment parameters out of the path.
$url = UrlHelper::parse($path);
// Seriously malformed URLs may return FALSE or empty arrays.
if (empty($url)) {
return $text;
}
// If the path is empty do not build a link around the given text and return
// it as is.
// http://www.example.com URLs will not have a $url['path'], so check host as well.
if (empty($url['path']) && empty($url['host']) && empty($url['fragment']) && empty($url['url'])) {
return $text;
}
// If we get to here we have a path from the url parsing. So assign that to
// $path now so we don't get query strings or fragments in the path.
$path = $url['path'];
if (isset($url['query'])) {
// Remove query parameters that were assigned a query string replacement
// token for which there is no value available.
foreach ($url['query'] as $param => $val) {
if ($val == '%' . $param) {
unset($url['query'][$param]);
}
// Replace any empty query params from URL parsing with NULL. So the
// query will get built correctly with only the param key.
// @see \Drupal\Component\Utility\UrlHelper::buildQuery().
if ($val === '') {
$url['query'][$param] = NULL;
}
}
$options['query'] = $url['query'];
}
if (isset($url['fragment'])) {
$path = strtr($path, [
'#' . $url['fragment'] => '',
]);
// If the path is empty we want to have a fragment for the current site.
if ($path == '') {
$options['external'] = TRUE;
}
$options['fragment'] = $url['fragment'];
}
$alt = $this
->viewsTokenReplace($alter['alt'], $tokens);
// Set the title attribute of the link only if it improves accessibility
if ($alt && $alt != $text) {
$options['attributes']['title'] = Html::decodeEntities($alt);
}
$class = $this
->viewsTokenReplace($alter['link_class'], $tokens);
if ($class) {
$options['attributes']['class'] = [
$class,
];
}
if (!empty($alter['rel']) && ($rel = $this
->viewsTokenReplace($alter['rel'], $tokens))) {
$options['attributes']['rel'] = $rel;
}
$target = trim($this
->viewsTokenReplace($alter['target'], $tokens));
if (!empty($target)) {
$options['attributes']['target'] = $target;
}
// Allow the addition of arbitrary attributes to links. Additional attributes
// currently can only be altered in preprocessors and not within the UI.
if (isset($alter['link_attributes']) && is_array($alter['link_attributes'])) {
foreach ($alter['link_attributes'] as $key => $attribute) {
if (!isset($options['attributes'][$key])) {
$options['attributes'][$key] = $this
->viewsTokenReplace($attribute, $tokens);
}
}
}
// If the query and fragment were programmatically assigned overwrite any
// parsed values.
if (isset($alter['query'])) {
// Convert the query to a string, perform token replacement, and then
// convert back to an array form for
// \Drupal\Core\Utility\LinkGeneratorInterface::generate().
$options['query'] = UrlHelper::buildQuery($alter['query']);
$options['query'] = $this
->viewsTokenReplace($options['query'], $tokens);
$query = [];
parse_str($options['query'], $query);
$options['query'] = $query;
}
if (isset($alter['alias'])) {
// Alias is a boolean field, so no token.
$options['alias'] = $alter['alias'];
}
if (isset($alter['fragment'])) {
$options['fragment'] = $this
->viewsTokenReplace($alter['fragment'], $tokens);
}
if (isset($alter['language'])) {
$options['language'] = $alter['language'];
}
// If the url came from entity_uri(), pass along the required options.
if (isset($alter['entity'])) {
$options['entity'] = $alter['entity'];
}
if (isset($alter['entity_type'])) {
$options['entity_type'] = $alter['entity_type'];
}
// The path has been heavily processed above, so it should be used as-is.
$final_url = CoreUrl::fromUri($path, $options);
// Build the link based on our altered Url object, adding on the optional
// prefix and suffix
$render = [
'#type' => 'link',
'#title' => $text,
'#url' => $final_url,
];
if (!empty($alter['prefix'])) {
$render['#prefix'] = $this
->viewsTokenReplace($alter['prefix'], $tokens);
}
if (!empty($alter['suffix'])) {
$render['#suffix'] = $this
->viewsTokenReplace($alter['suffix'], $tokens);
}
return $this
->getRenderer()
->render($render);
}