Issue #2852067 by Sam152, seanB, amateescu, jibran, dawehner, larowlan, tstoeckler, tim.plunkett: Add support for rendering computed fields to the "field" views field handler
parent
6496b03d54
commit
1fa12fb744
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\entity_test\Entity;
|
||||
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Field\BaseFieldDefinition;
|
||||
use Drupal\entity_test\Plugin\Field\ComputedTestFieldItemList;
|
||||
|
||||
/**
|
||||
* An entity used for testing computed field values.
|
||||
*
|
||||
* @ContentEntityType(
|
||||
* id = "entity_test_computed_field",
|
||||
* label = @Translation("Entity Test computed field"),
|
||||
* base_table = "entity_test_computed_field",
|
||||
* handlers = {
|
||||
* "views_data" = "Drupal\entity_test\EntityTestViewsData"
|
||||
* },
|
||||
* entity_keys = {
|
||||
* "id" = "id",
|
||||
* "label" = "name",
|
||||
* },
|
||||
* admin_permission = "administer entity_test content",
|
||||
* links = {
|
||||
* "add-form" = "/entity_test_computed_field/add",
|
||||
* },
|
||||
* )
|
||||
*/
|
||||
class EntityTestComputedField 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);
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
}
|
|
@ -16,6 +16,17 @@ class EntityTestViewsData extends EntityViewsData {
|
|||
public function getViewsData() {
|
||||
$views_data = parent::getViewsData();
|
||||
|
||||
if ($this->entityType->id() === 'entity_test_computed_field') {
|
||||
$views_data['entity_test_computed_field']['computed_string_field'] = [
|
||||
'title' => $this->t('Computed String Field'),
|
||||
'field' => [
|
||||
'id' => 'field',
|
||||
'default_formatter' => 'string',
|
||||
'field_name' => 'computed_string_field',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
if ($this->entityType->id() != 'entity_test') {
|
||||
return $views_data;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\entity_test\Plugin\Field;
|
||||
|
||||
use Drupal\Core\Field\FieldItemList;
|
||||
|
||||
/**
|
||||
* A computed field item list.
|
||||
*/
|
||||
class ComputedTestFieldItemList extends FieldItemList {
|
||||
|
||||
/**
|
||||
* Compute the list property from state.
|
||||
*/
|
||||
protected function computedListProperty() {
|
||||
foreach (\Drupal::state()->get('entity_test_computed_field_item_list_value', []) as $delta => $item) {
|
||||
$this->list[$delta] = $this->createItem($delta, $item);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get($index) {
|
||||
$this->computedListProperty();
|
||||
return isset($this->list[$index]) ? $this->list[$index] : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIterator() {
|
||||
$this->computedListProperty();
|
||||
return parent::getIterator();
|
||||
}
|
||||
|
||||
}
|
|
@ -316,24 +316,33 @@ class EntityField extends FieldPluginBase implements CacheableDependencyInterfac
|
|||
}
|
||||
|
||||
/**
|
||||
* Gets the field storage of the used field.
|
||||
* Gets the field storage definition.
|
||||
*
|
||||
* @return \Drupal\Core\Field\FieldStorageDefinitionInterface
|
||||
* The field storage definition used by this handler.
|
||||
*/
|
||||
protected function getFieldStorageDefinition() {
|
||||
$entity_type_id = $this->definition['entity_type'];
|
||||
$field_storage_definitions = $this->entityManager->getFieldStorageDefinitions($entity_type_id);
|
||||
|
||||
$field_storage = NULL;
|
||||
// @todo Unify 'entity field'/'field_name' instead of converting back and
|
||||
// forth. https://www.drupal.org/node/2410779
|
||||
if (isset($this->definition['field_name'])) {
|
||||
$field_storage = $field_storage_definitions[$this->definition['field_name']];
|
||||
if (isset($this->definition['field_name']) && isset($field_storage_definitions[$this->definition['field_name']])) {
|
||||
return $field_storage_definitions[$this->definition['field_name']];
|
||||
}
|
||||
elseif (isset($this->definition['entity field'])) {
|
||||
$field_storage = $field_storage_definitions[$this->definition['entity field']];
|
||||
|
||||
if (isset($this->definition['entity field']) && isset($field_storage_definitions[$this->definition['entity field']])) {
|
||||
return $field_storage_definitions[$this->definition['entity field']];
|
||||
}
|
||||
|
||||
// The list of field storage definitions above does not include computed
|
||||
// base fields, so we need to explicitly fetch a list of all base fields in
|
||||
// order to support them.
|
||||
// @see \Drupal\Core\Entity\EntityFieldManager::getFieldStorageDefinitions()
|
||||
$base_fields = $this->entityManager->getBaseFieldDefinitions($entity_type_id);
|
||||
if (isset($this->definition['field_name']) && isset($base_fields[$this->definition['field_name']])) {
|
||||
return $base_fields[$this->definition['field_name']]->getFieldStorageDefinition();
|
||||
}
|
||||
return $field_storage;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,171 @@
|
|||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- entity_test
|
||||
id: computed_field_view
|
||||
label: 'Computed Field View'
|
||||
module: views
|
||||
description: ''
|
||||
tag: ''
|
||||
base_table: entity_test_computed_field
|
||||
base_field: id
|
||||
core: 8.x
|
||||
display:
|
||||
default:
|
||||
display_plugin: default
|
||||
id: default
|
||||
display_title: Master
|
||||
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_computed_field
|
||||
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
|
||||
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: { }
|
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\views\Kernel\Handler;
|
||||
|
||||
use Drupal\entity_test\Entity\EntityTestComputedField;
|
||||
use Drupal\Tests\views\Kernel\ViewsKernelTestBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
* Provides some integration tests for the Field handler.
|
||||
*
|
||||
* @see \Drupal\views\Plugin\views\field\EntityField
|
||||
* @group views
|
||||
*/
|
||||
class ComputedFieldTest extends ViewsKernelTestBase {
|
||||
|
||||
/**
|
||||
* Views to be enabled.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $testViews = ['computed_field_view'];
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['entity_test'];
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp($import_test_views = TRUE) {
|
||||
parent::setUp($import_test_views);
|
||||
|
||||
$this->installEntitySchema('entity_test_computed_field');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the computed field handler.
|
||||
*/
|
||||
public function testComputedFieldHandler() {
|
||||
\Drupal::state()->set('entity_test_computed_field_item_list_value', ['computed string']);
|
||||
|
||||
$entity = EntityTestComputedField::create([]);
|
||||
$entity->save();
|
||||
|
||||
$view = Views::getView('computed_field_view');
|
||||
|
||||
$rendered_view = $view->preview();
|
||||
$output = $this->container->get('renderer')->renderRoot($rendered_view);
|
||||
$this->assertContains('computed string', (string) $output);
|
||||
}
|
||||
|
||||
}
|
|
@ -16,6 +16,7 @@ use Drupal\Core\TypedData\DataDefinitionInterface;
|
|||
use Drupal\Core\TypedData\ListInterface;
|
||||
use Drupal\Core\TypedData\Type\StringInterface;
|
||||
use Drupal\Core\TypedData\TypedDataInterface;
|
||||
use Drupal\entity_test\Entity\EntityTestComputedField;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
|
||||
|
@ -737,6 +738,16 @@ class EntityFieldTest extends EntityKernelTestBase {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test computed fields.
|
||||
*/
|
||||
public function testComputedFields() {
|
||||
\Drupal::state()->set('entity_test_computed_field_item_list_value', ['foo computed']);
|
||||
|
||||
$entity = EntityTestComputedField::create([]);
|
||||
$this->assertEquals($entity->computed_string_field->value, 'foo computed');
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the computed properties tests for the given entity type.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue