commit b13ddada3af6f848dc23347c046c5409edb6775c Author: Jibran Ijaz Date: Sat Jun 18 10:50:52 2016 +0500 Views fix. diff --git a/dynamic_entity_reference.module b/dynamic_entity_reference.module index be53516..24db001 100644 --- a/dynamic_entity_reference.module +++ b/dynamic_entity_reference.module @@ -5,12 +5,14 @@ * Contains main module functionality. */ +use Drupal\Core\Entity\FieldableEntityInterface; +use Drupal\Core\Entity\Sql\SqlEntityStorageInterface; use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem; use Drupal\dynamic_entity_reference\Plugin\Field\FieldType\DynamicEntityReferenceItem; use Drupal\field\FieldConfigInterface; /** - * Implements hook_ENTITY_TYPE_presave() for 'field_config'. + * Implements hook_ENTITY_TYPE_presave(). * * @todo Clean this up once field_field_config_save is more accommodating. */ @@ -54,3 +56,56 @@ function dynamic_entity_reference_module_implements_alter(&$implementations, $ho $implementations['dynamic_entity_reference'] = $group; } } + +/** + * Determines if an entity type is using an integer-based ID definition. + * + * @param string $entity_type_id + * The ID the represents the entity type. + * + * @return bool + * Returns TRUE if the entity type has an integer-based ID definition and + * FALSE otherwise. + */ +function _dynamic_entity_reference_entity_id_is_int($entity_type_id) { + $entity_type = \Drupal::entityTypeManager()->getDefinition($entity_type_id); + $entity_type_id_key = $entity_type->getKey('id'); + if ($entity_type_id_key === FALSE) { + return FALSE; + } + $field_definitions = \Drupal::service('entity_field.manager')->getBaseFieldDefinitions($entity_type->id()); + $entity_type_id_definition = $field_definitions[$entity_type_id_key]; + return $entity_type_id_definition->getType() === 'integer'; +} + +/** + * Helper function to return all the base fields. + * + * @return array + * Returns all the entity types with dynamic_entity_reference base field, all + * the SQL entity types and all the base fields. + */ +function _dynamic_entity_reference_get_all_base_fields() { + $entity_types = []; + $sql_entity_types = []; + $fields_all = []; + // Ensure origin and target entity types are SQL. + $entity_manager = \Drupal::entityManager(); + foreach ($entity_manager->getDefinitions() as $entity_type) { + // \Drupal\views\EntityViewsData class only allows entities with + // \Drupal\Core\Entity\Sql\SqlEntityStorageInterface. + if ($entity_type->hasHandlerClass('views_data') && $entity_manager->getStorage($entity_type->id()) instanceof SqlEntityStorageInterface) { + $sql_entity_types[$entity_type->id()] = $entity_type->id(); + // Only fieldable entities have base fields. + if ($entity_type->isSubclassOf(FieldableEntityInterface::class)) { + $entity_types[$entity_type->id()] = $entity_type; + foreach ($entity_manager->getBaseFieldDefinitions($entity_type->id()) as $base_field) { + if ($base_field->getType() == 'dynamic_entity_reference') { + $fields_all[$entity_type->id()][] = $base_field; + } + } + } + } + } + return [$entity_types, $sql_entity_types, $fields_all]; +} \ No newline at end of file diff --git a/dynamic_entity_reference.views.inc b/dynamic_entity_reference.views.inc index d6909d1..6038040 100644 --- a/dynamic_entity_reference.views.inc +++ b/dynamic_entity_reference.views.inc @@ -5,10 +5,8 @@ * Provides views data for the dynamic_entity_reference module. */ -use Drupal\Core\Entity\FieldableEntityInterface; use Drupal\field\FieldStorageConfigInterface; use Drupal\dynamic_entity_reference\Plugin\Field\FieldType\DynamicEntityReferenceItem; -use Drupal\Core\Entity\Sql\SqlEntityStorageInterface; /** * Implements hook_field_views_data(). @@ -30,8 +28,10 @@ function dynamic_entity_reference_field_views_data(FieldStorageConfigInterface $ // Add a relationship to all the target entity types. foreach ($target_entity_type_ids as $target_entity_type_id) { $target_entity_type = $entity_manager->getDefinition($target_entity_type_id); + $target_entity_id_is_int = _dynamic_entity_reference_entity_id_is_int($target_entity_type_id); $entity_type_id = $field_storage->getTargetEntityTypeId(); $entity_type = $entity_manager->getDefinition($entity_type_id); + $entity_id_is_int = _dynamic_entity_reference_entity_id_is_int($entity_type_id); $target_base_table = $entity_manager->getHandler($target_entity_type_id, 'views_data')->getViewsTableForEntityType($target_entity_type); $field_name = $field_storage->getName(); @@ -41,6 +41,10 @@ function dynamic_entity_reference_field_views_data(FieldStorageConfigInterface $ '@label' => $target_entity_type->getLabel(), '@field_name' => $field_name, ); + if ($target_entity_id_is_int) { + $data[$table_name][$target_entity_type_id . '__' . $field_name]['argument']['id'] = 'numeric'; + $data[$table_name][$target_entity_type_id . '__' . $field_name]['filter']['id'] = 'numeric'; + } $data[$table_name][$target_entity_type_id . '__' . $field_name]['relationship'] = array( 'title' => t('@label referenced from @field_name', $args), 'label' => t('@field_name: @label', $args), @@ -50,7 +54,7 @@ function dynamic_entity_reference_field_views_data(FieldStorageConfigInterface $ 'base' => $target_base_table, 'entity type' => $target_entity_type_id, 'base field' => $target_entity_type->getKey('id'), - 'relationship field' => $field_name . '_target_id_int', + 'relationship field' => $target_entity_id_is_int ? $field_name . '_target_id_int' : $field_name . '_target_id' , // Entity reference field only has one target type whereas dynamic // entity reference field can have multiple target types that is why we // need extra join condition on target types. @@ -80,7 +84,7 @@ function dynamic_entity_reference_field_views_data(FieldStorageConfigInterface $ 'base field' => $entity_type->getKey('id'), 'field_name' => $field_name, 'field table' => $table_mapping->getDedicatedDataTableName($field_storage), - 'field field' => $field_name . '_target_id_int', + 'field field' => $entity_id_is_int ? $field_name . '_target_id_int' : $field_name . '_target_id', // Entity reference field only has one target type whereas dynamic // entity reference field can have multiple target types that is why we // need extra join condition on target types. @@ -113,26 +117,7 @@ function dynamic_entity_reference_views_data() { $entity_manager = \Drupal::entityManager(); /** @var \Drupal\Core\Entity\EntityTypeInterface[] $entity_types */ - $entity_types = []; - $sql_entity_types = []; - $fields_all = []; - // Ensure origin and target entity types are SQL. - foreach ($entity_manager->getDefinitions() as $entity_type) { - // \Drupal\views\EntityViewsData class only allows entities with - // \Drupal\Core\Entity\Sql\SqlEntityStorageInterface. - if ($entity_type->hasHandlerClass('views_data') && $entity_manager->getStorage($entity_type->id()) instanceof SqlEntityStorageInterface) { - $sql_entity_types[$entity_type->id()] = $entity_type->id(); - // Only fieldable entities have base fields. - if ($entity_type->isSubclassOf(FieldableEntityInterface::class)) { - $entity_types[$entity_type->id()] = $entity_type; - foreach ($entity_manager->getBaseFieldDefinitions($entity_type->id()) as $base_field) { - if ($base_field->getType() == 'dynamic_entity_reference') { - $fields_all[$entity_type->id()][] = $base_field; - } - } - } - } - } + list($entity_types, $sql_entity_types, $fields_all) = _dynamic_entity_reference_get_all_base_fields(); $data = []; foreach ($fields_all as $entity_type_id => $fields) { @@ -140,13 +125,14 @@ function dynamic_entity_reference_views_data() { $table_mapping = $entity_manager->getStorage($entity_type_id)->getTableMapping(); $entity_type = $entity_types[$entity_type_id]; + $entity_id_is_int = _dynamic_entity_reference_entity_id_is_int($entity_type_id); $base_table = $entity_manager->getHandler($entity_type_id, 'views_data')->getViewsTableForEntityType($entity_type); /** @var \Drupal\Core\Field\BaseFieldDefinition[] $fields */ foreach ($fields as $field) { $field_name = $field->getName(); $columns = $table_mapping->getColumnNames($field_name); - $column_id = $columns['target_id'] . '_int'; + $column_id = $entity_id_is_int ? $columns['target_id'] . '_int' : $columns['target_id']; $column_type = $columns['target_type']; // Unlimited (-1) or > 1 store field data in a dedicated table. @@ -247,3 +233,43 @@ function dynamic_entity_reference_views_data() { return $data; } + +/** + * Implements hook_views_data_alter(). + * + * Changes dynamic_entity_reference base fields argument and filter to numeric. + */ +function dynamic_entity_reference_views_data_alter(&$data) { + $entity_manager = \Drupal::entityManager(); + + /** @var \Drupal\Core\Entity\EntityTypeInterface[] $entity_types */ + list($entity_types, $sql_entity_types, $fields_all) = _dynamic_entity_reference_get_all_base_fields(); + + foreach ($fields_all as $entity_type_id => $fields) { + + $entity_type = $entity_types[$entity_type_id]; + $base_table = $entity_manager->getHandler($entity_type_id, 'views_data')->getViewsTableForEntityType($entity_type); + + /** @var \Drupal\Core\Field\BaseFieldDefinition[] $fields */ + foreach ($fields as $field) { + $field_name = $field->getName(); + + // Unlimited (-1) or > 1 store field data in a dedicated table. + $table = $field->getCardinality() == 1 ? $base_table : $entity_type->getBaseTable() . '__' . $field_name; + // Filter out non SQL entity types because \Drupal\views\EntityViewsData + // class only allows entities with + // \Drupal\Core\Entity\Sql\SqlEntityStorageInterface. + $targets = array_intersect(DynamicEntityReferenceItem::getTargetTypes($field->getSettings()), array_keys($sql_entity_types)); + foreach ($targets as $target_entity_type_id) { + $target_entity_id_is_int = _dynamic_entity_reference_entity_id_is_int($target_entity_type_id); + if ($target_entity_id_is_int) { + $data[$table][$target_entity_type_id . '__' . $field_name]['argument']['id'] = 'numeric'; + $data[$table][$target_entity_type_id . '__' . $field_name]['filter']['id'] = 'numeric'; + } + + } + + } + } + +}