Verified Commit cc1bc30d authored by Alex Pott's avatar Alex Pott
Browse files

Issue #2981047 by owenbush, jibran, tstoeckler, alexpott, TwoD, wells,...

Issue #2981047 by owenbush, jibran, tstoeckler, alexpott, TwoD, wells, joachim, k4v, ankithashetty, ranjith_kumar_k_u, Prem Suthar, larowlan, Lendude, tim.plunkett, Sam152, claudiu.cristea: Allow adding computed bundle fields in Views
parent 201fd312
Loading
Loading
Loading
Loading
Loading
+91 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\entity_test\Entity;

use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Field\FieldDefinition;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\entity_test\FieldStorageDefinition;
use Drupal\entity_test\Plugin\Field\ComputedReferenceTestFieldItemList;
use Drupal\entity_test\Plugin\Field\ComputedTestBundleFieldItemList;
use Drupal\entity_test\Plugin\Field\ComputedTestCacheableStringItemList;
use Drupal\entity_test\Plugin\Field\ComputedTestFieldItemList;

/**
 * An entity used for testing computed bundle field values.
 *
 * @ContentEntityType(
 *   id = "entity_test_comp_bund_fld",
 *   label = @Translation("Entity Test computed bundle field"),
 *   base_table = "entity_test_comp_bund_fld",
 *   handlers = {
 *     "views_data" = "Drupal\entity_test\EntityTestViewsData"
 *   },
 *   entity_keys = {
 *     "id" = "id",
 *     "uuid" = "uuid",
 *     "label" = "name",
 *     "bundle" = "type",
 *   },
 *   admin_permission = "administer entity_test content",
 * )
 */
class EntityTestComputedBundleField extends EntityTest {

  /**
   * {@inheritdoc}
   */
  public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
    $fields = parent::baseFieldDefinitions($entity_type);

    $fields['computed_string_field'] = BaseFieldDefinition::create('string')
      ->setLabel('Computed Field Test')
      ->setComputed(TRUE)
      ->setClass(ComputedTestFieldItemList::class);

    $fields['computed_reference_field'] = BaseFieldDefinition::create('entity_reference')
      ->setLabel('Computed Reference Field Test')
      ->setComputed(TRUE)
      ->setSetting('target_type', 'entity_test')
      ->setClass(ComputedReferenceTestFieldItemList::class);

    $fields['computed_test_cacheable_string_field'] = BaseFieldDefinition::create('computed_test_cacheable_string_item')
      ->setLabel(new TranslatableMarkup('Computed Cacheable String Field Test'))
      ->setComputed(TRUE)
      ->setClass(ComputedTestCacheableStringItemList::class)
      ->setReadOnly(FALSE)
      ->setInternal(FALSE);

