diff -u b/core/modules/views/src/EntityViewsData.php b/core/modules/views/src/EntityViewsData.php --- b/core/modules/views/src/EntityViewsData.php +++ b/core/modules/views/src/EntityViewsData.php @@ -229,10 +229,8 @@ $multiple = (count($field_column_mapping) > 1); $first = TRUE; foreach ($field_column_mapping as $field_column_name => $schema_field_name) { - $schema = $field_schema['columns'][$field_column_name]; - $field_name_to_use = ($multiple) ? $field_name . '__' . $field_column_name : $field_name; - $field_type_to_use = ($multiple) ? $field_definition_type : ''; - $table_data[$field_name_to_use] = $this->mapSingleFieldViewsData($table, $schema['type'], $field_column_name, $field_definition, $first, $field_type_to_use, $field_name); + $views_field_name = ($multiple) ? $field_name . '__' . $field_column_name : $field_name; + $table_data[$views_field_name] = $this->mapSingleFieldViewsData($table, $field_name, $field_definition_type, $field_column_name, $field_schema['columns'][$field_column_name]['type'], $first, $field_definition); $first = FALSE; } } @@ -242,125 +240,121 @@ * * @param string $table * The table of the field to handle. - * @param string $data_type - * The data type to generate views data for, for example "int". The data - * type comes directly from the schema definition of each field item. - * @param string $field_column_name + * @param string $field_name + * The machine name of the field being processed. + * @param string $field_type + * The type of field being handled. + * @param string $column_name * For fields containing multiple columns, the column name being processed. + * @param string $column_type + * Within the field, the column type being handled. + * @param bool $first + * TRUE if this is the first column within the field. * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition * The field definition. - * @param bool $first - * Is it the first column of the schema. - * @param string $field_type - * For fields containing multiple columns, the data type of the field as a - * whole. - * @param string $field_name - * The machine name fo the field being processed. * * @return array * The modified views data field definition. */ - protected function mapSingleFieldViewsData($table, $data_type, $field_column_name, FieldDefinitionInterface $field_definition, $first, $field_type, $field_name) { + protected function mapSingleFieldViewsData($table, $field_name, $field_type, $column_name, $column_type, $first, FieldDefinitionInterface $field_definition) { $views_field = array(); - // Provide a nicer, less verbose label for the first field. + // Provide a nicer, less verbose label for the first column within a field. if ($first) { $views_field['title'] = $field_definition->getLabel(); } else { - $views_field['title'] = $field_definition->getLabel() . " ($field_column_name)"; + $views_field['title'] = $field_definition->getLabel() . " ($column_name)"; } if ($description = $field_definition->getDescription()) { $views_field['help'] = $description; } + // Set up the field, sort, argument, and filters, based on + // the column and/or field data type. // @todo Allow field types to customize this. // @see https://www.drupal.org/node/2337515 - switch ($data_type) { - case 'int': - case 'integer': - case 'smallint': - case 'tinyint': - case 'mediumint': - case 'float': - case 'double': - case 'decimal': - $views_field['field']['id'] = 'numeric'; - $views_field['argument']['id'] = 'numeric'; - $views_field['filter']['id'] = 'numeric'; - $views_field['sort']['id'] = 'standard'; - break; - case 'char': - case 'string': - case 'varchar': - case 'tinytext': - case 'text': - case 'mediumtext': - case 'longtext': - $views_field['field']['id'] = 'standard'; - $views_field['argument']['id'] = 'string'; - $views_field['filter']['id'] = 'string'; - $views_field['sort']['id'] = 'standard'; - break; - case 'boolean': - $views_field['field']['id'] = 'boolean'; - $views_field['argument']['id'] = 'numeric'; - $views_field['filter']['id'] = 'boolean'; - $views_field['sort']['id'] = 'standard'; - break; - case 'uuid': - $views_field['field']['id'] = 'standard'; - $views_field['argument']['id'] = 'string'; - $views_field['filter']['id'] = 'string'; - $views_field['sort']['id'] = 'standard'; + switch ($field_type) { + + // Special case a few field types. + + case 'timestamp': + case 'created': + case 'changed': + $views_field['field']['id'] = 'date'; + $views_field['argument']['id'] = 'date'; + $views_field['filter']['id'] = 'date'; + $views_field['sort']['id'] = 'date'; break; + case 'language': $views_field['field']['id'] = 'language'; $views_field['argument']['id'] = 'language'; $views_field['filter']['id'] = 'language'; $views_field['sort']['id'] = 'standard'; break; - case 'created': - case 'changed': - $views_field['field']['id'] = 'date'; - $views_field['argument']['id'] = 'date'; - $views_field['filter']['id'] = 'date'; - $views_field['sort']['id'] = 'date'; - break; - case 'entity_reference': - // @todo Should the actual field handler respect that this is just renders a number - // @todo Create an optional entity field handler, that can render the - // entity. - // @see https://www.drupal.org/node/2322949 - $views_field['field']['id'] = 'standard'; - $views_field['argument']['id'] = 'standard'; - $views_field['filter']['id'] = 'standard'; - $views_field['sort']['id'] = 'standard'; - break; - case 'uri': - $views_field['field']['id'] = 'standard'; - $views_field['argument']['id'] = 'string'; - $views_field['filter']['id'] = 'string'; + + case 'boolean': + $views_field['field']['id'] = 'boolean'; + $views_field['argument']['id'] = 'numeric'; + $views_field['filter']['id'] = 'boolean'; $views_field['sort']['id'] = 'standard'; break; + + case 'text': + case 'text_with_summary': + // Treat these three long text fields the same. + $field_type = 'long_text'; + // Intentional fall-through here to the default processing! + default: - $views_field['field']['id'] = 'standard'; - $views_field['argument']['id'] = 'standard'; - $views_field['filter']['id'] = 'standard'; - $views_field['sort']['id'] = 'standard'; + // For most fields, the field type is generic enough to just use + // the column type to determine the filters etc. + switch ($column_type) { + + case 'int': + case 'integer': + case 'smallint': + case 'tinyint': + case 'mediumint': + case 'float': + case 'double': + case 'decimal': + $views_field['field']['id'] = 'numeric'; + $views_field['argument']['id'] = 'numeric'; + $views_field['filter']['id'] = 'numeric'; + $views_field['sort']['id'] = 'standard'; + break; + + case 'char': + case 'string': + case 'varchar': + case 'tinytext': + case 'text': + case 'mediumtext': + case 'longtext': + $views_field['field']['id'] = 'standard'; + $views_field['argument']['id'] = 'string'; + $views_field['filter']['id'] = 'string'; + $views_field['sort']['id'] = 'standard'; + break; + + default: + $views_field['field']['id'] = 'standard'; + $views_field['argument']['id'] = 'standard'; + $views_field['filter']['id'] = 'standard'; + $views_field['sort']['id'] = 'standard'; + } } - $process_method = 'processViewsDataFor' . Container::camelize($data_type); + // Do post-processing for a few field types. + + $process_method = 'processViewsDataFor' . Container::camelize($field_type); if (method_exists($this, $process_method)) { $this->{$process_method}($table, $field_definition, $views_field); } - // Special case a few field types for extra processing. - if (in_array($field_type, array('text', 'long_text', 'text_with_summary'))) { - $this->processViewsDataForLongText($views_field, $field_column_name, $field_name); - } - return $views_field; } @@ -397,6 +391,13 @@ * The views field data. */ protected function processViewsDataForEntityReference($table, FieldDefinitionInterface $field_definition, array &$views_field) { + + // @todo Should the actual field handler respect that this just renders a + // number? + // @todo Create an optional entity field handler, that can render the + // entity. + // @see https://www.drupal.org/node/2322949 + if ($entity_type_id = $field_definition->getItemDefinition()->getSetting('target_type')) { $entity_type = $this->entityManager->getDefinition($entity_type_id); if ($entity_type instanceof ContentEntityType) {