You are here

protected function FieldPluginBase::renderAsLink in Zircon Profile 8

Same name and namespace in other branches
  1. 8.0 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 1351
Contains \Drupal\views\Plugin\views\field\FieldPluginBase.

Class

FieldPluginBase
Base class for views fields.

Namespace

Drupal\views\Plugin\views\field

Code

protected function renderAsLink($alter, $text, $tokens) {
  $options = array(
    'absolute' => !empty($alter['absolute']) ? TRUE : FALSE,
    'alias' => FALSE,
    'entity' => NULL,
    'entity_type' => NULL,
    'fragment' => NULL,
    'language' => NULL,
    'query' => [],
  );
  $alter += [
    'path' => NULL,
  ];
  $path = $alter['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();

  // strip_tags() removes <front>, so check whether its different to front.
  if ($path != 'route:<front>') {

    // Unescape Twig delimiters that may have been escaped by the
    // Url::toUriString() call above, because we support twig tokens in
    // rewrite settings of views fields.
    // In that case the original path looks like
    // internal:/admin/content/files/usage/{{ fid }}, which will be escaped by
    // the toUriString() call above.
    $path = preg_replace([
      '/(\\%7B){2}(\\%20)*/',
      '/(\\%20)*(\\%7D){2}/',
    ], [
      '{{',
      '}}',
    ], $path);

    // Use strip tags as there should never be HTML in the path.
    // However, we need to preserve special characters like " that are escaped
    // by \Drupal\Component\Utility\Html::escape().
    $path = strip_tags(Html::decodeEntities($this
      ->viewsTokenReplace($path, $tokens)));
    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 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 on for external URLs.
  if ($alter['external']) {
    if (!isset($url['scheme'])) {

      // There is no scheme, add the default 'http://' to the $path.
      // Use the original $alter['path'] instead of the parsed version.
      $path = "http://" . $alter['path'];

      // Reset the $url array to include the new scheme.
      $url = UrlHelper::parse($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, array(
      '#' . $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'] = array(
      $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 = array();
    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);
}