    return $fields;
  }

  /**
   * {@inheritdoc}
   */
  public static function bundleFieldDefinitions(EntityTypeInterface $entity_type, $bundle, array $base_field_definitions) {
    $fields = parent::bundleFieldDefinitions($entity_type, $bundle, $base_field_definitions);

    $computed_field_bundles = [
      'entity_test_comp_bund_fld_bund',
      'entity_test_comp_bund_fld_bund_2',
    ];

    if (in_array($bundle, $computed_field_bundles, TRUE)) {
      // @todo Use the proper FieldStorageDefinition class instead
      // https://www.drupal.org/node/2280639.
      $storageDefinition = FieldStorageDefinition::create('string')
        ->setName('computed_bundle_field')
        ->setTargetEntityTypeId($entity_type->id())
        ->setComputed(TRUE)
        ->setClass(ComputedTestBundleFieldItemList::class);
      $fields['computed_bundle_field'] = FieldDefinition::createFromFieldStorageDefinition($storageDefinition)
        ->setLabel(t('A computed Bundle Field Test'))
        ->setComputed(TRUE)
        ->setClass(ComputedTestBundleFieldItemList::class);
    }

    return $fields;
  }

}
+10 −0
Original line number Diff line number Diff line
@@ -26,6 +26,16 @@ public function getViewsData() {
        ],
      ];
    }
    if ($this->entityType->id() === 'entity_test_comp_bund_fld') {
      $views_data['entity_test_comp_bund_fld']['computed_bundle_field'] = [
        'title' => $this->t('Computed Bundle Field'),
        'field' => [
          'id' => 'field',
          'default_formatter' => 'string',
          'field_name' => 'computed_bundle_field',
        ],
      ];
    }

    if ($this->entityType->id() != 'entity_test') {
      return $views_data;
+24 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\entity_test\Plugin\Field;

use Drupal\Core\TypedData\ComputedItemListTrait;
use Drupal\Core\Field\FieldItemList;

/**
 * A computed field item list for a bundle field.
 */
class ComputedTestBundleFieldItemList extends FieldItemList {

  use ComputedItemListTrait;

  /**
   * Compute the list property from state.
   */
  protected function computeValue() {
    foreach (\Drupal::state()->get('entity_test_comp_bund_fld_item_list_value', []) as $delta => $item) {
      $this->list[$delta] = $this->createItem($delta, $item);
    }
  }

}
+31 −2
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityRepositoryInterface;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Field\FieldTypePluginManagerInterface;
@@ -126,6 +127,13 @@ class EntityField extends FieldPluginBase implements CacheableDependencyInterfac
   */
  protected $entityFieldRenderer;

  /**
   * The entity type bundle info service.
   *
   * @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface
   */
  protected $entityTypeBundleInfo;

  /**
   * The fields that we are actually grouping on.
   */
@@ -154,8 +162,10 @@ class EntityField extends FieldPluginBase implements CacheableDependencyInterfac
   *   The entity repository.
   * @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager
   *   The entity field manager.
   * @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $entity_type_bundle_info
   *   The entity type bundle info service.
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, FormatterPluginManager $formatter_plugin_manager, FieldTypePluginManagerInterface $field_type_plugin_manager, LanguageManagerInterface $language_manager, RendererInterface $renderer, EntityRepositoryInterface $entity_repository, EntityFieldManagerInterface $entity_field_manager) {
  public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, FormatterPluginManager $formatter_plugin_manager, FieldTypePluginManagerInterface $field_type_plugin_manager, LanguageManagerInterface $language_manager, RendererInterface $renderer, EntityRepositoryInterface $entity_repository, EntityFieldManagerInterface $entity_field_manager, EntityTypeBundleInfoInterface $entity_type_bundle_info = NULL) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);

    $this->entityTypeManager = $entity_type_manager;
@@ -165,6 +175,11 @@ public function __construct(array $configuration, $plugin_id, $plugin_definition
    $this->renderer = $renderer;
    $this->entityRepository = $entity_repository;
    $this->entityFieldManager = $entity_field_manager;
    if ($entity_type_bundle_info === NULL) {
      $entity_type_bundle_info = \Drupal::service('entity_type.bundle.info');
      @trigger_error('Calling ' . __CLASS__ . '::__construct() without the $entity_type_bundle_info argument is deprecated in drupal:10.3.0 and is required in drupal:11.0.0. See https://www.drupal.org/node/3380621', E_USER_DEPRECATED);
    }
    $this->entityTypeBundleInfo = $entity_type_bundle_info;

    // @todo Unify 'entity field'/'field_name' instead of converting back and
    //   forth. https://www.drupal.org/node/2410779
@@ -188,7 +203,8 @@ public static function create(ContainerInterface $container, array $configuratio
      $container->get('language_manager'),
      $container->get('renderer'),
      $container->get('entity.repository'),
      $container->get('entity_field.manager')
      $container->get('entity_field.manager'),
      $container->get('entity_type.bundle.info')
    );
  }

