You are here

function linked_field_entity_display_build_alter in Linked Field 8

Implements hook_entity_display_build_alter().

Parameters

array $build: A render array.

array $context: An associative array.

File

./linked_field.module, line 350
Main file of Linked Field module.

Code

function linked_field_entity_display_build_alter(array &$build, array $context) {

  /** @var \Drupal\linked_field\LinkedFieldManager $manager */
  $manager = \Drupal::service('linked_field.manager');
  foreach (Element::children($build) as $field_name) {
    $element =& $build[$field_name];
    $settings = $manager
      ->getFieldDisplaySettings($context['display'], $field_name);

    // Continue to next if no Linked Field settings were found.
    if (!count($settings)) {
      continue;
    }

    // Normalize the settings.
    $destination = isset($settings['destination']) ? $settings['destination'] : FALSE;
    $linked = isset($settings['linked']) ? $settings['linked'] : FALSE;
    $destination_type = isset($settings['type']) ? $settings['type'] : 'custom';

    // If the destination field isn't filled for this field, we shouldn't
    // do anything. Continue to the next field.
    if (!$destination || !$linked) {
      continue;
    }
    if (isset($element['#entity_type']) && isset($element['#object'])) {
      $replace_tokens = [
        $element['#entity_type'] => $element['#object'],
      ];
    }
    else {
      $replace_tokens = [];
    }
    foreach (Element::children($element) as $delta) {
      $destination = $manager
        ->getDestination($destination_type, $destination, $context);

      // We need special handling for the token destination type.
      if ($destination_type == 'custom') {
        $destination = $manager
          ->replaceToken($destination, $replace_tokens, [
          'clear' => TRUE,
        ]);

        // Try to grab the href attribute if the replaced token is a link.
        preg_match('/<a.* href="([^"]+)".*>/', $destination, $match);
        $destination = isset($match[1]) ? $match[1] : $destination;
      }
      $attributes = [
        'href' => '',
      ];
      foreach ($settings['advanced'] as $attribute => $value) {
        if ($attribute == 'text') {
          continue;
        }
        $attributes[$attribute] = Html::escape($manager
          ->replaceToken($value, $replace_tokens, [
          'clear' => TRUE,
        ]));
      }

      // Would be better to have own set with allowed tags so that only
      // inline elements are allowed.
      $text = '';
      if (isset($settings['advanced']['text'])) {
        $text = Xss::filterAdmin($manager
          ->replaceToken($settings['advanced']['text'], $replace_tokens, [
          'clear' => TRUE,
        ]));
      }

      // Continue to next field if destination is empty.
      if (!$destination) {
        continue;
      }
      $url = $manager
        ->buildDestinationUrl($destination);
      if (!$url) {
        continue;
      }

      // Finally set 'href' attribute for link.
      $attributes['href'] = $url;

      // Render the field if no custom text was set in the configuration.
      if (!$text) {
        $renderer = \Drupal::service('renderer');
        if ($renderer
          ->hasRenderContext()) {
          $rendered = $renderer
            ->render($element[$delta]);
        }
        else {
          $rendered = $renderer
            ->renderRoot($element[$delta]);
        }
      }
      else {
        $rendered = $text;
      }
      $build[$field_name][$delta] = [
        '#markup' => $manager
          ->linkHtml($rendered, $attributes),
      ];
    }
  }
}