You are here

function ds_entity_view_alter in Display Suite 8.3

Same name and namespace in other branches
  1. 8.4 ds.module \ds_entity_view_alter()
  2. 8.2 ds.module \ds_entity_view_alter()

Implements hook_entity_view_alter().

File

./ds.module, line 260
Display Suite core functions.

Code

function ds_entity_view_alter(&$build, EntityInterface $entity, EntityDisplayInterface $display) {
  static $field_permissions = FALSE;
  static $loaded = FALSE;
  $entity_type = $entity
    ->getEntityTypeId();
  $bundle = $entity
    ->bundle();
  $view_mode = $display
    ->getMode();

  // Add extra metadata needed for contextual links.
  if (isset($build['#contextual_links'][$entity_type])) {
    $build['#contextual_links'][$entity_type]['metadata']['ds_bundle'] = $bundle;
    $build['#contextual_links'][$entity_type]['metadata']['ds_view_mode'] = $view_mode;
  }

  // If no layout is configured, stop executing.
  if (!$display
    ->getThirdPartySetting('ds', 'layout')) {
    return;
  }

  // If Display Suite is disabled, stop here.
  if (Ds::isDisabled()) {
    return;
  }

  // Load field permissions and layouts only once.
  if (!$loaded) {
    $loaded = TRUE;
    $field_permissions = \Drupal::config('ds_extras.settings')
      ->get('field_permissions');
  }

  // Get configuration.
  $configuration = $display
    ->getThirdPartySettings('ds');

  // Don't fatal on missing layout plugins.
  $layout_id = isset($configuration['layout']['id']) ? $configuration['layout']['id'] : '';
  if (!Ds::layoutExists($layout_id)) {
    return;
  }

  // Put #entity_type, #bundle and #layout on the build so we can access it in
  // ds_entity_variables().
  $build['#entity_type'] = $entity_type;
  $build['#bundle'] = $bundle;
  $build['#ds_configuration'] = $configuration;
  $build['#entity'] = $entity;

  // Implement UI limit.
  $components = $display
    ->getComponents();
  foreach ($components as $field => $component) {
    if (isset($component['third_party_settings']['ds']) && !empty($component['third_party_settings']['ds']['ds_limit'])) {
      $limit = $component['third_party_settings']['ds']['ds_limit'];
      if (isset($build[$field]) && isset($build[$field]['#items'])) {
        if ($limit === 'delta' && isset($build['#ds_delta']) && isset($build['#ds_delta'][$field])) {

          // Get delta.
          $delta = $build['#ds_delta'][$field];

          // Remove caching for this entity as it otherwise won't work.
          unset($build['#cache']);
          $filtered_elements = Element::children($build[$field]);
          foreach ($filtered_elements as $filtered_element) {
            if ($filtered_element != $delta) {
              unset($build[$field][$filtered_element]);
            }
          }
        }
        elseif (is_numeric($limit)) {

          // Remove caching for this entity as it otherwise won't work.
          unset($build['#cache']);
          $filtered_elements = Element::children($build[$field]);
          $filtered_elements = array_slice($filtered_elements, $limit);
          foreach ($filtered_elements as $filtered_element) {
            unset($build[$field][$filtered_element]);
          }
        }
      }
    }
  }

  // Add Display Suite fields.
  $fields = Ds::getFields($entity_type);
  $field_values = !empty($configuration['fields']) ? $configuration['fields'] : [];
  foreach ($configuration['regions'] as $region) {
    foreach ($region as $weight => $key) {

      // Ignore if this field is not a DS field, just pull it in from the
      // entity.
      if (!isset($fields[$key])) {
        continue;
      }
      $field = $fields[$key];
      if (isset($field_values[$key]['formatter'])) {
        $field['formatter'] = $field_values[$key]['formatter'];
      }
      if (isset($field_values[$key]['settings'])) {
        $field['settings'] = $field_values[$key]['settings'];
      }
      $field_instance = Ds::getFieldInstance($key, $field, $entity, $view_mode, $display, $build);
      $field_value = $field_instance
        ->build();
      $field_title = $field_instance
        ->getTitle();

      // If the field value is cache data then we presume the value was empty
      // and we just have cache data as to why it's empty.
      if ($field_value instanceof CacheableMetadata) {
        CacheableMetadata::createFromRenderArray($build)
          ->merge($field_value)
          ->applyTo($build);
      }
      elseif (!empty($field_value)) {
        $build[$key] = [
          '#theme' => 'field',
          '#field_type' => 'ds',
          '#title' => $field_title,
          '#weight' => isset($field_values[$key]['weight']) ? $field_values[$key]['weight'] : $weight,
          '#label_display' => isset($field_values[$key]['label']) ? $field_values[$key]['label'] : 'inline',
          '#field_name' => $key,
          '#bundle' => $bundle,
          '#object' => $entity,
          '#entity_type' => $entity_type,
          '#view_mode' => '_custom',
          '#ds_view_mode' => $view_mode,
          '#items' => [
            (object) [
              '_attributes' => [],
            ],
          ],
          '#is_multiple' => $field_instance
            ->isMultiple(),
          '#access' => $field_permissions && function_exists('ds_extras_ds_field_access') ? ds_extras_ds_field_access($key, $entity_type) : TRUE,
          '#formatter' => 'ds_field',
        ];
        if ($field_instance
          ->isMultiple()) {
          $build[$key] += $field_value;
        }
        else {
          $build[$key][0] = [
            $field_value,
          ];
        }
      }
    }
  }

  // Defer to ds_entity_view theme hook to actually render the layout.
  $build['#theme'] = 'ds_entity_view';
}