@@ -363,6 +379,19 @@ protected function getFieldStorageDefinition() {
    if (isset($this->definition['field_name']) && isset($base_fields[$this->definition['field_name']])) {
      return $base_fields[$this->definition['field_name']]->getFieldStorageDefinition();
    }

    // If there is still no field storage definition found, we are dealing with
    // a bundle field. Get the storage from the field definition on the first
    // bundle we find which has this field.
    $bundles = $this->entityTypeBundleInfo->getBundleInfo($entity_type_id);
    foreach ($bundles as $bundle_id => $bundle) {
      $bundle_fields = $this->entityFieldManager->getFieldDefinitions($entity_type_id, $bundle_id);
      if (isset($this->definition['field_name']) && isset($bundle_fields[$this->definition['field_name']])) {
        return $bundle_fields[$this->definition['field_name']]->getFieldStorageDefinition();
      }
    }

    return NULL;
  }

  /**
+234 −0
Original line number Diff line number Diff line
langcode: en
status: true
dependencies:
  module:
    - entity_test
id: computed_bundle_field_view
label: 'Computed Bundled Field View'
module: views
description: ''
tag: ''
base_table: entity_test_comp_bund_fld
base_field: id
display:
  default:
    display_plugin: default
    id: default
    display_title: Default
    position: 0
    display_options:
      access:
        type: none
        options: {  }
      cache:
        type: tag
        options: {  }
      query:
        type: views_query
        options:
          disable_sql_rewrite: false
          distinct: false
          replica: false
          query_comment: ''
          query_tags: {  }
      exposed_form:
        type: basic
        options:
          submit_button: Apply
          reset_button: false
          reset_button_label: Reset
          exposed_sorts_label: 'Sort by'
          expose_sort_order: true
          sort_asc_label: Asc
          sort_desc_label: Desc
      pager:
        type: mini
        options:
          items_per_page: 10
          offset: 0
          id: 0
          total_pages: null
          expose:
            items_per_page: false
            items_per_page_label: 'Items per page'
            items_per_page_options: '5, 10, 25, 50'
            items_per_page_options_all: false
            items_per_page_options_all_label: '- All -'
            offset: false
            offset_label: Offset
          tags:
            previous: ‹‹
            next: ››
      style:
        type: default
        options:
          grouping: {  }
          row_class: ''
          default_row_class: true
          uses_fields: false
      row:
        type: fields
        options:
          inline: {  }
          separator: ''
          hide_empty: false
          default_field_elements: true
      fields:
        computed_string_field:
          id: computed_string_field
          table: entity_test_comp_bund_fld
          field: computed_string_field
          relationship: none
          group_type: group
          admin_label: ''
          label: ''
          exclude: false
          alter:
            alter_text: false
            text: ''
            make_link: false
            path: ''
            absolute: false
            external: false
            replace_spaces: false
            path_case: none
            trim_whitespace: false
            alt: ''
            rel: ''
            link_class: ''
            prefix: ''
            suffix: ''
            target: ''
            nl2br: false
            max_length: 0
            word_boundary: true
            ellipsis: true
            more_link: false
            more_link_text: ''
            more_link_path: ''
            strip_tags: false
            trim: false
            preserve_tags: ''
            html: false
          element_type: ''
          element_class: ''
          element_label_type: ''
          element_label_class: ''
          element_label_colon: false
          element_wrapper_type: ''
          element_wrapper_class: ''
          element_default_classes: true
          empty: ''
          hide_empty: false
          empty_zero: false
          hide_alter_empty: true
          click_sort_column: value
          type: string
          settings:
            link_to_entity: false
          group_column: value
          group_columns: {  }
          group_rows: true
          delta_limit: 0
          delta_offset: 0
          delta_reversed: false
          delta_first_last: false
          multi_type: separator
          separator: ', '
          field_api_classes: false
          entity_type: entity_test_computed_field
          plugin_id: field
        computed_bundle_field:
          id: computed_bundle_field
          table: entity_test_comp_bund_fld
          field: computed_bundle_field
          relationship: none
          group_type: group
          admin_label: ''
          label: ''
          exclude: false
          alter:
            alter_text: false
            text: ''
            make_link: false
            path: ''
            absolute: false
            external: false
            replace_spaces: false
            path_case: none
            trim_whitespace: false
            alt: ''
            rel: ''
            link_class: ''
            prefix: ''
            suffix: ''
            target: ''
            nl2br: false
            max_length: 0
            word_boundary: true
            ellipsis: true
            more_link: false
            more_link_text: ''
            more_link_path: ''
            strip_tags: false
            trim: false
            preserve_tags: ''
            html: false
          element_type: ''
          element_class: ''
          element_label_type: ''
          element_label_class: ''
          element_label_colon: false
          element_wrapper_type: ''
          element_wrapper_class: ''
          element_default_classes: true
          empty: ''
          hide_empty: false
          empty_zero: false
          hide_alter_empty: true
          click_sort_column: value
          type: string
          settings:
            link_to_entity: false
          group_column: value
          group_columns: {  }
          group_rows: true
          delta_limit: 0
          delta_offset: 0
          delta_reversed: false
          delta_first_last: false
          multi_type: separator
          separator: ', '
          field_api_classes: false
          entity_type: entity_test_comp_bund_fld
          plugin_id: field
      filters: {  }
      sorts: {  }
      header: {  }
      footer: {  }
      empty: {  }
      relationships: {  }
      arguments: {  }
      display_extenders: {  }
    cache_metadata:
      max-age: -1
      contexts:
        - 'languages:language_content'
        - 'languages:language_interface'
        - url.query_args
      tags: {  }
  page_1:
    display_plugin: page
    id: page_1
    display_title: Page
    position: 1
    display_options:
      display_extenders: {  }
      path: foo
    cache_metadata:
      max-age: -1
      contexts:
        - 'languages:language_content'
        - 'languages:language_interface'
        - url.query_args
      tags: {  }
Loading