Commit 7ba018f6 authored by alexpott's avatar alexpott
Browse files

Issue #1906806 by Berdir, damiankloip, Sifro, dawehner: Provide a relationship...

Issue #1906806 by Berdir, damiankloip, Sifro, dawehner: Provide a relationship for each entity reference field.
parent f654024c
<?php
/**
* @file
* Provides views data for the entity_reference module.
*/
use Drupal\Core\Entity\ContentEntityDatabaseStorage;
use Drupal\field\FieldConfigInterface;
/**
* Implements hook_field_views_data().
*/
function entity_reference_field_views_data(FieldConfigInterface $field) {
$data = field_views_field_default_views_data($field);
$entity_manager = \Drupal::entityManager();
foreach ($data as $table_name => $table_data) {
// Add a relationship to the target entity type.
$target_entity_type_id = $field->getSetting('target_type');
$target_entity_type = $entity_manager->getDefinition($target_entity_type_id);
$target_base_table = $target_entity_type->getBaseTable();
// Provide a relationship for the entity type with the entity reference
// field.
$args = array(
'@label' => $target_entity_type->getLabel(),
'@field_name' => $field->getName(),
);
$data[$table_name][$field->getName()]['relationship'] = array(
'id' => 'standard',
'base' => $target_base_table,
'entity type' => $target_entity_type_id,
'base field' => $target_entity_type->getKey('id'),
'relationship field' => $field->getName() . '_target_id',
'title' => t('@label referenced from @field_name', $args),
'label' => t('@field_name: @label', $args),
);
// Provide a reverse relationship for the entity type that is referenced by
// the field.
$pseudo_field_name = 'reverse__' . $field->getTargetEntityTypeId() . '__' . $field->getName();
$data[$target_base_table][$pseudo_field_name]['relationship'] = array(
'title' => t('@label using @field_name', $args),
'help' => t('Relate each @label with a @field_name.', $args),
'id' => 'entity_reverse',
'field_name' => $field->getName(),
'field table' => ContentEntityDatabaseStorage::_fieldTableName($field),
'field field' => $field->getName() . '_target_id',
'base' => $target_entity_type->getBaseTable(),
'base field' => $target_entity_type->getKey('id'),
'label' => t('@field_name', array('@field_name' => $field->getName())),
);
}
return $data;
}
<?php
/**
* @file
* Contains \Drupal\entity_reference\Tests\Views\EntityReferenceRelationshipTest.
*/
namespace Drupal\entity_reference\Tests\Views;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldInstanceConfig;
use Drupal\views\Tests\ViewTestData;
use Drupal\views\Tests\ViewUnitTestBase;
use Drupal\views\Views;
/**
* Defines a test for the entity_reference views relationship.
*
* @see entity_reference_field_views_data()
*/
class EntityReferenceRelationshipTest extends ViewUnitTestBase {
/**
* Views used by this test.
*
* @var array
*/
public static $testViews = array('test_entity_reference_view');
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('user', 'field', 'entity_test', 'options', 'entity_reference', 'views', 'entity_reference_test_views');
/**
* The entity_test entities used by the test.
*
* @var array
*/
protected $entities = array();
/**
* {@inheritdoc}
*/
public static function getInfo() {
return array(
'name' => 'Entity Reference: Relationship data',
'description' => 'Tests entity reference relationship data.',
'group' => 'Views module integration',
);
}
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installEntitySchema('entity_test');
ViewTestData::createTestViews(get_class($this), array('entity_reference_test_views'));
$field = FieldConfig::create(array(
'settings' => array(
'target_type' => 'entity_test',
),
'entity_type' => 'entity_test',
'name' => 'field_test',
'type' => 'entity_reference',
'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
));
$field->save();
$instance = FieldInstanceConfig::create(array(
'entity_type' => 'entity_test',
'field_name' => 'field_test',
'bundle' => 'entity_test',
'settings' => array(
'handler' => 'default',
'handler_settings' => array(),
),
));
$instance->save();
// Create some test entities which link each other.
$entity_storage= \Drupal::entityManager()->getStorage('entity_test');
$referenced_entity = $entity_storage->create(array());
$referenced_entity->save();
$this->entities[$referenced_entity->id()] = $referenced_entity;
$entity = $entity_storage->create(array());
$entity->field_test->target_id = $referenced_entity->id();
$entity->save();
$this->entities[$entity->id()] = $entity;
$entity = $entity_storage->create(array('field_test' => $entity->id()));
$entity->field_test->target_id = $referenced_entity->id();
$entity->save();
$this->entities[$entity->id()] = $entity;
}
/**
* Tests using the views relationship.
*/
public function testRelationship() {
// Check just the generated views data.
$views_data_field_test = Views::viewsData()->get('entity_test__field_test');
$this->assertEqual($views_data_field_test['field_test']['relationship']['id'], 'standard');
$this->assertEqual($views_data_field_test['field_test']['relationship']['base'], 'entity_test');
$this->assertEqual($views_data_field_test['field_test']['relationship']['base field'], 'id');
$this->assertEqual($views_data_field_test['field_test']['relationship']['relationship field'], 'field_test_target_id');
// Check the backwards reference.
$views_data_entity_test = Views::viewsData()->get('entity_test');
$this->assertEqual($views_data_entity_test['reverse__entity_test__field_test']['relationship']['id'], 'entity_reverse');
$this->assertEqual($views_data_entity_test['reverse__entity_test__field_test']['relationship']['base'], 'entity_test');
$this->assertEqual($views_data_entity_test['reverse__entity_test__field_test']['relationship']['base field'], 'id');
$this->assertEqual($views_data_entity_test['reverse__entity_test__field_test']['relationship']['field table'], 'entity_test__field_test');
$this->assertEqual($views_data_entity_test['reverse__entity_test__field_test']['relationship']['field field'], 'field_test_target_id');
// Check an actual test view.
$view = Views::getView('test_entity_reference_view');
$this->executeView($view);
foreach (array_keys($view->result) as $index) {
// Just check that the actual ID of the entity is the expected one.
$this->assertEqual($view->result[$index]->id, $this->entities[$index + 1]->id());
// Test the forward relationship.
// The second and third entity refer to the first one.
// The value key on the result will be in the format
// BASE_TABLE_FIELD_NAME.
$this->assertEqual($view->result[$index]->entity_test_entity_test__field_test_id, $index == 0 ? NULL : 1);
if ($index > 0) {
// Test that the correct relationship entity is on the row.
$this->assertEqual($view->result[$index]->_relationship_entities['test_relationship']->id(), 1);
}
}
$view->destroy();
$this->executeView($view, 'embed_1');
foreach (array_keys($view->result) as $index) {
$this->assertEqual($view->result[$index]->id, $this->entities[$index + 1]->id());
// The second and third entity refer to the first one.
$this->assertEqual($view->result[$index]->entity_test_entity_test__field_test_id, $index == 0 ? NULL : 1);
}
}
}
name: 'Entity reference test views'
type: module
description: 'Provides default views for views entity reference tests.'
package: Testing
version: VERSION
core: 8.x
dependencies:
- entity_reference
- views
base_table: entity_test
core: '8'
description: ''
status: '1'
display:
default:
display_options:
defaults:
fields: '0'
relationships: '0'
pager: '0'
pager_options: '0'
sorts: '0'
fields:
id:
field: id
id: id
relationship: none
table: entity_test
plugin_id: numeric
id_1:
field: id
id: id_1
order: ASC
relationship: test_relationship
table: entity_test
plugin_id: numeric
pager:
options:
offset: '0'
type: none
pager_options: { }
sorts:
id:
field: id
id: id
order: ASC
relationship: none
table: entity_test
plugin_id: standard
relationships:
test_relationship:
id: field_test
table: entity_test__field_test
field: field_test
relationship: none
plugin_id: standard
display_plugin: default
display_title: Master
id: default
position: '0'
embed_1:
display_options:
defaults:
relationships: '0'
relationships:
test_relationship:
id: reverse_field_test
table: entity_test
field: reverse_field_test
relationship: none
plugin_id: standard
display_plugin: embed
display_title: Embed
id: embed_1
human_name: ''
id: test_entity_reference_view
tag: ''
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment