Commit da026cf5 authored by alexpott's avatar alexpott

Issue #2116363 by Berdir, jessebeach | fago: Unified repository of field definitions (cache + API).

parent 8723cb96
...@@ -965,7 +965,7 @@ function install_base_system(&$install_state) { ...@@ -965,7 +965,7 @@ function install_base_system(&$install_state) {
// Enable the user module so that sessions can be recorded during the // Enable the user module so that sessions can be recorded during the
// upcoming bootstrap step. // upcoming bootstrap step.
\Drupal::moduleHandler()->install(array('field', 'user'), FALSE); \Drupal::moduleHandler()->install(array('user'), FALSE);
// Save the list of other modules to install for the upcoming tasks. // Save the list of other modules to install for the upcoming tasks.
// State can be set to the database now that system.module is installed. // State can be set to the database now that system.module is installed.
......
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
use Drupal\Core\Entity\Query\QueryInterface; use Drupal\Core\Entity\Query\QueryInterface;
use Drupal\Core\Field\FieldStorageDefinitionInterface; use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Language\Language; use Drupal\Core\Language\Language;
use Drupal\field\FieldInfo;
use Drupal\field\FieldConfigUpdateForbiddenException; use Drupal\field\FieldConfigUpdateForbiddenException;
use Drupal\field\FieldConfigInterface; use Drupal\field\FieldConfigInterface;
use Drupal\field\FieldInstanceConfigInterface; use Drupal\field\FieldInstanceConfigInterface;
...@@ -66,11 +65,11 @@ class ContentEntityDatabaseStorage extends ContentEntityStorageBase { ...@@ -66,11 +65,11 @@ class ContentEntityDatabaseStorage extends ContentEntityStorageBase {
protected $database; protected $database;
/** /**
* The field info object. * The entity manager.
* *
* @var \Drupal\field\FieldInfo * @var \Drupal\Core\Entity\EntityManagerInterface
*/ */
protected $fieldInfo; protected $entityManager;
/** /**
* {@inheritdoc} * {@inheritdoc}
...@@ -79,7 +78,7 @@ public static function createInstance(ContainerInterface $container, EntityTypeI ...@@ -79,7 +78,7 @@ public static function createInstance(ContainerInterface $container, EntityTypeI
return new static( return new static(
$entity_type, $entity_type,
$container->get('database'), $container->get('database'),
$container->get('field.info') $container->get('entity.manager')
); );
} }
...@@ -90,14 +89,14 @@ public static function createInstance(ContainerInterface $container, EntityTypeI ...@@ -90,14 +89,14 @@ public static function createInstance(ContainerInterface $container, EntityTypeI
* The entity type definition. * The entity type definition.
* @param \Drupal\Core\Database\Connection $database * @param \Drupal\Core\Database\Connection $database
* The database connection to be used. * The database connection to be used.
* @param \Drupal\field\FieldInfo $field_info * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
* The field info service. * The entity manager.
*/ */
public function __construct(EntityTypeInterface $entity_type, Connection $database, FieldInfo $field_info) { public function __construct(EntityTypeInterface $entity_type, Connection $database, EntityManagerInterface $entity_manager) {
parent::__construct($entity_type); parent::__construct($entity_type);
$this->database = $database; $this->database = $database;
$this->fieldInfo = $field_info; $this->entityManager = $entity_manager;
// Check if the entity type supports UUIDs. // Check if the entity type supports UUIDs.
$this->uuidKey = $this->entityType->getKey('uuid'); $this->uuidKey = $this->entityType->getKey('uuid');
...@@ -716,8 +715,10 @@ protected function doLoadFieldItems($entities, $age) { ...@@ -716,8 +715,10 @@ protected function doLoadFieldItems($entities, $age) {
// Collect impacted fields. // Collect impacted fields.
$fields = array(); $fields = array();
foreach ($bundles as $bundle => $v) { foreach ($bundles as $bundle => $v) {
foreach ($this->fieldInfo->getBundleInstances($this->entityTypeId, $bundle) as $field_name => $instance) { foreach ($this->entityManager->getFieldDefinitions($this->entityTypeId, $bundle) as $field_name => $instance) {
$fields[$field_name] = $instance->getField(); if ($instance instanceof FieldInstanceConfigInterface) {
$fields[$field_name] = $instance->getField();
}
} }
} }
...@@ -781,7 +782,10 @@ protected function doSaveFieldItems(EntityInterface $entity, $update) { ...@@ -781,7 +782,10 @@ protected function doSaveFieldItems(EntityInterface $entity, $update) {
$vid = $id; $vid = $id;
} }
foreach ($this->fieldInfo->getBundleInstances($entity_type, $bundle) as $field_name => $instance) { foreach ($this->entityManager->getFieldDefinitions($entity_type, $bundle) as $field_name => $instance) {
if (!($instance instanceof FieldInstanceConfigInterface)) {
continue;
}
$field = $instance->getField(); $field = $instance->getField();
$table_name = static::_fieldTableName($field); $table_name = static::_fieldTableName($field);
$revision_name = static::_fieldRevisionTableName($field); $revision_name = static::_fieldRevisionTableName($field);
...@@ -855,7 +859,10 @@ protected function doSaveFieldItems(EntityInterface $entity, $update) { ...@@ -855,7 +859,10 @@ protected function doSaveFieldItems(EntityInterface $entity, $update) {
* {@inheritdoc} * {@inheritdoc}
*/ */
protected function doDeleteFieldItems(EntityInterface $entity) { protected function doDeleteFieldItems(EntityInterface $entity) {
foreach ($this->fieldInfo->getBundleInstances($entity->getEntityTypeId(), $entity->bundle()) as $instance) { foreach ($this->entityManager->getFieldDefinitions($entity->getEntityTypeId(), $entity->bundle()) as $instance) {
if (!($instance instanceof FieldInstanceConfigInterface)) {
continue;
}
$field = $instance->getField(); $field = $instance->getField();
$table_name = static::_fieldTableName($field); $table_name = static::_fieldTableName($field);
$revision_name = static::_fieldRevisionTableName($field); $revision_name = static::_fieldRevisionTableName($field);
...@@ -874,7 +881,10 @@ protected function doDeleteFieldItems(EntityInterface $entity) { ...@@ -874,7 +881,10 @@ protected function doDeleteFieldItems(EntityInterface $entity) {
protected function doDeleteFieldItemsRevision(EntityInterface $entity) { protected function doDeleteFieldItemsRevision(EntityInterface $entity) {
$vid = $entity->getRevisionId(); $vid = $entity->getRevisionId();
if (isset($vid)) { if (isset($vid)) {
foreach ($this->fieldInfo->getBundleInstances($entity->getEntityTypeId(), $entity->bundle()) as $instance) { foreach ($this->entityManager->getFieldDefinitions($entity->getEntityTypeId(), $entity->bundle()) as $instance) {
if (!($instance instanceof FieldInstanceConfigInterface)) {
continue;
}
$revision_name = static::_fieldRevisionTableName($instance->getField()); $revision_name = static::_fieldRevisionTableName($instance->getField());
$this->database->delete($revision_name) $this->database->delete($revision_name)
->condition('entity_id', $entity->id()) ->condition('entity_id', $entity->id())
......
...@@ -39,13 +39,6 @@ class EntityDatabaseStorage extends EntityStorageBase { ...@@ -39,13 +39,6 @@ class EntityDatabaseStorage extends EntityStorageBase {
*/ */
protected $database; protected $database;
/**
* The field info object.
*
* @var \Drupal\field\FieldInfo
*/
protected $fieldInfo;
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
......
...@@ -136,6 +136,16 @@ class EntityManager extends PluginManagerBase implements EntityManagerInterface, ...@@ -136,6 +136,16 @@ class EntityManager extends PluginManagerBase implements EntityManagerInterface,
*/ */
protected $displayModeInfo = array(); protected $displayModeInfo = array();
/**
* An array keyed by entity type. Each value is an array whose keys are
* field names and whose value is an array with two entries:
* - type: The field type.
* - bundles: The bundles in which the field appears.
*
* @return array
*/
protected $fieldMap = array();
/** /**
* Constructs a new Entity plugin manager. * Constructs a new Entity plugin manager.
* *
...@@ -521,6 +531,35 @@ public function getFieldStorageDefinitions($entity_type_id) { ...@@ -521,6 +531,35 @@ public function getFieldStorageDefinitions($entity_type_id) {
return $this->fieldStorageDefinitions[$entity_type_id]; return $this->fieldStorageDefinitions[$entity_type_id];
} }
/**
* {@inheritdoc}
*/
public function getFieldMap() {
if (!$this->fieldMap) {
// Not prepared, try to load from cache.
$cid = 'entity_field_map';
if ($cache = $this->cache->get($cid)) {
$this->fieldMap = $cache->data;
}
else {
// Rebuild the definitions and put it into the cache.
foreach ($this->getDefinitions() as $entity_type_id => $entity_type) {
if ($entity_type->isSubclassOf('\Drupal\Core\Entity\ContentEntityInterface')) {
foreach ($this->getBundleInfo($entity_type_id) as $bundle => $bundle_info) {
foreach ($this->getFieldDefinitions($entity_type_id, $bundle) as $field_name => $field_definition) {
$this->fieldMap[$entity_type_id][$field_name]['type'] = $field_definition->getType();
$this->fieldMap[$entity_type_id][$field_name]['bundles'][] = $bundle;
}
}
}
}
$this->cache->set($cid, $this->fieldMap, Cache::PERMANENT, array('entity_types' => TRUE, 'entity_field_info' => TRUE));
}
}
return $this->fieldMap;
}
/** /**
* Builds field storage definitions for an entity type. * Builds field storage definitions for an entity type.
* *
...@@ -565,6 +604,7 @@ public function clearCachedFieldDefinitions() { ...@@ -565,6 +604,7 @@ public function clearCachedFieldDefinitions() {
$this->baseFieldDefinitions = array(); $this->baseFieldDefinitions = array();
$this->fieldDefinitions = array(); $this->fieldDefinitions = array();
$this->fieldStorageDefinitions = array(); $this->fieldStorageDefinitions = array();
$this->fieldMap = array();
Cache::deleteTags(array('entity_field_info' => TRUE)); Cache::deleteTags(array('entity_field_info' => TRUE));
} }
......
...@@ -80,6 +80,17 @@ public function getFieldDefinitions($entity_type_id, $bundle); ...@@ -80,6 +80,17 @@ public function getFieldDefinitions($entity_type_id, $bundle);
*/ */
public function getFieldStorageDefinitions($entity_type_id); public function getFieldStorageDefinitions($entity_type_id);
/**
* Collects a lightweight map of fields across bundles.
*
* @return array
* An array keyed by entity type. Each value is an array which keys are
* field names and value is an array with two entries:
* - type: The field type.
* - bundles: The bundles in which the field appears.
*/
public function getFieldMap();
/** /**
* Creates a new access controller instance. * Creates a new access controller instance.
* *
......
...@@ -8,12 +8,12 @@ ...@@ -8,12 +8,12 @@
namespace Drupal\Core\Entity\Query\Sql; namespace Drupal\Core\Entity\Query\Sql;
use Drupal\Core\Database\Query\SelectInterface; use Drupal\Core\Database\Query\SelectInterface;
use Drupal\Core\Entity\ContentEntityTypeInterface;
use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\ContentEntityDatabaseStorage; use Drupal\Core\Entity\ContentEntityDatabaseStorage;
use Drupal\Core\Entity\Plugin\DataType\EntityReference;
use Drupal\Core\Entity\Query\QueryException; use Drupal\Core\Entity\Query\QueryException;
use Drupal\field\Entity\FieldConfig; use Drupal\field\Entity\FieldConfig;
use Drupal\field\Field as FieldInfo; use Drupal\field\FieldConfigInterface;
/** /**
* Adds tables and fields to the SQL entity query. * Adds tables and fields to the SQL entity query.
...@@ -58,7 +58,6 @@ public function __construct(SelectInterface $sql_query) { ...@@ -58,7 +58,6 @@ public function __construct(SelectInterface $sql_query) {
public function addField($field, $type, $langcode) { public function addField($field, $type, $langcode) {
$entity_type_id = $this->sqlQuery->getMetaData('entity_type'); $entity_type_id = $this->sqlQuery->getMetaData('entity_type');
$entity_manager = \Drupal::entityManager(); $entity_manager = \Drupal::entityManager();
$field_info = FieldInfo::fieldInfo();
$age = $this->sqlQuery->getMetaData('age'); $age = $this->sqlQuery->getMetaData('age');
// This variable ensures grouping works correctly. For example: // This variable ensures grouping works correctly. For example:
// ->condition('tags', 2, '>') // ->condition('tags', 2, '>')
...@@ -75,11 +74,13 @@ public function addField($field, $type, $langcode) { ...@@ -75,11 +74,13 @@ public function addField($field, $type, $langcode) {
// system. // system.
$propertyDefinitions = array(); $propertyDefinitions = array();
$entity_type = $entity_manager->getDefinition($entity_type_id); $entity_type = $entity_manager->getDefinition($entity_type_id);
// Use the lightweight and fast field map for checking whether a specifier
// is a field or not. While calling field_info_field() on every specifier $field_storage_definitions = array();
// delivers the same information, if no specifiers are using the field API // @todo Needed for menu links, make this implementation content entity
// it is much faster if field_info_field() is never called. // specific after https://drupal.org/node/2256521.
$field_map = $field_info->getFieldMap(); if ($entity_type instanceof ContentEntityTypeInterface) {
$field_storage_definitions = $entity_manager->getFieldStorageDefinitions($entity_type_id);
}
for ($key = 0; $key <= $count; $key ++) { for ($key = 0; $key <= $count; $key ++) {
// If there is revision support and only the current revision is being // If there is revision support and only the current revision is being
// queried then use the revision id. Otherwise, the entity id will do. // queried then use the revision id. Otherwise, the entity id will do.
...@@ -95,25 +96,27 @@ public function addField($field, $type, $langcode) { ...@@ -95,25 +96,27 @@ public function addField($field, $type, $langcode) {
$entity_id_field = $entity_type->getKey('id'); $entity_id_field = $entity_type->getKey('id');
$field_id_field = 'entity_id'; $field_id_field = 'entity_id';
} }
// This can either be the name of an entity property (non-configurable // This can either be the name of an entity base field or a configurable
// field), a field API field (a configurable field). // field.
$specifier = $specifiers[$key]; $specifier = $specifiers[$key];
// First, check for field API fields by trying to retrieve the field specified.
// Normally it is a field name, but field_purge_batch() is passing in // Normally it is a field name, but field_purge_batch() is passing in
// id:$field_id so check that first. // id:$field_id so check that first.
/* @var \Drupal\Core\Field\FieldDefinitionInterface $field */
if (substr($specifier, 0, 3) == 'id:') { if (substr($specifier, 0, 3) == 'id:') {
$field = $field_info->getFieldById((substr($specifier, 3))); if ($fields = entity_load_multiple_by_properties('field_config', array('uuid' => substr($specifier, 3), 'include_deleted' => TRUE))) {
$field = current($fields);
}
} }
elseif (isset($field_map[$entity_type_id][$specifier])) { elseif (isset($field_storage_definitions[$specifier])) {
$field = $field_info->getField($entity_type_id, $specifier); $field = $field_storage_definitions[$specifier];
} }
else { else {
$field = FALSE; $field = FALSE;
} }
// If we managed to retrieve the field, process it. // If we managed to retrieve a configurable field, process it.
if ($field) { if ($field instanceof FieldConfigInterface) {
// Find the field column. // Find the field column.
$column = FALSE; $column = $field->getMainPropertyName();
if ($key < $count) { if ($key < $count) {
$next = $specifiers[$key + 1]; $next = $specifiers[$key + 1];
// Is this a field column? // Is this a field column?
...@@ -133,39 +136,16 @@ public function addField($field, $type, $langcode) { ...@@ -133,39 +136,16 @@ public function addField($field, $type, $langcode) {
// also use the property definitions for column. // also use the property definitions for column.
if ($key < $count) { if ($key < $count) {
$relationship_specifier = $specifiers[$key + 1]; $relationship_specifier = $specifiers[$key + 1];
$propertyDefinitions = $field->getPropertyDefinitions();
// Get the field definitions form a mocked entity.
$values = array();
$field_name = $field->getName();
// If there are bundles, pick one.
if ($bundle_key = $entity_type->getKey('bundle')) {
$values[$bundle_key] = reset($field_map[$entity_type_id][$field_name]['bundles']);
}
$entity = $entity_manager
->getStorage($entity_type_id)
->create($values);
$propertyDefinitions = $entity->$field_name->getFieldDefinition()->getPropertyDefinitions();
// If the column is not yet known, ie. the
// $node->field_image->entity case then use first property as
// column, i.e. target_id or fid.
// Otherwise, the code executing the relationship will throw an
// exception anyways so no need to do it here.
if (!$column && isset($propertyDefinitions[$relationship_specifier]) && $entity->{$field->getName()}->first()->get('entity') instanceof EntityReference) {
$column = current(array_keys($propertyDefinitions));
}
// Prepare the next index prefix. // Prepare the next index prefix.
$next_index_prefix = "$relationship_specifier.$column"; $next_index_prefix = "$relationship_specifier.$column";
} }
} }
else {
// If this is the last specifier, default to value.
$column = 'value';
}
$table = $this->ensureFieldTable($index_prefix, $field, $type, $langcode, $base_table, $entity_id_field, $field_id_field); $table = $this->ensureFieldTable($index_prefix, $field, $type, $langcode, $base_table, $entity_id_field, $field_id_field);
$sql_column = ContentEntityDatabaseStorage::_fieldColumnName($field, $column); $sql_column = ContentEntityDatabaseStorage::_fieldColumnName($field, $column);
} }
// This is an entity property (non-configurable field). // This is an entity base field (non-configurable field).
else { else {
// ensureEntityTable() decides whether an entity property will be // ensureEntityTable() decides whether an entity property will be
// queried from the data table or the base table based on where it // queried from the data table or the base table based on where it
...@@ -182,31 +162,20 @@ public function addField($field, $type, $langcode) { ...@@ -182,31 +162,20 @@ public function addField($field, $type, $langcode) {
$table = $this->ensureEntityTable($index_prefix, $specifier, $type, $langcode, $base_table, $entity_id_field, $entity_tables); $table = $this->ensureEntityTable($index_prefix, $specifier, $type, $langcode, $base_table, $entity_id_field, $entity_tables);
} }
// If there are more specifiers to come, it's a relationship. // If there are more specifiers to come, it's a relationship.
if ($key < $count) { if ($field && $key < $count) {
// Computed fields have prepared their property definition already, do // Computed fields have prepared their property definition already, do
// it for properties as well. // it for properties as well.
if (!$propertyDefinitions) { if (!$propertyDefinitions) {
// Create a relevant entity to find the definition for this $propertyDefinitions = $field->getPropertyDefinitions();
// property.
$values = array();
// If there are bundles, pick one. It does not matter which,
// properties exist on all bundles.
if ($bundle_key = $entity_type->getKey('bundle')) {
$bundles = entity_get_bundles($entity_type_id);
$values[$bundle_key] = key($bundles);
}
$entity = $entity_manager
->getStorage($entity_type_id)
->create($values);
$propertyDefinitions = $entity->$specifier->getFieldDefinition()->getPropertyDefinitions();
$relationship_specifier = $specifiers[$key + 1]; $relationship_specifier = $specifiers[$key + 1];
$next_index_prefix = $relationship_specifier; $next_index_prefix = $relationship_specifier;
} }
// Check for a valid relationship. // Check for a valid relationship.
if (isset($propertyDefinitions[$relationship_specifier]) && $entity->get($specifier)->first()->get('entity') instanceof EntityReference) { if (isset($propertyDefinitions[$relationship_specifier]) && $field->getPropertyDefinition('entity')->getDataType() == 'entity_reference' ) {
// If it is, use the entity type. // If it is, use the entity type.
$entity_type_id = $propertyDefinitions[$relationship_specifier]->getTargetDefinition()->getEntityTypeId(); $entity_type_id = $propertyDefinitions[$relationship_specifier]->getTargetDefinition()->getEntityTypeId();
$entity_type = $entity_manager->getDefinition($entity_type_id); $entity_type = $entity_manager->getDefinition($entity_type_id);
$field_storage_definitions = $entity_manager->getFieldStorageDefinitions($entity_type_id);
// Add the new entity base table using the table and sql column. // Add the new entity base table using the table and sql column.
$join_condition= '%alias.' . $entity_type->getKey('id') . " = $table.$sql_column"; $join_condition= '%alias.' . $entity_type->getKey('id') . " = $table.$sql_column";
$base_table = $this->sqlQuery->leftJoin($entity_type->getBaseTable(), NULL, $join_condition); $base_table = $this->sqlQuery->leftJoin($entity_type->getBaseTable(), NULL, $join_condition);
......
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
use Drupal\custom_block\Entity\CustomBlockType; use Drupal\custom_block\Entity\CustomBlockType;
use Drupal\custom_block\Entity\CustomBlock; use Drupal\custom_block\Entity\CustomBlock;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldInstanceConfig;
/** /**
* Implements hook_help(). * Implements hook_help().
...@@ -115,8 +117,8 @@ function custom_block_entity_bundle_info() { ...@@ -115,8 +117,8 @@ function custom_block_entity_bundle_info() {
*/ */
function custom_block_add_body_field($block_type_id, $label = 'Body') { function custom_block_add_body_field($block_type_id, $label = 'Body') {
// Add or remove the body field, as needed. // Add or remove the body field, as needed.
$field = field_info_field('custom_block', 'body'); $field = FieldConfig::loadByName('custom_block', 'body');
$instance = field_info_instance('custom_block', 'body', $block_type_id); $instance = FieldInstanceConfig::loadByName('custom_block', $block_type_id, 'body');
if (empty($field)) { if (empty($field)) {
$field = entity_create('field_config', array( $field = entity_create('field_config', array(
'name' => 'body', 'name' => 'body',
......
...@@ -78,8 +78,8 @@ public function testCustomBlockTypeEditing() { ...@@ -78,8 +78,8 @@ public function testCustomBlockTypeEditing() {
// We need two block types to prevent /block/add redirecting. // We need two block types to prevent /block/add redirecting.
$this->createCustomBlockType('other'); $this->createCustomBlockType('other');
$instance = field_info_instance('custom_block', 'body', 'basic'); $field_definition = \Drupal::entityManager()->getFieldDefinitions('custom_block', 'other')['body'];
$this->assertEqual($instance->getLabel(), 'Body', 'Body field was found.'); $this->assertEqual($field_definition->getLabel(), 'Body', 'Body field was found.');
// Verify that title and body fields are displayed. // Verify that title and body fields are displayed.
$this->drupalGet('block/add/basic'); $this->drupalGet('block/add/basic');
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityInterface;
use Drupal\entity\Entity\EntityViewDisplay; use Drupal\entity\Entity\EntityViewDisplay;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface; use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Render\Element; use Drupal\Core\Render\Element;
use Drupal\Core\Url; use Drupal\Core\Url;
use Drupal\field\FieldInstanceConfigInterface; use Drupal\field\FieldInstanceConfigInterface;
...@@ -98,14 +99,25 @@ function comment_help($route_name, Request $request) { ...@@ -98,14 +99,25 @@ function comment_help($route_name, Request $request) {
*/ */
function comment_entity_bundle_info() { function comment_entity_bundle_info() {
$bundles = array(); $bundles = array();
foreach (\Drupal::service('comment.manager')->getAllFields() as $entity_type => $fields) { $ids = \Drupal::entityQuery('field_config')
foreach ($fields as $field_name => $field_info) { ->condition('type', 'comment')
$sample_bundle = reset($field_info['bundles']); ->execute();
// We cannot use field info API here because it will result in recursion. $config_factory = \Drupal::configFactory();
$config = \Drupal::config('field.instance.' . $entity_type . '.' . $sample_bundle . '.' . $field_name); foreach ($ids as $id) {
$bundles['comment'][$entity_type . '__' . $field_name] = array( // @todo: We can not rely on the field map here, so we need to manually look
'label' => $config->get('label'), // for a matching field instance to use for the label. Remove this in
); // https://drupal.org/node/2228763.
list($entity_type_id, $field_name) = explode('.', $id);
$instance_ids = $config_factory->listAll('field.instance.' . $entity_type_id . '.');
// Look for an instance for this field.
foreach ($instance_ids as $instance_id) {
$instance_field_name = substr($instance_id, strrpos($instance_id, '.') + 1);
if ($instance_field_name == $field_name) {
$config = \Drupal::config($instance_id);
$bundles['comment'][$entity_type_id . '__' . $field_name] = array(
'label' => $config->get('label'),
);
}
} }
} }
return $bundles; return $bundles;
...@@ -407,7 +419,7 @@ function comment_node_links_alter(array &$node_links, NodeInterface $node, array ...@@ -407,7 +419,7 @@ function comment_node_links_alter(array &$node_links, NodeInterface $node, array
$links = array(); $links = array();
$commenting_status = $node->get($field_name)->status; $commenting_status = $node->get($field_name)->status;
if ($commenting_status) { if ($commenting_status) {
$instance = \Drupal::service('field.info')->getInstance('node', $node->bundle(), $field_name); $field_definition = $node->getFieldDefinition($field_name);
// Node have commenting open or close. // Node have commenting open or close.
if ($view_mode == 'rss') { if ($view_mode == 'rss') {
// Add a comments RSS element which is a URL to the comments of this node. // Add a comments RSS element which is a URL to the comments of this node.
...@@ -449,7 +461,7 @@ function comment_node_links_alter(array &$node_links, NodeInterface $node, array ...@@ -449,7 +461,7 @@ function comment_node_links_alter(array &$node_links, NodeInterface $node, array
} }
// Provide a link to new comment form. // Provide a link to new comment form.
if ($commenting_status == CommentItemInterface::OPEN) { if ($commenting_status == CommentItemInterface::OPEN) {
$comment_form_location = $instance->getSetting('form_location'); $comment_form_location = $field_definition->getSetting('form_location');
if (user_access('post comments')) { if (user_access('post comments')) {
$links['comment-add'] = array( $links['comment-add'] = array(
'title' => t('Add new comment'), 'title' => t('Add new comment'),
...@@ -481,7 +493,7 @@ function comment_node_links_alter(array &$node_links, NodeInterface $node, array ...@@ -481,7 +493,7 @@ function comment_node_links_alter(array &$node_links, NodeInterface $node, array
// Node in other view modes: add a "post comment" link if the user is // Node in other view modes: add a "post comment" link if the user is
// allowed to post comments and if this node is allowing new comments. // allowed to post comments and if this node is allowing new comments.
if ($commenting_status == CommentItemInterface::OPEN) { if ($commenting_status == CommentItemInterface::OPEN) {
$comment_form_location = $instance->getSetting('form_location'); $comment_form_location = $field_definition->getSetting('form_location');
if (user_access('post comments')) { if (user_access('post comments')) {
// Show the "post comment" link if the form is on another page, or // Show the "post comment" link if the form is on another page, or
// if there are existing comments that the link will skip past. // if there are existing comments that the link will skip past.
...@@ -1135,16 +1147,15 @@ function comment_num_new($entity_id, $entity_type, $field_name = NULL, $timestam ...@@ -1135,16 +1147,15 @@ function comment_num_new($entity_id, $entity_type, $field_name = NULL, $timestam
* *
* @param int $cid * @param int $cid
* The comment ID. * The comment ID.
* @param array $instance * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
* Field instance as returned from field_info_instance(). * Field definition of the comments.
* *
* @return int * @return int
* The display ordinal for the comment. * The display ordinal for the comment.
* *
* @see comment_get_display_page() * @see comment_get_display_page()
* @see field_info_instance().
*/ */
function comment_get_display_ordinal($cid, $instance) { function comment_get_display_ordinal($cid, FieldDefinitionInterface $field_definition) {
// Count how many comments (c1) are before $cid (c2) in display order. This is // Count how many comments (c1) are before $cid (c2) in display order. This is
// the 0-based display ordinal. // the 0-based display ordinal.
$query = db_select('comment', 'c1'); $query = db_select('comment', 'c1');
...@@ -1155,7 +1166,7 @@ function comment_get_display_ordinal($cid, $instance) { ...@@ -1155,7 +1166,7 @@ function comment_get_display_ordinal($cid, $instance) {
$query->condition('c1.status', CommentInterface::PUBLISHED); $query->condition('c1.status', CommentInterface::PUBLISHED);
} }
if ($instance->getSetting('default_mode') == COMMENT_MODE_FLAT) { if ($field_definition->getSetting('default_mode') == COMMENT_MODE_FLAT) {
// For flat comments, cid is used for ordering comments due to // For flat comments, cid is used for ordering comments due to
// unpredictable behavior with timestamp, so we make the same assumption // unpredictable behavior with timestamp, so we make the same assumption
// here. // here.
...@@ -1179,15 +1190,15 @@ function comment_get_display_ordinal($cid, $instance) { ...@@ -1179,15 +1190,15 @@ function comment_get_display_ordinal($cid, $instance) {
* *
* @param int $cid * @param int $cid
* The comment ID. * The comment ID.