You are here

public function Link::render in Views link area 8

Render the area.

Parameters

bool $empty: (optional) Indicator if view result is empty or not. Defaults to FALSE.

Return value

array In any case we need a valid Drupal render array to return.

Overrides AreaPluginBase::render

File

src/Plugin/views/area/Link.php, line 259

Class

Link
Views area Link handler.

Namespace

Drupal\views_linkarea\Plugin\views\area

Code

public function render($empty = FALSE) {

  // Note: Method adapted from the renderAsLinkmethod from
  // Drupal\views\Plugin\views\field\FieldPluginBase.
  if ($empty && empty($this->options['empty'])) {
    return [];
  }
  $options = [
    'absolute' => !empty($this->options['absolute']) ? TRUE : FALSE,
    'alias' => FALSE,
    'entity' => NULL,
    'entity_type' => NULL,
    'fragment' => NULL,
    'language' => NULL,
    'query' => [],
  ];
  $path = $this->options['path'];
  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 SafeMarkup::checkPlain().
    $path = Html::decodeEntities($this
      ->tokenizeValue($path));

    // 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 the base url
    // from the request context. For proper further handling reset this to
    // internal:/.
    $base_path = $this->context
      ->getBaseUrl() . '/';
    if (strpos($path, $base_path) === 0) {
      $path = 'internal:/' . substr($path, strlen($base_path));
    }

    // If we have no $path and no $url_info['url'], we have nothing to work
    // with, so we just return the text.
    if (empty($path)) {
      return $this->options['link_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 ($this->options['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 (!parse_url($path, PHP_URL_SCHEME)) {
    $url = Url::fromUserInput('/' . ltrim($path, '/'));
  }
  else {
    $url = Url::fromUri($path);
  }
  $options = $url
    ->getOptions() + $options;
  $path = $url
    ->setOptions($options)
    ->toUriString();
  if (!empty($this->options['path_case']) && $this->options['path_case'] != 'none' && !$url
    ->isRouted()) {
    $path = str_replace($this->options['path'], $this
      ->caseTransform($this->options['path'], $this->options['path_case']), $path);
  }
  if (!empty($url_info['replace_spaces'])) {
    $path = str_replace(' ', '-', $path);
  }

  // Parse the URL and move any query and fragment parameters out of the path.
  $url_parts = UrlHelper::parse($path);

  // Seriously malformed URLs may return FALSE or empty arrays.
  if (empty($url_parts)) {
    return $this->options['link_text'];
  }

  // If the path is empty do not build a link around the given text and return
  // it as is.
  if (empty($url_parts['path']) && empty($url_parts['fragment']) && empty($url_parts['url'])) {
    return $this->options['link_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_parts['path'];
  if (isset($url_parts['query'])) {

    // Remove query parameters that were assigned a query string replacement
    // token for which there is no value available.
    foreach ($url_parts['query'] as $param => $val) {
      if ($val == '%' . $param) {
        unset($url_parts['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_parts['query'][$param] = NULL;
      }
    }
    $options['query'] = $url_parts['query'];
  }
  if (isset($url_parts['fragment'])) {
    $path = strtr($path, [
      '#' . $url_parts['fragment'] => '',
    ]);

    // If the path is empty we want to have a fragment for the current site.
    if ($path == '') {
      $options['external'] = TRUE;
    }
    $options['fragment'] = $url_parts['fragment'];
  }
  $alt = $this
    ->tokenizeValue($this->options['alt']);

  // Set the title attribute of the link only if it improves accessibility.
  if ($alt && $alt != $this->options['link_text']) {
    $options['attributes']['title'] = Html::decodeEntities($alt);
  }
  $class = $this
    ->tokenizeValue($this->options['link_class']);
  if ($class) {
    $options['attributes']['class'] = [
      $class,
    ];
  }
  if (!empty($this->options['rel']) && ($rel = $this
    ->tokenizeValue($this->options['rel']))) {
    $options['attributes']['rel'] = $rel;
  }
  $target = trim($this
    ->tokenizeValue($this->options['target']));
  if (!empty($target)) {
    $options['attributes']['target'] = $target;
  }
  if (!empty($this->options['destination'])) {
    $options['query'] += \Drupal::destination()
      ->getAsArray();
  }
  if ($this->languageManager
    ->isMultilingual() && $this->options['language'] !== '**auto**') {
    $options['language'] = $this->languageManager
      ->getLanguage($this->options['language']);
  }
  return $this
    ->renderUrl(Url::fromUri($path, $options));
}