Problem/Motivation
Since #2852067: Add support for rendering computed fields to the "field" views field handler Views can render computed fields. However, this only works for computed base fields not computed bundle fields.
The problem is that generally a view is not specific to a given bundle, so we cannot know up-front to which bundle a (computed) bundle field may belong.
Steps to reproduce
To reproduce this issue you must implement hook_entity_bundle_field_info_alter()
to add a computed bundle base field to an existing entity, and then also add a hook_views_data_alter()
implementation to expose the new bundle field to views. If you then attempt to add that bundle base field to a view, you will see an error like:
Error: Call to a member function getType() on null in Drupal\views\Plugin\views\field\EntityField->defineOptions() (line 370 of
/var/www/html/repos/drupal/core/modules/views/src/Plugin/views/field/EntityField.php)
Here are example files that can be used to test this as part of a module called computed_bundle_field_test:
computed_bundle_field_test.module
<?php
/**
* @file
* Testing computed bundle fields.
*/
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\computed_bundle_field_test\FieldStorageDefinition;
/**
* Implements hook_entity_bundle_field_info_alter().
*/
function computed_bundle_field_test_entity_bundle_field_info_alter(&$fields, EntityTypeInterface $entity_type, $bundle) {
if ($bundle === 'page') {
$fields['computed_bundle_string_field'] = FieldStorageDefinition::create('string')
->setLabel('Computed Bundle String Field')
->setName('computed_bundle_string_field')
->setDescription('A computed bundle string field')
->setComputed(TRUE)
->setClass('\Drupal\computed_bundle_field_test\ComputedBundleStringField')
->setTargetEntityTypeId('node')
->setTargetBundle('page')
->setTranslatable(FALSE)
->setRevisionable(FALSE)
->setReadOnly(TRUE)
->setDisplayConfigurable('view', TRUE)
->setDisplayOptions('view', [
'label' => 'visible',
]);
}
}
?>
computed_bundle_field_test.views.inc
<?php
/**
* @file
* Views functionality for the computed_bundle_field_test module.
*/
/**
* Implements hook_views_data_alter().
*/
function computed_bundle_field_test_views_data_alter(array &$data) {
$data['node_field_data']['computed_bundle_string_field'] = [
'title' => 'Computed Bundle String Field',
'field' => [
'title' => 'Computed Bundle String Field',
'id' => 'field',
'field_name' => 'computed_bundle_string_field',
],
];
}
?>
src/ComputedBundleStringField.php
<?php
namespace Drupal\computed_bundle_field_test;
use Drupal\Core\Field\FieldItemList;
use Drupal\Core\TypedData\ComputedItemListTrait;
/**
* The ComputedBundleStringField class.
*/
class ComputedBundleStringField extends FieldItemList {
use ComputedItemListTrait;
/**
* Compute the field value.
*/
protected function computeValue() {
$this->list[0] = $this->createItem(0, 'THIS IS A COMPUTED FIELD');
}
}
src/FieldStorageDefinition.php
<?php
namespace Drupal\computed_bundle_field_test;
use Drupal\Core\Field\BaseFieldDefinition;
/**
* A custom field storage definition class.
*
* For convenience we extend from BaseFieldDefinition although this should not
* implement FieldDefinitionInterface.
*
*/
class FieldStorageDefinition extends BaseFieldDefinition {
/**
* {@inheritdoc}
*/
public function isBaseField() {
return FALSE;
}
}
Once these files are in place then you should be able to add the Computed field to views and any/all Page nodes should display a value of THIS IS A COMPUTED FIELD for that column.
Proposed resolution
Allow adding views data for (computed) bundle fields and - if it is - fetch the respective field definition for those bundles. Note, if multiple bundles need to specify different computed fields with different underlying classes, they will need to be added separately to the views data definition.
Remaining tasks
Create 9.4.x PatchCreate 10.x PatchCreate 11.x PatchAdd Tests- Review & Merge
User interface changes
N/A
API changes
N/A
Data model changes
N/A
Release notes snippet
N/A