diff --git a/core/lib/Drupal/Core/Entity/ContentEntityDatabaseStorage.php b/core/lib/Drupal/Core/Entity/ContentEntityDatabaseStorage.php index 22cf527..d3bca5f 100644 --- a/core/lib/Drupal/Core/Entity/ContentEntityDatabaseStorage.php +++ b/core/lib/Drupal/Core/Entity/ContentEntityDatabaseStorage.php @@ -11,7 +11,6 @@ use Drupal\Core\Entity\Query\QueryInterface; use Drupal\Core\Field\FieldStorageDefinitionInterface; use Drupal\Core\Language\Language; -use Drupal\field\FieldInfo; use Drupal\field\FieldConfigUpdateForbiddenException; use Drupal\field\FieldConfigInterface; use Drupal\field\FieldInstanceConfigInterface; @@ -73,11 +72,11 @@ class ContentEntityDatabaseStorage extends ContentEntityStorageBase { protected $database; /** - * The field info object. + * The entity manager. * - * @var \Drupal\field\FieldInfo + * @var \Drupal\Core\Entity\EntityManagerInterface */ - protected $fieldInfo; + protected $entityManager; /** * {@inheritdoc} @@ -86,7 +85,7 @@ public static function createInstance(ContainerInterface $container, EntityTypeI return new static( $entity_type, $container->get('database'), - $container->get('field.info') + $container->get('entity.manager') ); } @@ -97,14 +96,14 @@ public static function createInstance(ContainerInterface $container, EntityTypeI * The entity type definition. * @param \Drupal\Core\Database\Connection $database * The database connection to be used. - * @param \Drupal\field\FieldInfo $field_info - * The field info service. + * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager + * 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); $this->database = $database; - $this->fieldInfo = $field_info; + $this->entityManager = $entity_manager; // Check if the entity type supports IDs. if ($this->entityType->hasKey('id')) { @@ -791,8 +790,10 @@ protected function doLoadFieldItems($entities, $age) { // Collect impacted fields. $fields = array(); foreach ($bundles as $bundle => $v) { - foreach ($this->fieldInfo->getBundleInstances($this->entityTypeId, $bundle) as $field_name => $instance) { - $fields[$field_name] = $instance->getField(); + foreach ($this->entityManager->getFieldDefinitions($this->entityTypeId, $bundle) as $field_name => $instance) { + if ($instance instanceof FieldInstanceConfigInterface) { + $fields[$field_name] = $instance->getField(); + } } } @@ -856,7 +857,10 @@ protected function doSaveFieldItems(EntityInterface $entity, $update) { $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(); $table_name = static::_fieldTableName($field); $revision_name = static::_fieldRevisionTableName($field); @@ -930,7 +934,10 @@ protected function doSaveFieldItems(EntityInterface $entity, $update) { * {@inheritdoc} */ 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(); $table_name = static::_fieldTableName($field); $revision_name = static::_fieldRevisionTableName($field); @@ -949,7 +956,10 @@ protected function doDeleteFieldItems(EntityInterface $entity) { protected function doDeleteFieldItemsRevision(EntityInterface $entity) { $vid = $entity->getRevisionId(); 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()); $this->database->delete($revision_name) ->condition('entity_id', $entity->id()) diff --git a/core/lib/Drupal/Core/Entity/EntityDatabaseStorage.php b/core/lib/Drupal/Core/Entity/EntityDatabaseStorage.php index 180dfef..3b20fe4 100644 --- a/core/lib/Drupal/Core/Entity/EntityDatabaseStorage.php +++ b/core/lib/Drupal/Core/Entity/EntityDatabaseStorage.php @@ -9,16 +9,7 @@ use Drupal\Component\Uuid\UuidInterface; use Drupal\Core\Database\Connection; -use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Entity\Query\QueryInterface; -use Drupal\Core\Language\Language; -use Drupal\Component\Utility\NestedArray; -use Drupal\Component\Uuid\Uuid; -use Drupal\field\FieldInfo; -use Drupal\field\FieldConfigUpdateForbiddenException; -use Drupal\field\FieldConfigInterface; -use Drupal\field\FieldInstanceConfigInterface; -use Drupal\field\Entity\FieldConfig; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -50,13 +41,6 @@ class EntityDatabaseStorage extends EntityStorageBase { protected $database; /** - * The field info object. - * - * @var \Drupal\field\FieldInfo - */ - protected $fieldInfo; - - /** * {@inheritdoc} */ public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) { diff --git a/core/lib/Drupal/Core/Entity/EntityManager.php b/core/lib/Drupal/Core/Entity/EntityManager.php index 679f849..2fc0e0a 100644 --- a/core/lib/Drupal/Core/Entity/EntityManager.php +++ b/core/lib/Drupal/Core/Entity/EntityManager.php @@ -135,6 +135,16 @@ class EntityManager extends PluginManagerBase implements EntityManagerInterface, protected $displayModeInfo = 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. + * + * @return array + */ + protected $fieldMap = array(); + + /** * Constructs a new Entity plugin manager. * * @param \Traversable $namespaces @@ -514,6 +524,35 @@ public function getFieldStorageDefinitions($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 instanceof ContentEntityTypeInterface) { + 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. * * @param string $entity_type_id @@ -557,6 +596,7 @@ public function clearCachedFieldDefinitions() { $this->baseFieldDefinitions = array(); $this->fieldDefinitions = array(); $this->fieldStorageDefinitions = array(); + $this->fieldMap = array(); Cache::deleteTags(array('entity_field_info' => TRUE)); } diff --git a/core/lib/Drupal/Core/Entity/EntityManagerInterface.php b/core/lib/Drupal/Core/Entity/EntityManagerInterface.php index da36a36..6ce0ea8 100644 --- a/core/lib/Drupal/Core/Entity/EntityManagerInterface.php +++ b/core/lib/Drupal/Core/Entity/EntityManagerInterface.php @@ -77,6 +77,17 @@ public function getFieldDefinitions($entity_type_id, $bundle); 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. * * @param string $entity_type diff --git a/core/lib/Drupal/Core/Entity/Query/Sql/Tables.php b/core/lib/Drupal/Core/Entity/Query/Sql/Tables.php index ee2bebc..77ef12f 100644 --- a/core/lib/Drupal/Core/Entity/Query/Sql/Tables.php +++ b/core/lib/Drupal/Core/Entity/Query/Sql/Tables.php @@ -8,12 +8,12 @@ namespace Drupal\Core\Entity\Query\Sql; use Drupal\Core\Database\Query\SelectInterface; +use Drupal\Core\Entity\ContentEntityTypeInterface; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Entity\ContentEntityDatabaseStorage; -use Drupal\Core\Entity\Plugin\DataType\EntityReference; use Drupal\Core\Entity\Query\QueryException; use Drupal\field\Entity\FieldConfig; -use Drupal\field\Field as FieldInfo; +use Drupal\field\FieldConfigInterface; /** * Adds tables and fields to the SQL entity query. @@ -58,7 +58,6 @@ public function __construct(SelectInterface $sql_query) { public function addField($field, $type, $langcode) { $entity_type_id = $this->sqlQuery->getMetaData('entity_type'); $entity_manager = \Drupal::entityManager(); - $field_info = FieldInfo::fieldInfo(); $age = $this->sqlQuery->getMetaData('age'); // This variable ensures grouping works correctly. For example: // ->condition('tags', 2, '>') @@ -75,11 +74,13 @@ public function addField($field, $type, $langcode) { // system. $propertyDefinitions = array(); $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 - // delivers the same information, if no specifiers are using the field API - // it is much faster if field_info_field() is never called. - $field_map = $field_info->getFieldMap(); + + $storage_definitions = array(); + // @todo Needed for menu links, make this implementation content entity + // specific after https://drupal.org/node/1842858. + if ($entity_type instanceof ContentEntityTypeInterface) { + $storage_definitions = $entity_manager->getFieldStorageDefinitions($entity_type_id); + } for ($key = 0; $key <= $count; $key ++) { // If there is revision support and only the current revision is being // queried then use the revision id. Otherwise, the entity id will do. @@ -95,25 +96,27 @@ public function addField($field, $type, $langcode) { $entity_id_field = $entity_type->getKey('id'); $field_id_field = 'entity_id'; } - // This can either be the name of an entity property (non-configurable - // field), a field API field (a configurable field). + // This can either be the name of an entity base field or a configurable + // field. $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 // id:$field_id so check that first. + /* @var \Drupal\Core\Field\FieldDefinitionInterface $field */ 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])) { - $field = $field_info->getField($entity_type_id, $specifier); + elseif (isset($storage_definitions[$specifier])) { + $field = $storage_definitions[$specifier]; } else { $field = FALSE; } - // If we managed to retrieve the field, process it. - if ($field) { + // If we managed to retrieve a configurable field, process it. + if ($field instanceof FieldConfigInterface) { // Find the field column. - $column = FALSE; + $column = $field->getMainPropertyName(); if ($key < $count) { $next = $specifiers[$key + 1]; // Is this a field column? @@ -133,39 +136,16 @@ public function addField($field, $type, $langcode) { // also use the property definitions for column. if ($key < $count) { $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. $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); $sql_column = ContentEntityDatabaseStorage::_fieldColumnName($field, $column); } - // This is an entity property (non-configurable field). + // This is an entity base field (non-configurable field). else { // ensureEntityTable() decides whether an entity property will be // queried from the data table or the base table based on where it @@ -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); } // 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 // it for properties as well. if (!$propertyDefinitions) { - // Create a relevant entity to find the definition for this - // 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(); + $propertyDefinitions = $field->getPropertyDefinitions(); $relationship_specifier = $specifiers[$key + 1]; $next_index_prefix = $relationship_specifier; } // 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. $entity_type_id = $propertyDefinitions[$relationship_specifier]->getTargetDefinition()->getEntityTypeId(); $entity_type = $entity_manager->getDefinition($entity_type_id); + $storage_definitions = $entity_manager->getFieldStorageDefinitions($entity_type_id); // Add the new entity base table using the table and sql column. $join_condition= '%alias.' . $entity_type->getKey('id') . " = $table.$sql_column"; $base_table = $this->sqlQuery->leftJoin($entity_type->getBaseTable(), NULL, $join_condition); diff --git a/core/modules/block/custom_block/custom_block.module b/core/modules/block/custom_block/custom_block.module index bfe5a39..c84276a 100644 --- a/core/modules/block/custom_block/custom_block.module +++ b/core/modules/block/custom_block/custom_block.module @@ -7,6 +7,8 @@ use Drupal\custom_block\Entity\CustomBlockType; use Drupal\custom_block\Entity\CustomBlock; +use Drupal\field\Entity\FieldConfig; +use Drupal\field\Entity\FieldInstanceConfig; /** * Implements hook_help(). @@ -114,8 +116,8 @@ function custom_block_entity_bundle_info() { */ function custom_block_add_body_field($block_type_id, $label = 'Block body') { // Add or remove the body field, as needed. - $field = field_info_field('custom_block', 'body'); - $instance = field_info_instance('custom_block', 'body', $block_type_id); + $field = FieldConfig::loadByName('custom_block', 'body'); + $instance = FieldInstanceConfig::loadByName('custom_block', $block_type_id, 'body'); if (empty($field)) { $field = entity_create('field_config', array( 'name' => 'body', diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockTypeTest.php b/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockTypeTest.php index 739f234..d193be9 100644 --- a/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockTypeTest.php +++ b/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockTypeTest.php @@ -78,8 +78,8 @@ public function testCustomBlockTypeEditing() { // We need two block types to prevent /block/add redirecting. $this->createCustomBlockType('other'); - $instance = field_info_instance('custom_block', 'body', 'basic'); - $this->assertEqual($instance->getLabel(), 'Block body', 'Body field was found.'); + $field_definition = \Drupal::entityManager()->getFieldDefinitions('custom_block', 'other')['body']; + $this->assertEqual($field_definition->getLabel(), 'Block body', 'Body field was found.'); // Verify that title and body fields are displayed. $this->drupalGet('block/add/basic'); diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module index 4115444..a85f449 100644 --- a/core/modules/comment/comment.module +++ b/core/modules/comment/comment.module @@ -14,6 +14,7 @@ use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\Display\EntityViewDisplayInterface; +use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Render\Element; use Drupal\Core\Url; use Drupal\field\FieldInstanceConfigInterface; @@ -96,15 +97,18 @@ function comment_help($path, $arg) { */ function comment_entity_bundle_info() { $bundles = array(); - foreach (\Drupal::service('comment.manager')->getAllFields() as $entity_type => $fields) { - foreach ($fields as $field_name => $field_info) { - $sample_bundle = reset($field_info['bundles']); - // We cannot use field info API here because it will result in recursion. - $config = \Drupal::config('field.instance.' . $entity_type . '.' . $sample_bundle . '.' . $field_name); - $bundles['comment'][$entity_type . '__' . $field_name] = array( - 'label' => $config->get('label'), - ); - } + $ids = \Drupal::entityQuery('field_config') + ->condition('type', 'comment') + ->execute(); + $config_factory = \Drupal::configFactory(); + foreach ($ids as $id) { + list($entity_type_id, $field_name) = explode('.', $id); + $instance_ids = $config_factory->listAll('field.instance.' . $id . '.'); + $instance_id = reset($instance_ids); + $config = \Drupal::config('field.instance.' . $instance_id); + $bundles['comment'][$entity_type_id . '__' . $field_name] = array( + 'label' => $config->get('label'), + ); } return $bundles; } @@ -1131,16 +1135,15 @@ function comment_num_new($entity_id, $entity_type, $field_name = NULL, $timestam * * @param int $cid * The comment ID. - * @param array $instance - * Field instance as returned from field_info_instance(). + * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition + * Field definition of the comments. * * @return int * The display ordinal for the comment. * * @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 // the 0-based display ordinal. $query = db_select('comment', 'c1'); @@ -1151,7 +1154,7 @@ function comment_get_display_ordinal($cid, $instance) { $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 // unpredictable behavior with timestamp, so we make the same assumption // here. @@ -1175,15 +1178,15 @@ function comment_get_display_ordinal($cid, $instance) { * * @param int $cid * The comment ID. - * @param array $instance - * Field instance as returned from field_info_instance(). + * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition + * Field definition of the comments. * * @return int * The page number. */ -function comment_get_display_page($cid, $instance) { - $ordinal = comment_get_display_ordinal($cid, $instance); - $comments_per_page = $instance->getSetting('per_page'); +function comment_get_display_page($cid, FieldDefinitionInterface $field_definition) { + $ordinal = comment_get_display_ordinal($cid, $field_definition); + $comments_per_page = $field_definition->getSetting('per_page'); return floor($ordinal / $comments_per_page); } diff --git a/core/modules/comment/comment.services.yml b/core/modules/comment/comment.services.yml index 76fdbc4..13846b1 100644 --- a/core/modules/comment/comment.services.yml +++ b/core/modules/comment/comment.services.yml @@ -7,7 +7,7 @@ services: comment.manager: class: Drupal\comment\CommentManager - arguments: ['@field.info', '@entity.manager', '@config.factory', '@string_translation', '@url_generator'] + arguments: ['@entity.manager', '@config.factory', '@string_translation', '@url_generator'] comment.statistics: class: Drupal\comment\CommentStatistics diff --git a/core/modules/comment/lib/Drupal/comment/CommentFormController.php b/core/modules/comment/lib/Drupal/comment/CommentFormController.php index e9759eb..dfc0691 100644 --- a/core/modules/comment/lib/Drupal/comment/CommentFormController.php +++ b/core/modules/comment/lib/Drupal/comment/CommentFormController.php @@ -16,7 +16,6 @@ use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Language\Language; use Drupal\Core\Session\AccountInterface; -use Drupal\field\FieldInfo; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -25,13 +24,6 @@ class CommentFormController extends ContentEntityFormController { /** - * The field info service. - * - * @var \Drupal\field\FieldInfo - */ - protected $fieldInfo; - - /** * The current user. * * @var \Drupal\Core\Session\AccountInterface @@ -44,7 +36,6 @@ class CommentFormController extends ContentEntityFormController { public static function create(ContainerInterface $container) { return new static( $container->get('entity.manager'), - $container->get('field.info'), $container->get('current_user') ); } @@ -59,9 +50,8 @@ public static function create(ContainerInterface $container) { * @param \Drupal\Core\Session\AccountInterface $current_user * The current user. */ - public function __construct(EntityManagerInterface $entity_manager, FieldInfo $field_info, AccountInterface $current_user) { + public function __construct(EntityManagerInterface $entity_manager, AccountInterface $current_user) { parent::__construct($entity_manager); - $this->fieldInfo = $field_info; $this->currentUser = $current_user; } @@ -89,13 +79,13 @@ public function form(array $form, array &$form_state) { $comment = $this->entity; $entity = $this->entityManager->getStorage($comment->getCommentedEntityTypeId())->load($comment->getCommentedEntityId()); $field_name = $comment->getFieldName(); - $instance = $this->fieldInfo->getInstance($entity->getEntityTypeId(), $entity->bundle(), $field_name); + $field_definition = $this->entityManager->getFieldDefinitions($entity->getEntityTypeId(), $entity->bundle())[$comment->getFieldName()]; // Use #comment-form as unique jump target, regardless of entity type. $form['#id'] = drupal_html_id('comment_form'); $form['#theme'] = array('comment_form__' . $entity->getEntityTypeId() . '__' . $entity->bundle() . '__' . $field_name, 'comment_form'); - $anonymous_contact = $instance->getSetting('anonymous'); + $anonymous_contact = $field_definition->getSetting('anonymous'); $is_admin = $comment->id() && $this->currentUser->hasPermission('administer comments'); if (!$this->currentUser->isAuthenticated() && $anonymous_contact != COMMENT_ANONYMOUS_MAYNOT_CONTACT) { @@ -214,7 +204,7 @@ public function form(array $form, array &$form_state) { '#title' => $this->t('Subject'), '#maxlength' => 64, '#default_value' => $comment->getSubject(), - '#access' => $instance->getSetting('subject'), + '#access' => $field_definition->getSetting('subject'), ); // Used for conditional validation of author fields. @@ -241,8 +231,8 @@ protected function actions(array $form, array &$form_state) { /* @var \Drupal\comment\CommentInterface $comment */ $comment = $this->entity; $entity = $comment->getCommentedEntity(); - $instance = $this->fieldInfo->getInstance($comment->getCommentedEntityTypeId(), $entity->bundle(), $comment->getFieldName()); - $preview_mode = $instance->getSetting('preview'); + $field_definition = $this->entityManager->getFieldDefinitions($entity->getEntityTypeId(), $entity->bundle())[$comment->getFieldName()]; + $preview_mode = $field_definition->getSetting('preview'); // No delete action on the comment form. unset($element['delete']); @@ -404,8 +394,8 @@ public function save(array $form, array &$form_state) { } $query = array(); // Find the current display page for this comment. - $instance = $this->fieldInfo->getInstance($entity->getEntityTypeId(), $entity->bundle(), $field_name); - $page = comment_get_display_page($comment->id(), $instance); + $field_definition = $this->entityManager->getFieldDefinitions($entity->getEntityTypeId(), $entity->bundle())[$field_name]; + $page = comment_get_display_page($comment->id(), $field_definition); if ($page > 0) { $query['page'] = $page; } diff --git a/core/modules/comment/lib/Drupal/comment/CommentManager.php b/core/modules/comment/lib/Drupal/comment/CommentManager.php index fcb3277..3250d85 100644 --- a/core/modules/comment/lib/Drupal/comment/CommentManager.php +++ b/core/modules/comment/lib/Drupal/comment/CommentManager.php @@ -15,7 +15,6 @@ use Drupal\Core\Routing\UrlGeneratorInterface; use Drupal\Core\Session\AccountInterface; use Drupal\Core\StringTranslation\TranslationInterface; -use Drupal\field\FieldInfo; /** * Comment manager contains common functions to manage comment fields. @@ -23,13 +22,6 @@ class CommentManager implements CommentManagerInterface { /** - * The field info service. - * - * @var \Drupal\field\FieldInfo - */ - protected $fieldInfo; - - /** * The entity manager service. * * @var \Drupal\Core\Entity\EntityManagerInterface @@ -67,8 +59,6 @@ class CommentManager implements CommentManagerInterface { /** * Construct the CommentManager object. * - * @param \Drupal\field\FieldInfo $field_info - * The field info service. * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager * The entity manager service. * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory @@ -78,8 +68,7 @@ class CommentManager implements CommentManagerInterface { * @param \Drupal\Core\Routing\UrlGeneratorInterface $url_generator * The url generator service. */ - public function __construct(FieldInfo $field_info, EntityManagerInterface $entity_manager, ConfigFactoryInterface $config_factory, TranslationInterface $translation_manager, UrlGeneratorInterface $url_generator) { - $this->fieldInfo = $field_info; + public function __construct(EntityManagerInterface $entity_manager, ConfigFactoryInterface $config_factory, TranslationInterface $translation_manager, UrlGeneratorInterface $url_generator) { $this->entityManager = $entity_manager; $this->userConfig = $config_factory->get('user.settings'); $this->translationManager = $translation_manager; @@ -113,7 +102,7 @@ public function getFields($entity_type_id) { * {@inheritdoc} */ public function getAllFields() { - $map = $this->fieldInfo->getFieldMap(); + $map = $this->entityManager->getFieldMap(); // Build a list of comment fields only. $comment_fields = array(); foreach ($map as $entity_type => $data) { @@ -131,7 +120,7 @@ public function getAllFields() { */ public function addDefaultField($entity_type, $bundle, $field_name = 'comment', $default_value = CommentItemInterface::OPEN) { // Make sure the field doesn't already exist. - if (!$this->fieldInfo->getField($entity_type, $field_name)) { + if (!$this->entityManager->getStorage('field_config')->load($entity_type . '.' . $field_name)) { // Add a default comment field for existing node comments. $field = $this->entityManager->getStorage('field_config')->create(array( 'entity_type' => $entity_type, @@ -146,7 +135,7 @@ public function addDefaultField($entity_type, $bundle, $field_name = 'comment', $field->save(); } // Make sure the instance doesn't already exist. - if (!$this->fieldInfo->getInstance($entity_type, $bundle, $field_name)) { + if (!$this->entityManager->getStorage('field_instance_config')->load($entity_type . '.' . $bundle . '.' . $field_name)) { $instance = $this->entityManager->getStorage('field_instance_config')->create(array( 'label' => 'Comment settings', 'description' => '', @@ -256,11 +245,10 @@ public function addBodyField($entity_type, $field_name) { * {@inheritdoc} */ public function getFieldUIPageTitle($commented_entity_type, $field_name) { - $field_info = $this->fieldInfo->getField($commented_entity_type, $field_name); - $bundles = $field_info->getBundles(); - $sample_bundle = reset($bundles); - $sample_instance = $this->fieldInfo->getInstance($commented_entity_type, $sample_bundle, $field_name); - return String::checkPlain($sample_instance->label); + $field_info = $this->getFields($commented_entity_type); + $sample_bundle = reset($field_info[$field_name]['bundles']); + $sample_definition = $this->entityManager->getFieldDefinitions($commented_entity_type, $sample_bundle)[$field_name]; + return String::checkPlain($sample_definition->getLabel()); } /** diff --git a/core/modules/comment/lib/Drupal/comment/CommentStorage.php b/core/modules/comment/lib/Drupal/comment/CommentStorage.php index d05b2c3..6343587 100644 --- a/core/modules/comment/lib/Drupal/comment/CommentStorage.php +++ b/core/modules/comment/lib/Drupal/comment/CommentStorage.php @@ -9,9 +9,9 @@ use Drupal\Core\Database\Connection; use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Entity\ContentEntityDatabaseStorage; -use Drupal\field\FieldInfo; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -36,13 +36,13 @@ class CommentStorage extends ContentEntityDatabaseStorage implements CommentStor * An array of entity info for the entity type. * @param \Drupal\Core\Database\Connection $database * The database connection to be used. - * @param \Drupal\field\FieldInfo $field_info - * The field info service. + * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager + * The entity manager. * @param \Drupal\comment\CommentStatisticsInterface $comment_statistics * The comment statistics service. */ - public function __construct(EntityTypeInterface $entity_info, Connection $database, FieldInfo $field_info, CommentStatisticsInterface $comment_statistics) { - parent::__construct($entity_info, $database, $field_info); + public function __construct(EntityTypeInterface $entity_info, Connection $database, EntityManagerInterface $entity_manager, CommentStatisticsInterface $comment_statistics) { + parent::__construct($entity_info, $database, $entity_manager); $this->statistics = $comment_statistics; } @@ -53,7 +53,7 @@ public static function createInstance(ContainerInterface $container, EntityTypeI return new static( $entity_info, $container->get('database'), - $container->get('field.info'), + $container->get('entity.manager'), $container->get('comment.statistics') ); } diff --git a/core/modules/comment/lib/Drupal/comment/CommentViewBuilder.php b/core/modules/comment/lib/Drupal/comment/CommentViewBuilder.php index da28f7b..80f746c 100644 --- a/core/modules/comment/lib/Drupal/comment/CommentViewBuilder.php +++ b/core/modules/comment/lib/Drupal/comment/CommentViewBuilder.php @@ -15,7 +15,6 @@ use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Entity\EntityViewBuilder; use Drupal\Core\Language\LanguageManagerInterface; -use Drupal\field\FieldInfo; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -24,13 +23,6 @@ class CommentViewBuilder extends EntityViewBuilder { /** - * The field info service. - * - * @var \Drupal\field\FieldInfo - */ - protected $fieldInfo; - - /** * The module handler service. * * @var \Drupal\Core\Extension\ModuleHandlerInterface @@ -52,7 +44,6 @@ public static function createInstance(ContainerInterface $container, EntityTypeI $entity_type, $container->get('entity.manager'), $container->get('language_manager'), - $container->get('field.info'), $container->get('csrf_token') ); } @@ -71,9 +62,8 @@ public static function createInstance(ContainerInterface $container, EntityTypeI * @param \Drupal\Core\Access\CsrfTokenGenerator $csrf_token * The CSRF token manager service. */ - public function __construct(EntityTypeInterface $entity_type, EntityManagerInterface $entity_manager, LanguageManagerInterface $language_manager, FieldInfo $field_info, CsrfTokenGenerator $csrf_token) { + public function __construct(EntityTypeInterface $entity_type, EntityManagerInterface $entity_manager, LanguageManagerInterface $language_manager, CsrfTokenGenerator $csrf_token) { parent::__construct($entity_type, $entity_manager, $language_manager); - $this->fieldInfo = $field_info; $this->csrfToken = $csrf_token; } @@ -273,9 +263,9 @@ protected function alterBuild(array &$build, EntityInterface $comment, EntityVie if (empty($comment->in_preview)) { $prefix = ''; $commented_entity = $comment->getCommentedEntity(); - $instance = $this->fieldInfo->getInstance($commented_entity->getEntityTypeId(), $commented_entity->bundle(), $comment->getFieldName()); + $field_definition = $this->entityManager->getFieldDefinitions($commented_entity->getEntityTypeId(), $commented_entity->bundle())[$comment->getFieldName()]; $is_threaded = isset($comment->divs) - && $instance->getSetting('default_mode') == COMMENT_MODE_THREADED; + && $field_definition->getSetting('default_mode') == COMMENT_MODE_THREADED; // Add indentation div or close open divs as needed. if ($is_threaded) { diff --git a/core/modules/comment/lib/Drupal/comment/Controller/AdminController.php b/core/modules/comment/lib/Drupal/comment/Controller/AdminController.php index b0c7cbe..12044ea 100644 --- a/core/modules/comment/lib/Drupal/comment/Controller/AdminController.php +++ b/core/modules/comment/lib/Drupal/comment/Controller/AdminController.php @@ -8,7 +8,7 @@ namespace Drupal\comment\Controller; use Drupal\comment\CommentManagerInterface; -use Drupal\field\FieldInfo; +use Drupal\field\FieldConfigInterface; use Drupal\Component\Utility\String; use Drupal\Core\Controller\ControllerBase; use Drupal\Core\Form\FormBuilderInterface; @@ -22,13 +22,6 @@ class AdminController extends ControllerBase { /** - * The field info service. - * - * @var \Drupal\field\FieldInfo - */ - protected $fieldInfo; - - /** * The comment manager service. * * @var \Drupal\comment\CommentManagerInterface @@ -47,7 +40,6 @@ class AdminController extends ControllerBase { */ public static function create(ContainerInterface $container) { return new static( - $container->get('field.info'), $container->get('comment.manager'), $container->get('form_builder') ); @@ -56,15 +48,12 @@ public static function create(ContainerInterface $container) { /** * Constructs an AdminController object. * - * @param \Drupal\field\FieldInfo $field_info - * The field info service. * @param \Drupal\comment\CommentManagerInterface $comment_manager * The comment manager service. * @param \Drupal\Core\Form\FormBuilderInterface $form_builder * The form builder. */ - public function __construct(FieldInfo $field_info, CommentManagerInterface $comment_manager, FormBuilderInterface $form_builder) { - $this->fieldInfo = $field_info; + public function __construct(CommentManagerInterface $comment_manager, FormBuilderInterface $form_builder) { $this->commentManager = $comment_manager; $this->formBuilder = $form_builder; } @@ -105,24 +94,29 @@ public function overviewBundles() { $fields = $this->commentManager->getAllFields(); foreach ($fields as $entity_type => $data) { + $storage_definitions = $this->entityManager()->getFieldStorageDefinitions($entity_type); foreach ($data as $field_name => $field_info_map) { - $field_info = $this->fieldInfo->getField($entity_type, $field_name); + $storage_definition = $storage_definitions[$field_name]; // Initialize the row. $row = array( - 'class' => $field_info->get('locked') ? array('field-disabled') : array(''), + 'class' => $storage_definition->get('locked') ? array('field-disabled') : array(''), ); - $bundles = $field_info->getBundles(); - $sample_bundle = reset($bundles); - $sample_instance = $this->fieldInfo->getInstance($entity_type, $sample_bundle, $field_name); + $label = $storage_definition->getLabel(); + if ($storage_definition instanceof FieldConfigInterface) { + $bundles = $storage_definition->getBundles(); + $sample_bundle = reset($bundles); + $field_definitions = $this->entityManager()->getFieldDefinitions($entity_type, $sample_bundle); + $label = $field_definitions[$field_name]->getLabel(); + } $tokens = array( - '@label' => $sample_instance->label, + '@label' => $label, '@field_name' => $field_name, ); - $row['data']['field_name']['data'] = $field_info->get('locked') ? $this->t('@label (@field_name) (Locked)', $tokens) : $this->t('@label (@field_name)', $tokens); + $row['data']['field_name']['data'] = $storage_definition->get('locked') ? $this->t('@label (@field_name) (Locked)', $tokens) : $this->t('@label (@field_name)', $tokens); - $row['data']['description']['data'] = $field_info->getSetting('description'); + $row['data']['description']['data'] = $storage_definition->getSetting('description'); $row['data']['usage']['data'] = array( '#theme' => 'item_list', '#items' => array(), @@ -200,7 +194,12 @@ public function bundleInfo($commented_entity_type, $field_name) { // Add a link to manage entity fields if the Field UI module is enabled. $field_ui_enabled = $this->moduleHandler()->moduleExists('field_ui'); - $field_info = $this->fieldInfo->getField($commented_entity_type, $field_name); + $storage_definition = $this->entityManager()->getFieldStorageDefinitions($commented_entity_type)[$field_name]; + + if (!($storage_definition instanceof FieldConfigInterface)) { + // @todo: Support base fields. + return array(); + } $entity_type_info = $this->entityManager()->getDefinition($commented_entity_type); $entity_bundle_info = $this->entityManager()->getBundleInfo($commented_entity_type); @@ -211,7 +210,7 @@ public function bundleInfo($commented_entity_type, $field_name) { '#items' => array(), ); // Loop over all of bundles to which this comment field is attached. - foreach ($field_info->getBundles() as $bundle) { + foreach ($storage_definition->getBundles() as $bundle) { // Add the current instance to the list of bundles. if ($field_ui_enabled && $route_info = FieldUI::getOverviewRouteInfo($commented_entity_type, $bundle)) { // Add a link to configure the fields on the given bundle and entity diff --git a/core/modules/comment/lib/Drupal/comment/Controller/CommentController.php b/core/modules/comment/lib/Drupal/comment/Controller/CommentController.php index 7829950..78eb686 100644 --- a/core/modules/comment/lib/Drupal/comment/Controller/CommentController.php +++ b/core/modules/comment/lib/Drupal/comment/Controller/CommentController.php @@ -10,7 +10,6 @@ use Drupal\comment\CommentInterface; use Drupal\comment\CommentManagerInterface; use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface; -use Drupal\field\FieldInfo; use Drupal\Core\Controller\ControllerBase; use Drupal\Core\Entity\EntityInterface; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -36,13 +35,6 @@ class CommentController extends ControllerBase { protected $httpKernel; /** - * Field info service. - * - * @var \Drupal\field\FieldInfo - */ - protected $fieldInfo; - - /** * The comment manager service. * * @var \Drupal\comment\CommentManagerInterface @@ -54,14 +46,11 @@ class CommentController extends ControllerBase { * * @param \Symfony\Component\HttpKernel\HttpKernelInterface $http_kernel * HTTP kernel to handle requests. - * @param \Drupal\field\FieldInfo $field_info - * Field Info service. * @param \Drupal\comment\CommentManagerInterface $comment_manager * The comment manager service. */ - public function __construct(HttpKernelInterface $http_kernel, FieldInfo $field_info, CommentManagerInterface $comment_manager) { + public function __construct(HttpKernelInterface $http_kernel, CommentManagerInterface $comment_manager) { $this->httpKernel = $http_kernel; - $this->fieldInfo = $field_info; $this->commentManager = $comment_manager; } @@ -71,7 +60,6 @@ public function __construct(HttpKernelInterface $http_kernel, FieldInfo $field_i public static function create(ContainerInterface $container) { return new static( $container->get('http_kernel'), - $container->get('field.info'), $container->get('comment.manager') ); } @@ -118,15 +106,15 @@ public function commentApprove(CommentInterface $comment) { * The comment listing set to the page on which the comment appears. */ public function commentPermalink(Request $request, CommentInterface $comment) { - if ($entity = $this->entityManager()->getStorage($comment->getCommentedEntityTypeId())->load($comment->getCommentedEntityId())) { + if ($entity = $comment->getCommentedEntity()) { // Check access permissions for the entity. if (!$entity->access('view')) { throw new AccessDeniedHttpException(); } - $instance = $this->fieldInfo->getInstance($entity->getEntityTypeId(), $entity->bundle(), $comment->getFieldName()); + $field_definition = $this->entityManager()->getFieldDefinitions($entity->getEntityTypeId(), $entity->bundle())[$comment->getFieldName()]; // Find the current display page for this comment. - $page = comment_get_display_page($comment->id(), $instance); + $page = comment_get_display_page($comment->id(), $field_definition); // @todo: Cleaner sub request handling. $redirect_request = Request::create($entity->getSystemPath(), 'GET', $request->query->all(), $request->cookies->all(), array(), $request->server->all()); $redirect_request->query->set('page', $page); diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentFieldsTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentFieldsTest.php index 24a20a9..86172a1 100644 --- a/core/modules/comment/lib/Drupal/comment/Tests/CommentFieldsTest.php +++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentFieldsTest.php @@ -7,7 +7,6 @@ namespace Drupal\comment\Tests; -use Drupal\field\Field; use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface; /** diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentLanguageTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentLanguageTest.php index 139bf73..260834f 100644 --- a/core/modules/comment/lib/Drupal/comment/Tests/CommentLanguageTest.php +++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentLanguageTest.php @@ -8,6 +8,7 @@ namespace Drupal\comment\Tests; use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface; +use Drupal\field\Entity\FieldConfig; use Drupal\simpletest\WebTestBase; /** @@ -74,7 +75,7 @@ function setUp() { $this->container->get('comment.manager')->addDefaultField('node', 'article'); // Make comment body translatable. - $field = field_info_field('comment', 'comment_body'); + $field = FieldConfig::loadByName('comment', 'comment_body'); $field->translatable = TRUE; $field->save(); $this->assertTrue($field->isTranslatable(), 'Comment body is translatable.'); diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentTranslationUITest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentTranslationUITest.php index 5e5b4de..119b06d 100644 --- a/core/modules/comment/lib/Drupal/comment/Tests/CommentTranslationUITest.php +++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentTranslationUITest.php @@ -9,6 +9,7 @@ use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface; use Drupal\content_translation\Tests\ContentTranslationUITest; +use Drupal\field\Entity\FieldConfig; /** * Tests the Comment Translation UI. @@ -77,7 +78,7 @@ protected function getTranslatorPermissions() { */ function setupTestFields() { parent::setupTestFields(); - $field = field_info_field('comment', 'comment_body'); + $field = FieldConfig::loadByName('comment', 'comment_body'); $field->translatable = TRUE; $field->save(); } diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentUninstallTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentUninstallTest.php index 6127552..5be58c8 100644 --- a/core/modules/comment/lib/Drupal/comment/Tests/CommentUninstallTest.php +++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentUninstallTest.php @@ -7,6 +7,7 @@ namespace Drupal\comment\Tests; +use Drupal\field\Entity\FieldConfig; use Drupal\simpletest\WebTestBase; /** @@ -43,14 +44,14 @@ protected function setUp() { */ function testCommentUninstallWithField() { // Ensure that the field exists before uninstallation. - $field = field_info_field('comment', 'comment_body'); + $field = FieldConfig::loadByName('comment', 'comment_body'); $this->assertNotNull($field, 'The comment_body field exists.'); // Uninstall the comment module which should trigger field deletion. $this->container->get('module_handler')->uninstall(array('comment')); // Check that the field is now deleted. - $field = field_info_field('comment', 'comment_body'); + $field = FieldConfig::loadByName('comment', 'comment_body'); $this->assertNull($field, 'The comment_body field has been deleted.'); } @@ -60,12 +61,12 @@ function testCommentUninstallWithField() { */ function testCommentUninstallWithoutField() { // Manually delete the comment_body field before module uninstallation. - $field = field_info_field('comment', 'comment_body'); + $field = FieldConfig::loadByName('comment', 'comment_body'); $this->assertNotNull($field, 'The comment_body field exists.'); $field->delete(); // Check that the field is now deleted. - $field = field_info_field('comment', 'comment_body'); + $field = FieldConfig::loadByName('comment', 'comment_body'); $this->assertNull($field, 'The comment_body field has been deleted.'); // Ensure that uninstallation succeeds even if the field has already been diff --git a/core/modules/config_translation/lib/Drupal/config_translation/Controller/ConfigTranslationFieldInstanceListBuilder.php b/core/modules/config_translation/lib/Drupal/config_translation/Controller/ConfigTranslationFieldInstanceListBuilder.php index e58947a..ff569d3 100644 --- a/core/modules/config_translation/lib/Drupal/config_translation/Controller/ConfigTranslationFieldInstanceListBuilder.php +++ b/core/modules/config_translation/lib/Drupal/config_translation/Controller/ConfigTranslationFieldInstanceListBuilder.php @@ -13,7 +13,6 @@ use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Entity\EntityTypeInterface; -use Drupal\field\Field; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -90,13 +89,12 @@ public function setMapperDefinition($mapper_definition) { * {@inheritdoc} */ public function load() { - $entities = array(); // It is not possible to use the standard load method, because this needs // all field instance entities only for the given baseEntityType. - foreach (Field::fieldInfo()->getInstances($this->baseEntityType) as $fields) { - $entities = array_merge($entities, array_values($fields)); - } - return $entities; + $ids = \Drupal::entityQuery('field_instance_config') + ->condition('entity_type', $this->baseEntityType) + ->execute(); + return $this->storage->loadMultiple($ids); } /** diff --git a/core/modules/content_translation/content_translation.admin.inc b/core/modules/content_translation/content_translation.admin.inc index 557f06e..eb03aea 100644 --- a/core/modules/content_translation/content_translation.admin.inc +++ b/core/modules/content_translation/content_translation.admin.inc @@ -9,7 +9,7 @@ use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Language\Language; use Drupal\Core\Render\Element; -use Drupal\field\Field as FieldService; +use Drupal\field\Entity\FieldConfig; use Drupal\field\FieldInstanceConfigInterface; /** @@ -348,7 +348,7 @@ function _content_translation_update_field_translatability($settings) { foreach ($bundle_settings['fields'] as $field_name => $translatable) { // If translatability changes for at least one field instance we need // to switch field translatability. - $field = FieldService::fieldInfo()->getField($entity_type, $field_name); + $field = FieldConfig::loadByName($entity_type, $field_name); if ($field && $field->isTranslatable() !== $translatable) { $fields[$field_name] = $translatable; } @@ -357,7 +357,7 @@ function _content_translation_update_field_translatability($settings) { } // Store updated fields. foreach ($fields as $field_name => $translatable) { - $field = FieldService::fieldInfo()->getField($entity_type, $field_name); + $field = FieldConfig::loadByName($entity_type, $field_name); $field->translatable = $translatable; $field->save(); } diff --git a/core/modules/content_translation/content_translation.module b/core/modules/content_translation/content_translation.module index 38b5b41..ae97a2f 100644 --- a/core/modules/content_translation/content_translation.module +++ b/core/modules/content_translation/content_translation.module @@ -14,6 +14,7 @@ use Drupal\Core\Language\Language; use Drupal\Core\Session\AccountInterface; use Drupal\Core\TypedData\TranslatableInterface; +use Drupal\field\Entity\FieldInstanceConfig; use Drupal\node\NodeInterface; /** @@ -865,7 +866,7 @@ function content_translation_save_settings($settings) { // Store whether fields have translation enabled or not. if (!empty($bundle_settings['columns'])) { foreach ($bundle_settings['columns'] as $field_name => $column_settings) { - $instance = field_info_instance($entity_type, $field_name, $bundle); + $instance = FieldInstanceConfig::loadByName($entity_type, $bundle, $field_name); if ($instance->isTranslatable()) { $instance->settings['translation_sync'] = $column_settings; } diff --git a/core/modules/content_translation/lib/Drupal/content_translation/Tests/ContentTranslationSettingsTest.php b/core/modules/content_translation/lib/Drupal/content_translation/Tests/ContentTranslationSettingsTest.php index a8e1a0c..059cb79 100644 --- a/core/modules/content_translation/lib/Drupal/content_translation/Tests/ContentTranslationSettingsTest.php +++ b/core/modules/content_translation/lib/Drupal/content_translation/Tests/ContentTranslationSettingsTest.php @@ -8,7 +8,7 @@ namespace Drupal\content_translation\Tests; use Drupal\Core\Language\Language; -use Drupal\field\Field as FieldService; +use Drupal\field\Entity\FieldConfig; use Drupal\simpletest\WebTestBase; /** @@ -95,7 +95,7 @@ function testSettingsUI() { ); $this->assertSettings('comment', 'node__comment_article', TRUE, $edit); field_info_cache_clear(); - $field = field_info_field('comment', 'comment_body'); + $field = FieldConfig::loadByName('comment', 'comment_body'); $this->assertTrue($field->isTranslatable(), 'Comment body is translatable.'); // Test that language settings are correctly stored. @@ -134,7 +134,7 @@ function testSettingsUI() { // Test that configurable field translatability is correctly switched. $edit = array('settings[node][article][fields][body]' => $translatable); $this->assertSettings('node', 'article', TRUE, $edit); - $field = FieldService::fieldInfo()->getField('node', 'body'); + $field = FieldConfig::loadByName('node', 'body'); $definitions = \Drupal::entityManager()->getFieldDefinitions('node', 'article'); $this->assertEqual($definitions['body']->isTranslatable(), $translatable, 'Field translatability correctly switched.'); $this->assertEqual($field->isTranslatable(), $definitions['body']->isTranslatable(), 'Configurable field translatability correctly switched.'); @@ -145,7 +145,7 @@ function testSettingsUI() { $this->drupalPostForm('admin/structure/types/manage/article/fields/node.article.body/field', $edit, t('Save field settings')); field_info_cache_clear(); entity_info_cache_clear(); - $field = FieldService::fieldInfo()->getField('node', 'body'); + $field = FieldConfig::loadByName('node', 'body'); $definitions = \Drupal::entityManager()->getFieldDefinitions('node', 'article'); $this->assertEqual($definitions['body']->isTranslatable(), $translatable, 'Field translatability correctly switched.'); $this->assertEqual($field->isTranslatable(), $definitions['body']->isTranslatable(), 'Configurable field translatability correctly switched.'); diff --git a/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php b/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php index dd1bfa0..43370fe 100644 --- a/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php +++ b/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php @@ -11,7 +11,7 @@ use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Entity\Display\EntityDisplayInterface; -use Drupal\field\Field; +use Drupal\field\Entity\FieldInstanceConfig; /** * Provides a common base class for entity view and form displays. @@ -164,7 +164,7 @@ public function calculateDependencies() { // Create dependencies on both hidden and visible fields. $fields = $this->content + $this->hidden; foreach ($fields as $field_name => $component) { - $field_instance = Field::fieldInfo()->getInstance($this->targetEntityType, $this->bundle, $field_name); + $field_instance = FieldInstanceConfig::loadByName($this->targetEntityType, $this->bundle, $field_name); if ($field_instance) { $this->addDependency('entity', $field_instance->getConfigDependencyName()); } diff --git a/core/modules/entity_reference/entity_reference.module b/core/modules/entity_reference/entity_reference.module index 846a723..5d59210 100644 --- a/core/modules/entity_reference/entity_reference.module +++ b/core/modules/entity_reference/entity_reference.module @@ -10,6 +10,8 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Render\Element; +use Drupal\field\Entity\FieldConfig; +use Drupal\field\Entity\FieldInstanceConfig; use Drupal\field\FieldConfigInterface; /** @@ -91,7 +93,7 @@ function entity_reference_field_config_update(FieldConfigInterface $field) { foreach ($field->bundles() as $entity_type => $bundles) { foreach ($bundles as $bundle) { - $instance = field_info_instance($entity_type, $field_name, $bundle); + $instance = FieldInstanceConfig::loadByName($entity_type, $bundle, $field_name); $instance->settings['handler_settings'] = array(); $instance->save(); } @@ -209,8 +211,8 @@ function entity_reference_create_instance($entity_type, $bundle, $field_name, $f } // Look for or add the specified field to the requested entity bundle. - $field = field_info_field($entity_type, $field_name); - $instance = field_info_instance($entity_type, $field_name, $bundle); + $field = FieldConfig::loadByName($entity_type, $field_name); + $instance = FieldInstanceConfig::loadByName($entity_type, $bundle, $field_name); if (empty($field)) { $field = array( diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceFieldTest.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceFieldTest.php index f035f37..bde0b2c 100644 --- a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceFieldTest.php +++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceFieldTest.php @@ -7,8 +7,9 @@ namespace Drupal\entity_reference\Tests; +use Drupal\field\Entity\FieldConfig; +use Drupal\field\Entity\FieldInstanceConfig; use Drupal\system\Tests\Entity\EntityUnitTestBase; -use Drupal\field\Field; /** * Tests for the entity reference field. @@ -88,9 +89,8 @@ public function setUp() { array('target_bundles' => array($this->bundle)) ); - $this->field = Field::fieldInfo()->getField($this->entityType, $this->fieldName); - $instances = Field::fieldInfo()->getBundleInstances($this->entityType, $this->bundle); - $this->instance = $instances[$this->fieldName]; + $this->field = FieldConfig::loadByName($this->entityType, $this->fieldName); + $this->instance = FieldInstanceConfig::loadByName($this->entityType, $this->bundle, $this->fieldName); } /** diff --git a/core/modules/field/field.module b/core/modules/field/field.module index 029db41..5473182 100644 --- a/core/modules/field/field.module +++ b/core/modules/field/field.module @@ -8,7 +8,6 @@ use Drupal\Component\Utility\Xss; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Extension\Extension; -use Drupal\field\Field; /* * Load all public Field API functions. Drupal currently has no @@ -200,9 +199,19 @@ function field_entity_field_storage_info(\Drupal\Core\Entity\EntityTypeInterface */ function field_entity_bundle_field_info(EntityTypeInterface $entity_type, $bundle, array $base_field_definitions) { if ($entity_type->isFieldable()) { - // Configurable fields, which are always attached to a specific bundle, are - // added 'by bundle'. - return Field::fieldInfo()->getBundleInstances($entity_type->id(), $bundle); + // Query by filtering on the ID as this is more efficient than filtering + // on the entity_type property directly. + $ids = \Drupal::entityQuery('field_instance_config') + ->condition('id', $entity_type->id() . '.' . $bundle . '.', 'STARTS_WITH') + ->execute(); + + // Fetch all fields and key them by field name. + $field_instance_configs = entity_load_multiple('field_instance_config', $ids); + $result = array(); + foreach ($field_instance_configs as $field_instance) { + $result[$field_instance->getName()] = $field_instance; + } + return $result; } } diff --git a/core/modules/field/lib/Drupal/field/Entity/FieldConfig.php b/core/modules/field/lib/Drupal/field/Entity/FieldConfig.php index 5ec5f0c..3f1f4df 100644 --- a/core/modules/field/lib/Drupal/field/Entity/FieldConfig.php +++ b/core/modules/field/lib/Drupal/field/Entity/FieldConfig.php @@ -798,4 +798,20 @@ protected function getFieldItemClass() { return $type_definition['class']; } + /** + * Loads a field config entity based on the entity type and field name. + * + * @param string $entity_type_id + * ID of the entity type. + * @param string $field_name + * Name of the field. + * + * @return static|null + * The field config entity if one exists for the provided field name, + * otherwise NULL. + */ + public static function loadByName($entity_type_id, $field_name) { + return \Drupal::entityManager()->getStorage('field_config')->load($entity_type_id . '.' . $field_name); + } + } diff --git a/core/modules/field/lib/Drupal/field/Entity/FieldInstanceConfig.php b/core/modules/field/lib/Drupal/field/Entity/FieldInstanceConfig.php index ff6217d..1a418f2 100644 --- a/core/modules/field/lib/Drupal/field/Entity/FieldInstanceConfig.php +++ b/core/modules/field/lib/Drupal/field/Entity/FieldInstanceConfig.php @@ -12,7 +12,6 @@ use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Field\FieldDefinition; use Drupal\Core\Field\TypedData\FieldItemDataDefinition; -use Drupal\field\Field; use Drupal\field\FieldException; use Drupal\field\FieldInstanceConfigInterface; @@ -232,24 +231,20 @@ class FieldInstanceConfig extends ConfigEntityBase implements FieldInstanceConfi * @ingroup field_crud */ public function __construct(array $values, $entity_type = 'field_instance_config') { - // Field instances configuration is stored with a 'field_uuid' property - // unambiguously identifying the field. We only take it into account if a - // 'uuid' entry is present too, so that leftover 'field_uuid' entries - // present in config files imported as "default module config" are ignored. - if (isset($values['field_uuid']) && isset($values['uuid'])) { - $field = Field::fieldInfo()->getFieldById($values['field_uuid']); + // Load the corresponding field. + if (isset($values['field_name']) && isset($values['entity_type'])) { + $field = FieldConfig::loadByName($values['entity_type'], $values['field_name']); if (!$field) { - throw new FieldException(format_string('Attempt to create an instance of unknown field @uuid', array('@uuid' => $values['field_uuid']))); - } - $values['field_name'] = $field->getName(); - } - // Alternatively, accept incoming 'field_name' instead of 'field_uuid', for - // easier DX on creation of new instances (either through programmatic - // creation / or through import of default config files). - elseif (isset($values['field_name']) && isset($values['entity_type'])) { - $field = Field::fieldInfo()->getField($values['entity_type'], $values['field_name']); - if (!$field) { - throw new FieldException(format_string('Attempt to create an instance of field @field_name that does not exist on entity type @entity_type.', array('@field_name' => $values['field_name'], '@entity_type' => $values['entity_type']))); + // The field might have been deleted, try to load it based on the UUID + // when present. + if (isset($values['field_uuid']) && isset($values['uuid'])) { + if ($fields = entity_load_multiple_by_properties('field_config', array('uuid' => $values['field_uuid'], 'include_deleted' => TRUE))) { + $field = current($fields); + } + } + if (!$field) { + throw new FieldException(format_string('Attempt to create an instance of field @field_name that does not exist on entity type @entity_type.', array('@field_name' => $values['field_name'], '@entity_type' => $values['entity_type']))); + } } $values['field_uuid'] = $field->uuid(); } @@ -808,4 +803,22 @@ public function isDeleted() { return $this->deleted; } + /** + * Loads a field config entity based on the entity type and field name. + * + * @param string $entity_type_id + * ID of the entity type. + * @param string $bundle + * Bundle name. + * @param string $field_name + * Name of the field. + * + * @return static|null + * The field instance config entity if one exists for the provided field + * name, otherwise NULL. + */ + public static function loadByName($entity_type_id, $bundle, $field_name) { + return \Drupal::entityManager()->getStorage('field_instance_config')->load($entity_type_id . '.' . $bundle . '.' . $field_name); + } + } diff --git a/core/modules/field/lib/Drupal/field/Plugin/views/argument/FieldList.php b/core/modules/field/lib/Drupal/field/Plugin/views/argument/FieldList.php index 2f0cadb..c948bcb 100644 --- a/core/modules/field/lib/Drupal/field/Plugin/views/argument/FieldList.php +++ b/core/modules/field/lib/Drupal/field/Plugin/views/argument/FieldList.php @@ -34,7 +34,7 @@ class FieldList extends Numeric { public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) { parent::init($view, $display, $options); - $field = field_info_field($this->definition['entity_type'], $this->definition['field_name']); + $field = \Drupal::entityManager()->getFieldStorageDefinitions($this->definition['entity_type'])[$this->definition['field_name']]; $this->allowed_values = options_allowed_values($field); } diff --git a/core/modules/field/lib/Drupal/field/Plugin/views/argument/ListString.php b/core/modules/field/lib/Drupal/field/Plugin/views/argument/ListString.php index a257cad..14f7a8f 100644 --- a/core/modules/field/lib/Drupal/field/Plugin/views/argument/ListString.php +++ b/core/modules/field/lib/Drupal/field/Plugin/views/argument/ListString.php @@ -34,7 +34,7 @@ class ListString extends String { public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) { parent::init($view, $display, $options); - $field = field_info_field($this->definition['entity_type'], $this->definition['field_name']); + $field = \Drupal::entityManager()->getFieldStorageDefinitions($this->definition['entity_type'])[$this->definition['field_name']]; $this->allowed_values = options_allowed_values($field); } diff --git a/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php b/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php index 30b0398..3a5c3a8 100644 --- a/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php +++ b/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php @@ -13,7 +13,6 @@ use Drupal\Core\Field\FieldDefinition; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Render\Element; -use Drupal\field\Field as FieldHelper; use Drupal\Core\Entity\ContentEntityDatabaseStorage; use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Field\FormatterPluginManager; @@ -166,7 +165,7 @@ protected function getFieldDefinition() { */ protected function getFieldConfig() { if (!$this->fieldConfig) { - $this->fieldConfig = FieldHelper::fieldInfo()->getField($this->definition['entity_type'], $this->definition['field_name']); + $this->fieldConfig = \Drupal::entityManager()->getFieldStorageDefinitions($this->definition['entity_type'])[$this->definition['field_name']]; } return $this->fieldConfig; } @@ -347,7 +346,7 @@ public function clickSort($order) { } $this->ensureMyTable(); - $field = field_info_field($this->definition['entity_type'], $this->definition['field_name']); + $field = $this->entityManager->getFieldStorageDefinitions($this->definition['entity_type'])[$this->definition['field_name']]; $column = ContentEntityDatabaseStorage::_fieldColumnName($field, $this->options['click_sort_column']); if (!isset($this->aliases[$column])) { // Column is not in query; add a sort on it (without adding the column). @@ -360,7 +359,7 @@ protected function defineOptions() { $options = parent::defineOptions(); // defineOptions runs before init/construct, so no $this->field_info - $field = field_info_field($this->definition['entity_type'], $this->definition['field_name']); + $field = $this->entityManager->getFieldStorageDefinitions($this->definition['entity_type'])[$this->definition['field_name']]; $field_type = \Drupal::service('plugin.manager.field.field_type')->getDefinition($field->getType()); $column_names = array_keys($field->getColumns()); $default_column = ''; diff --git a/core/modules/field/lib/Drupal/field/Plugin/views/filter/FieldList.php b/core/modules/field/lib/Drupal/field/Plugin/views/filter/FieldList.php index 6b0b153..d1d007f 100644 --- a/core/modules/field/lib/Drupal/field/Plugin/views/filter/FieldList.php +++ b/core/modules/field/lib/Drupal/field/Plugin/views/filter/FieldList.php @@ -19,7 +19,7 @@ class FieldList extends ManyToOne { public function getValueOptions() { - $field = field_info_field($this->definition['entity_type'], $this->definition['field_name']); + $field = \Drupal::entityManager()->getFieldStorageDefinitions($this->definition['entity_type'])[$this->definition['field_name']]; $this->value_options = list_allowed_values($field); } diff --git a/core/modules/field/lib/Drupal/field/Plugin/views/relationship/EntityReverse.php b/core/modules/field/lib/Drupal/field/Plugin/views/relationship/EntityReverse.php index 46db003..383ab40 100644 --- a/core/modules/field/lib/Drupal/field/Plugin/views/relationship/EntityReverse.php +++ b/core/modules/field/lib/Drupal/field/Plugin/views/relationship/EntityReverse.php @@ -52,7 +52,7 @@ public static function create(ContainerInterface $container, array $configuratio public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) { parent::init($view, $display, $options); - $this->field_info = field_info_field($this->definition['entity_type'], $this->definition['field_name']); + $this->field_info = \Drupal::entityManager()->getFieldStorageDefinitions($this->definition['entity_type'])[$this->definition['field_name']]; } /** diff --git a/core/modules/field/lib/Drupal/field/Tests/BulkDeleteTest.php b/core/modules/field/lib/Drupal/field/Tests/BulkDeleteTest.php index 2b74370..542139e 100644 --- a/core/modules/field/lib/Drupal/field/Tests/BulkDeleteTest.php +++ b/core/modules/field/lib/Drupal/field/Tests/BulkDeleteTest.php @@ -9,6 +9,7 @@ use Drupal\Core\Entity\ContentEntityDatabaseStorage; use Drupal\Core\Entity\EntityInterface; +use Drupal\field\Entity\FieldInstanceConfig; use Drupal\field\FieldConfigInterface; @@ -176,7 +177,7 @@ function testDeleteFieldInstance() { $this->assertEqual(count($found), 10, 'Correct number of entities found before deleting'); // Delete the instance. - $instance = field_info_instance($this->entity_type, $field->name, $bundle); + $instance = FieldInstanceConfig::loadByName($this->entity_type, $bundle, $field->name); $instance->delete(); // The instance still exists, deleted. @@ -226,7 +227,7 @@ function testPurgeInstance() { $field = reset($this->fields); // Delete the instance. - $instance = field_info_instance($this->entity_type, $field->name, $bundle); + $instance = FieldInstanceConfig::loadByName($this->entity_type, $bundle, $field->name); $instance->delete(); // No field hooks were called. @@ -285,7 +286,7 @@ function testPurgeField() { // Delete the first instance. $bundle = reset($this->bundles); - $instance = field_info_instance($this->entity_type, $field->name, $bundle); + $instance = FieldInstanceConfig::loadByName($this->entity_type, $bundle, $field->name); $instance->delete(); // Assert that FieldItemInterface::delete() was not called yet. @@ -315,7 +316,7 @@ function testPurgeField() { // Delete the second instance. $bundle = next($this->bundles); - $instance = field_info_instance($this->entity_type, $field->name, $bundle); + $instance = FieldInstanceConfig::loadByName($this->entity_type, $bundle, $field->name); $instance->delete(); // Assert that FieldItemInterface::delete() was not called yet. diff --git a/core/modules/field/lib/Drupal/field/Tests/CrudTest.php b/core/modules/field/lib/Drupal/field/Tests/CrudTest.php index 36a2770..4644b2c 100644 --- a/core/modules/field/lib/Drupal/field/Tests/CrudTest.php +++ b/core/modules/field/lib/Drupal/field/Tests/CrudTest.php @@ -8,6 +8,7 @@ namespace Drupal\field\Tests; use Drupal\Core\Entity\EntityStorageException; +use Drupal\field\Entity\FieldConfig; use Drupal\field\FieldException; class CrudTest extends FieldUnitTestBase { @@ -312,7 +313,7 @@ function testDeleteField() { // Test that the first field is not deleted, and then delete it. $field = current(entity_load_multiple_by_properties('field_config', array('field_name' => $this->field['name'], 'include_deleted' => TRUE))); $this->assertTrue(!empty($field) && empty($field->deleted), 'A new field is not marked for deletion.'); - field_info_field('entity_test', $this->field['name'])->delete(); + FieldConfig::loadByName('entity_test', $this->field['name'])->delete(); // Make sure that the field is marked as deleted when it is specifically // loaded. diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldAttachStorageTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldAttachStorageTest.php index a80df81..0bf7732 100644 --- a/core/modules/field/lib/Drupal/field/Tests/FieldAttachStorageTest.php +++ b/core/modules/field/lib/Drupal/field/Tests/FieldAttachStorageTest.php @@ -6,6 +6,7 @@ */ namespace Drupal\field\Tests; +use Drupal\field\Entity\FieldInstanceConfig; /** * Unit test class for storage-related field behavior. @@ -337,7 +338,7 @@ function testEntityCreateRenameBundle() { entity_test_rename_bundle($this->instance_definition['bundle'], $new_bundle, $entity_type); // Check that the instance definition has been updated. - $this->instance = field_info_instance($entity_type, $this->field_name, $new_bundle); + $this->instance = FieldInstanceConfig::loadByName($entity_type, $new_bundle, $this->field_name); $this->assertIdentical($this->instance->bundle, $new_bundle, "Bundle name has been updated in the instance."); // Verify the field data is present on load. diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldImportCreateTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldImportCreateTest.php index f248fdc..7a1c4fb 100644 --- a/core/modules/field/lib/Drupal/field/Tests/FieldImportCreateTest.php +++ b/core/modules/field/lib/Drupal/field/Tests/FieldImportCreateTest.php @@ -7,8 +7,6 @@ namespace Drupal\field\Tests; -use Drupal\field\Field; - /** * Tests creating fields and instances as part of config import. */ @@ -60,13 +58,20 @@ function testImportCreateDefault() { $this->assertTrue($instance->bundle, 'test_bundle', 'The second field instance was created on bundle test_bundle.'); $this->assertTrue($instance->bundle, 'test_bundle_2', 'The second field instance was created on bundle test_bundle_2.'); - // Tests field info contains the right data. - $instances = Field::fieldInfo()->getInstances('entity_test'); - $this->assertEqual(count($instances['entity_test']), 2); - $this->assertTrue(isset($instances['entity_test']['field_test_import'])); - $this->assertTrue(isset($instances['entity_test']['field_test_import_2'])); - $this->assertEqual(count($instances['test_bundle']), 1); - $this->assertTrue(isset($instances['test_bundle']['field_test_import_2'])); + // Tests field instances. + $ids = \Drupal::entityQuery('field_instance_config') + ->condition('entity_type', 'entity_test') + ->condition('bundle', 'entity_test') + ->execute(); + $this->assertEqual(count($ids), 2); + $this->assertTrue(isset($ids['entity_test.entity_test.field_test_import'])); + $this->assertTrue(isset($ids['entity_test.entity_test.field_test_import_2'])); + $ids = \Drupal::entityQuery('field_instance_config') + ->condition('entity_type', 'entity_test') + ->condition('bundle', 'test_bundle') + ->execute(); + $this->assertEqual(count($ids), 1); + $this->assertTrue(isset($ids['entity_test.test_bundle.field_test_import_2'])); } /** diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldInstanceCrudTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldInstanceCrudTest.php index f8a02ab..515301e 100644 --- a/core/modules/field/lib/Drupal/field/Tests/FieldInstanceCrudTest.php +++ b/core/modules/field/lib/Drupal/field/Tests/FieldInstanceCrudTest.php @@ -8,6 +8,8 @@ namespace Drupal\field\Tests; use Drupal\Core\Entity\EntityStorageException; +use Drupal\field\Entity\FieldConfig; +use Drupal\field\Entity\FieldInstanceConfig; use Drupal\field\FieldException; class FieldInstanceCrudTest extends FieldUnitTestBase { @@ -188,8 +190,8 @@ function testDeleteFieldInstanceCrossDeletion() { entity_create('field_instance_config', $this->instance_definition)->save(); entity_create('field_instance_config', $instance_definition_2)->save(); $field->delete(); - $this->assertFalse(field_info_instance('entity_test', $this->instance_definition['bundle'], $field->name)); - $this->assertFalse(field_info_instance('entity_test', $instance_definition_2['bundle'], $field->name)); + $this->assertFalse(FieldInstanceConfig::loadByName('entity_test', $this->instance_definition['bundle'], $field->name)); + $this->assertFalse(FieldInstanceConfig::loadByName('entity_test', $instance_definition_2['bundle'], $field->name)); // Chack that deletion of the last instance deletes the field. $field = entity_create('field_config', $this->field_definition); @@ -199,9 +201,9 @@ function testDeleteFieldInstanceCrossDeletion() { $instance_2 = entity_create('field_instance_config', $instance_definition_2); $instance_2->save(); $instance->delete(); - $this->assertTrue(field_info_field('entity_test', $field->name)); + $this->assertTrue(FieldConfig::loadByName('entity_test', $field->name)); $instance_2->delete(); - $this->assertFalse(field_info_field('entity_test', $field->name)); + $this->assertFalse(FieldConfig::loadByName('entity_test', $field->name)); // Check that deletion of all instances of the same field simultaneously // deletes the field. @@ -213,7 +215,7 @@ function testDeleteFieldInstanceCrossDeletion() { $instance_2->save(); $instance_storage = $this->container->get('entity.manager')->getStorage('field_instance_config'); $instance_storage->delete(array($instance, $instance_2)); - $this->assertFalse(field_info_field('entity_test', $field->name)); + $this->assertFalse(FieldConfig::loadByName('entity_test', $field->name)); } } diff --git a/core/modules/field/tests/Drupal/field/Tests/FieldInstanceConfigEntityUnitTest.php b/core/modules/field/tests/Drupal/field/Tests/FieldInstanceConfigEntityUnitTest.php index d8a43d4..7ab37dc 100644 --- a/core/modules/field/tests/Drupal/field/Tests/FieldInstanceConfigEntityUnitTest.php +++ b/core/modules/field/tests/Drupal/field/Tests/FieldInstanceConfigEntityUnitTest.php @@ -48,13 +48,6 @@ class FieldInstanceConfigEntityUnitTest extends UnitTestCase { protected $uuid; /** - * The field info provider. - * - * @var \Drupal\field\FieldInfo|\PHPUnit_Framework_MockObject_MockObject - */ - protected $fieldInfo; - - /** * {@inheritdoc} */ public static function getInfo() { @@ -75,14 +68,9 @@ public function setUp() { $this->uuid = $this->getMock('\Drupal\Component\Uuid\UuidInterface'); - $this->fieldInfo = $this->getMockBuilder('\Drupal\field\FieldInfo') - ->disableOriginalConstructor() - ->getMock(); - $container = new ContainerBuilder(); $container->set('entity.manager', $this->entityManager); $container->set('uuid', $this->uuid); - $container->set('field.info', $this->fieldInfo); \Drupal::setContainer($container); } @@ -98,9 +86,12 @@ public function testCalculateDependencies() { $field->expects($this->once()) ->method('getConfigDependencyName') ->will($this->returnValue('field.field.test_entity_type.test_field')); - $this->fieldInfo->expects($this->any()) - ->method('getField') - ->with('test_entity_type', 'test_field') + + $field_storage = $this->getMock('\Drupal\Core\Config\Entity\ConfigEntityStorageInterface'); + $field_storage + ->expects($this->any()) + ->method('load') + ->with('test_entity_type.test_field') ->will($this->returnValue($field)); // Mock the interfaces necessary to create a dependency on a bundle entity. @@ -118,8 +109,10 @@ public function testCalculateDependencies() { $this->entityManager->expects($this->any()) ->method('getStorage') - ->with('bundle_entity_type') - ->will($this->returnValue($storage)); + ->will($this->returnValueMap(array( + array('field_config', $field_storage), + array('bundle_entity_type', $storage), + ))); $target_entity_type = $this->getMock('\Drupal\Core\Entity\EntityTypeInterface'); $target_entity_type->expects($this->any()) diff --git a/core/modules/field_ui/lib/Drupal/field_ui/FieldOverview.php b/core/modules/field_ui/lib/Drupal/field_ui/FieldOverview.php index eee9f27..dc37731 100644 --- a/core/modules/field_ui/lib/Drupal/field_ui/FieldOverview.php +++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldOverview.php @@ -424,7 +424,7 @@ public function submitForm(array &$form, array &$form_state) { if (!empty($form_values['_add_existing_field']['field_name'])) { $values = $form_values['_add_existing_field']; $field_name = $values['field_name']; - $field = field_info_field($this->entity_type, $field_name); + $field = FieldConfig::loadByName($this->entity_type, $field_name); if (!empty($field->locked)) { drupal_set_message($this->t('The field %label cannot be added because it is locked.', array('%label' => $values['label'])), 'error'); } @@ -531,16 +531,17 @@ protected function getExistingFieldOptions() { * Checks if a field machine name is taken. * * @param string $value - * The machine name, not prefixed with 'field_'. + * The machine name, not prefixed. * * @return bool * Whether or not the field machine name is taken. */ public function fieldNameExists($value) { - // Prefix with 'field_'. - $field_name = 'field_' . $value; + // Add the field prefix. + $field_name = \Drupal::config('field_ui.settings')->get('field_prefix') . $value; - return (bool) field_info_field($this->entity_type, $field_name); + $fields = \Drupal::entityManager()->getFieldStorageDefinitions($this->entity_type); + return isset($fields[$field_name]); } } diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldEditForm.php b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldEditForm.php index 3739368..b526c02 100644 --- a/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldEditForm.php +++ b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldEditForm.php @@ -10,7 +10,6 @@ use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Form\FormBase; use Drupal\Core\TypedData\TypedDataManager; -use Drupal\field\FieldInfo; use Drupal\field\FieldInstanceConfigInterface; use Drupal\field_ui\FieldUI; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -35,13 +34,6 @@ class FieldEditForm extends FormBase { protected $entityManager; /** - * The field info service. - * - * @var \Drupal\field\FieldInfo - */ - protected $fieldInfo; - - /** * The typed data manager. * * @var \Drupal\Core\TypedData\TypedDataManager @@ -60,14 +52,11 @@ public function getFormId() { * * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager * The entity manager. - * @param \Drupal\field\FieldInfo $field_info - * The field info service. * @param \Drupal\Core\TypedData\TypedDataManager $typed_data_manager * The typed data manager. */ - public function __construct(EntityManagerInterface $entity_manager, FieldInfo $field_info, TypedDataManager $typed_data_manager) { + public function __construct(EntityManagerInterface $entity_manager, TypedDataManager $typed_data_manager) { $this->entityManager = $entity_manager; - $this->fieldInfo = $field_info; $this->typedDataManager = $typed_data_manager; } @@ -77,7 +66,6 @@ public function __construct(EntityManagerInterface $entity_manager, FieldInfo $f public static function create(ContainerInterface $container) { return new static( $container->get('entity.manager'), - $container->get('field.info'), $container->get('typed_data_manager') ); } diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php index 1b8c16d..e5850a7 100644 --- a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php +++ b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php @@ -311,10 +311,11 @@ function testSingleViewMode() { */ function testNoFieldsDisplayOverview() { // Create a fresh content type without any fields. - $this->drupalCreateContentType(array('type' => 'no_fields', 'name' => 'No fields')); - - // Remove the 'body' field. - field_info_instance('node', 'body', 'no_fields')->delete(); + $this->drupalCreateContentType(array( + 'type' => 'no_fields', + 'name' => 'No fields', + 'create_body' => FALSE, + )); $this->drupalGet('admin/structure/types/manage/no_fields/display'); $this->assertRaw(t('There are no fields yet added. You can add new fields on the Manage fields page.', array('@link' => url('admin/structure/types/manage/no_fields/fields')))); diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php index 8fd993f..212df05 100644 --- a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php +++ b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php @@ -10,6 +10,8 @@ use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Language\Language; use Drupal\Component\Utility\String; +use Drupal\field\Entity\FieldConfig; +use Drupal\field\Entity\FieldInstanceConfig; /** * Tests the functionality of the 'Manage fields' screen. @@ -246,11 +248,11 @@ function assertFieldSettings($bundle, $field_name, $string = 'dummy test string' // Reset the fields info. field_info_cache_clear(); // Assert field settings. - $field = field_info_field($entity_type, $field_name); + $field = FieldConfig::loadByName($entity_type, $field_name); $this->assertTrue($field->getSetting('test_field_setting') == $string, 'Field settings were found.'); // Assert instance settings. - $instance = field_info_instance($entity_type, $field_name, $bundle); + $instance = FieldInstanceConfig::loadByName($entity_type, $bundle, $field_name); $this->assertTrue($instance->getSetting('test_instance_setting') == $string, 'Field instance settings were found.'); } @@ -322,7 +324,7 @@ function testDefaultValue() { $this->drupalPostForm($admin_path, $edit, t('Save settings')); $this->assertText("Saved $field_name configuration", 'The form was successfully submitted.'); field_info_cache_clear(); - $instance = field_info_instance('node', $field_name, $this->type); + $instance = FieldInstanceConfig::loadByName('node', $this->type, $field_name); $this->assertEqual($instance->default_value, array(array('value' => 1)), 'The default value was correctly saved.'); // Check that the default value shows up in the form @@ -334,7 +336,7 @@ function testDefaultValue() { $this->drupalPostForm(NULL, $edit, t('Save settings')); $this->assertText("Saved $field_name configuration", 'The form was successfully submitted.'); field_info_cache_clear(); - $instance = field_info_instance('node', $field_name, $this->type); + $instance = FieldInstanceConfig::loadByName('node', $this->type, $field_name); $this->assertEqual($instance->default_value, NULL, 'The default value was correctly saved.'); // Check that the default widget is used when the field is hidden. @@ -375,9 +377,9 @@ function testDeleteField() { // Reset the fields info. field_info_cache_clear(); // Check that the field instance was deleted. - $this->assertNull(field_info_instance('node', $this->field_name, $this->type), 'Field instance was deleted.'); + $this->assertNull(FieldInstanceConfig::loadByName('node', $this->type, $this->field_name), 'Field instance was deleted.'); // Check that the field was not deleted - $this->assertNotNull(field_info_field('node', $this->field_name), 'Field was not deleted.'); + $this->assertNotNull(FieldConfig::loadByName('node', $this->field_name), 'Field was not deleted.'); // Delete the second instance. $this->fieldUIDeleteField($bundle_path2, "node.$type_name2.$this->field_name", $this->field_label, $type_name2); @@ -385,9 +387,9 @@ function testDeleteField() { // Reset the fields info. field_info_cache_clear(); // Check that the field instance was deleted. - $this->assertNull(field_info_instance('node', $this->field_name, $type_name2), 'Field instance was deleted.'); + $this->assertNull(FieldInstanceConfig::loadByName('node', $type_name2, $this->field_name), 'Field instance was deleted.'); // Check that the field was deleted too. - $this->assertNull(field_info_field('node', $this->field_name), 'Field was deleted.'); + $this->assertNull(FieldConfig::loadByName('node', $this->field_name), 'Field was deleted.'); } /** @@ -407,13 +409,13 @@ function testDisallowedFieldNames() { $edit['fields[_add_new_field][field_name]'] = 'title'; $bundle_path = 'admin/structure/types/manage/' . $this->type; $this->drupalPostForm("$bundle_path/fields", $edit, t('Save')); - $this->assertText(t('There was a problem creating field Disallowed field: Attempt to create field title which is reserved by entity type node.', array('%label' => $label)), 'Field was not saved.'); + $this->assertText(t('The machine-readable name is already in use. It must be unique.')); // Try with a base field. $edit['fields[_add_new_field][field_name]'] = 'sticky'; $bundle_path = 'admin/structure/types/manage/' . $this->type; $this->drupalPostForm("$bundle_path/fields", $edit, t('Save')); - $this->assertText(t('There was a problem creating field Disallowed field: Attempt to create field sticky which is reserved by entity type node.', array('%label' => $label)), 'Field was not saved.'); + $this->assertText(t('The machine-readable name is already in use. It must be unique.')); } /** @@ -554,9 +556,9 @@ function testDeleteTaxonomyField() { // Reset the fields info. field_info_cache_clear(); // Check that the field instance was deleted. - $this->assertNull(field_info_instance('taxonomy_term', $this->field_name, 'tags'), 'Field instance was deleted.'); + $this->assertNull(FieldInstanceConfig::loadByName('taxonomy_term', 'tags', $this->field_name), 'Field instance was deleted.'); // Check that the field was deleted too. - $this->assertNull(field_info_field('taxonomy_term', $this->field_name), 'Field was deleted.'); + $this->assertNull(FieldConfig::loadByName('taxonomy_term', $this->field_name), 'Field was deleted.'); } /** diff --git a/core/modules/file/file.module b/core/modules/file/file.module index 9fb3c60..5218ca3 100644 --- a/core/modules/file/file.module +++ b/core/modules/file/file.module @@ -5,7 +5,10 @@ * Defines a "managed_file" Form API field and a "file" field for Field module. */ +use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Render\Element; +use Drupal\field\Entity\FieldConfig; +use Drupal\field\FieldConfigInterface; use Drupal\file\Entity\File; use Drupal\Component\Utility\NestedArray; use Drupal\Component\Utility\Unicode; @@ -647,8 +650,9 @@ function file_file_download($uri, $field_type = 'file') { // reference denied access, access is denied. foreach ($references as $field_name => $field_references) { foreach ($field_references as $entity_type => $entities) { + $fields = \Drupal::entityManager()->getFieldStorageDefinitions($entity_type); foreach ($entities as $entity) { - $field = field_info_field($entity_type, $field_name); + $field = $fields[$field_name]; // Check if access to this field is not disallowed. if (!$entity->get($field_name)->access('view')) { $denied = TRUE; @@ -1857,8 +1861,8 @@ function file_icon_map(File $file) { * * @param \Drupal\file\File $file * A file entity. - * @param $field - * (optional) A field array to be used for this check. If given, limits the + * @param \Drupal\Core\Field\FieldDefinitionInterface $field + * (optional) A field definition to be used for this check. If given, limits the * reference check to the given field. * @param $age * (optional) A constant that specifies which references to count. Use @@ -1876,7 +1880,7 @@ function file_icon_map(File $file) { * A multidimensional array. The keys are field_name, entity_type, * entity_id and the value is an entity referencing this file. */ -function file_get_file_references(File $file, $field = NULL, $age = EntityStorageInterface::FIELD_LOAD_REVISION, $field_type = 'file') { +function file_get_file_references(File $file, FieldDefinitionInterface $field = NULL, $age = EntityStorageInterface::FIELD_LOAD_REVISION, $field_type = 'file') { $references = &drupal_static(__FUNCTION__, array()); $field_columns = &drupal_static(__FUNCTION__ . ':field_columns', array()); @@ -1938,7 +1942,7 @@ function file_get_file_references(File $file, $field = NULL, $age = EntityStorag if ($field || $field_type) { foreach ($return as $field_name => $data) { foreach (array_keys($data) as $entity_type_id) { - $current_field = field_info_field($entity_type_id, $field_name); + $current_field = \Drupal::entityManager()->getFieldStorageDefinitions($entity_type_id)[$field_name]; if (($field_type && $current_field->getType() != $field_type) || ($field && $field->uuid() != $current_field->uuid())) { unset($return[$field_name][$entity_type_id]); } diff --git a/core/modules/file/lib/Drupal/file/Plugin/Field/FieldWidget/FileWidget.php b/core/modules/file/lib/Drupal/file/Plugin/Field/FieldWidget/FileWidget.php index 6426304..6be495c 100644 --- a/core/modules/file/lib/Drupal/file/Plugin/Field/FieldWidget/FileWidget.php +++ b/core/modules/file/lib/Drupal/file/Plugin/Field/FieldWidget/FileWidget.php @@ -12,7 +12,6 @@ use Drupal\Core\Field\FieldItemListInterface; use Drupal\Component\Utility\NestedArray; use Drupal\Core\Render\Element; -use Drupal\field\Field; /** * Plugin implementation of the 'file_generic' widget. @@ -311,18 +310,18 @@ public static function validateMultipleCount($element, &$form_state, $form) { array_pop($parents); $current = count(Element::children(NestedArray::getValue($form, $parents))) - 1; - $field = Field::fieldInfo()->getField($element['#entity_type'], $element['#field_name']); + $field = \Drupal::entityManager()->getFieldStorageDefinitions($element['#entity_type'])[$element['#field_name']]; $uploaded = count($values['fids']); $count = $uploaded + $current; - if ($count > $field->cardinality) { - $keep = $uploaded - $count + $field->cardinality; + if ($count > $field->getCardinality()) { + $keep = $uploaded - $count + $field->getCardinality(); $removed_files = array_slice($values['fids'], $keep); $removed_names = array(); foreach ($removed_files as $fid) { $file = file_load($fid); $removed_names[] = $file->getFilename(); } - $args = array('%field' => $field->getFieldName(), '@max' => $field->cardinality, '@count' => $keep, '%list' => implode(', ', $removed_names)); + $args = array('%field' => $field->getFieldName(), '@max' => $field->getCardinality(), '@count' => $keep, '%list' => implode(', ', $removed_names)); $message = t('Field %field can only hold @max values but there were @count uploaded. The following files have been omitted as a result: %list.', $args); drupal_set_message($message, 'warning'); $values['fids'] = array_slice($values['fids'], 0, $keep); diff --git a/core/modules/file/lib/Drupal/file/Tests/FileFieldTestBase.php b/core/modules/file/lib/Drupal/file/Tests/FileFieldTestBase.php index a7df01d..644f6f9 100644 --- a/core/modules/file/lib/Drupal/file/Tests/FileFieldTestBase.php +++ b/core/modules/file/lib/Drupal/file/Tests/FileFieldTestBase.php @@ -7,6 +7,8 @@ namespace Drupal\file\Tests; +use Drupal\field\Entity\FieldConfig; +use Drupal\field\Entity\FieldInstanceConfig; use Drupal\file\FileInterface; use Drupal\simpletest\WebTestBase; @@ -123,7 +125,7 @@ function attachFileField($name, $entity_type, $bundle, $instance_settings = arra * Updates an existing file field with new settings. */ function updateFileField($name, $type_name, $instance_settings = array(), $widget_settings = array()) { - $instance = field_info_instance('node', $name, $type_name); + $instance = FieldInstanceConfig::loadByName('node', $type_name, $name); $instance->settings = array_merge($instance->settings, $instance_settings); $instance->save(); @@ -159,7 +161,7 @@ function uploadNodeFile($file, $field_name, $nid_or_type, $new_revision = TRUE, } // Attach a file to the node. - $field = field_info_field('node', $field_name); + $field = FieldConfig::loadByName('node', $field_name); $name = 'files[' . $field_name . '_0]'; if ($field->getCardinality() != 1) { $name .= '[]'; diff --git a/core/modules/file/lib/Drupal/file/Tests/FileFieldValidateTest.php b/core/modules/file/lib/Drupal/file/Tests/FileFieldValidateTest.php index b85b187..d35a491 100644 --- a/core/modules/file/lib/Drupal/file/Tests/FileFieldValidateTest.php +++ b/core/modules/file/lib/Drupal/file/Tests/FileFieldValidateTest.php @@ -8,7 +8,7 @@ namespace Drupal\file\Tests; use Drupal\Core\Field\FieldDefinitionInterface; -use Drupal\field\Field; +use Drupal\field\Entity\FieldInstanceConfig; /** * Tests various validations. @@ -32,7 +32,7 @@ function testRequired() { $type_name = 'article'; $field_name = strtolower($this->randomName()); $field = $this->createFileField($field_name, 'node', $type_name, array(), array('required' => '1')); - $instance = Field::fieldInfo()->getInstance('node', $type_name, $field_name); + $instance = FieldInstanceConfig::loadByName('node', $type_name, $field_name); $test_file = $this->getTestFile('text'); diff --git a/core/modules/file/lib/Drupal/file/Tests/FileFieldWidgetTest.php b/core/modules/file/lib/Drupal/file/Tests/FileFieldWidgetTest.php index bf80c17..416ea07 100644 --- a/core/modules/file/lib/Drupal/file/Tests/FileFieldWidgetTest.php +++ b/core/modules/file/lib/Drupal/file/Tests/FileFieldWidgetTest.php @@ -6,6 +6,7 @@ */ namespace Drupal\file\Tests; +use Drupal\field\Entity\FieldInstanceConfig; /** * Tests file field widget. @@ -208,7 +209,7 @@ function testPrivateFileSetting() { $type_name = 'article'; $field_name = strtolower($this->randomName()); $this->createFileField($field_name, 'node', $type_name); - $instance = field_info_instance('node', $field_name, $type_name); + $instance = FieldInstanceConfig::loadByName('node', $type_name, $field_name); $test_file = $this->getTestFile('text'); diff --git a/core/modules/file/tests/file_module_test/file_module_test.module b/core/modules/file/tests/file_module_test/file_module_test.module index 30a7664..e9d6010 100644 --- a/core/modules/file/tests/file_module_test/file_module_test.module +++ b/core/modules/file/tests/file_module_test/file_module_test.module @@ -75,10 +75,9 @@ function file_module_test_form_submit($form, &$form_state) { * Implements hook_file_download_access(). */ function file_module_test_file_download_access(FieldConfigInterface $field, EntityInterface $entity, File $file) { - $instance = field_info_instance($entity->getEntityTypeId(), $field->getName(), $entity->bundle()); + $field_definitions = \Drupal::entityManager()->getFieldDefinitions($entity->getEntityTypeId(), $entity->bundle()); // Allow the file to be downloaded only if the given arguments are correct. - // If any are wrong, $instance will be NULL. - if (empty($instance)) { + if (empty($field_definitions[$field->getName()])) { return FALSE; } } diff --git a/core/modules/forum/forum.install b/core/modules/forum/forum.install index 7f975e9..dafedba 100644 --- a/core/modules/forum/forum.install +++ b/core/modules/forum/forum.install @@ -4,6 +4,7 @@ * @file * Install, update, and uninstall functions for the Forum module. */ +use Drupal\field\Entity\FieldConfig; /** * Implements hook_install(). @@ -20,7 +21,7 @@ function forum_install() { // Create the 'taxonomy_forums' field if it doesn't already exist. If forum // is being enabled at the same time as taxonomy after both modules have been // enabled, the field might exist but still be marked inactive. - if (!field_info_field('node', 'taxonomy_forums')) { + if (!FieldConfig::loadByName('node', 'taxonomy_forums')) { entity_create('field_config', array( 'name' => 'taxonomy_forums', 'entity_type' => 'node', @@ -92,15 +93,15 @@ function forum_install() { * Implements hook_uninstall(). */ function forum_uninstall() { - if ($field = field_info_field('node', 'taxonomy_forums')) { + if ($field = FieldConfig::loadByName('node', 'taxonomy_forums')) { $field->delete(); } - if ($field = field_info_field('node', 'comment_forum')) { + if ($field = FieldConfig::loadByName('node', 'comment_forum')) { $field->delete(); } - if ($field = field_info_field('taxonomy_term', 'forum_container')) { + if ($field = FieldConfig::loadByName('taxonomy_term', 'forum_container')) { $field->delete(); } diff --git a/core/modules/forum/forum.module b/core/modules/forum/forum.module index 5facc3c..ae2f9a8 100644 --- a/core/modules/forum/forum.module +++ b/core/modules/forum/forum.module @@ -9,7 +9,7 @@ use Drupal\Component\Utility\Xss; use Drupal\Core\Entity\EntityInterface; use Drupal\Component\Utility\String; -use Drupal\field\Field; +use Drupal\field\Entity\FieldConfig; /** * Implements hook_help(). @@ -109,7 +109,7 @@ function forum_menu_local_tasks(&$data, $route_name) { $vid = \Drupal::config('forum.settings')->get('vocabulary'); $links = array(); // Loop through all bundles for forum taxonomy vocabulary field. - $field = Field::fieldInfo()->getField('node', 'taxonomy_forums'); + $field = FieldConfig::loadByName('node', 'taxonomy_forums'); foreach ($field->getBundles() as $type) { if (\Drupal::entityManager()->getAccessController('node')->createAccess($type)) { $links[$type] = array( diff --git a/core/modules/forum/forum.services.yml b/core/modules/forum/forum.services.yml index 3035062..68a135b 100644 --- a/core/modules/forum/forum.services.yml +++ b/core/modules/forum/forum.services.yml @@ -1,7 +1,7 @@ services: forum_manager: class: Drupal\forum\ForumManager - arguments: ['@config.factory', '@entity.manager', '@database', '@field.info', '@string_translation'] + arguments: ['@config.factory', '@entity.manager', '@database', '@string_translation'] forum.breadcrumb.node: class: Drupal\forum\Breadcrumb\ForumNodeBreadcrumbBuilder arguments: ['@entity.manager', '@config.factory', '@forum_manager'] diff --git a/core/modules/forum/lib/Drupal/forum/ForumManager.php b/core/modules/forum/lib/Drupal/forum/ForumManager.php index 388dd4a..85692ab 100644 --- a/core/modules/forum/lib/Drupal/forum/ForumManager.php +++ b/core/modules/forum/lib/Drupal/forum/ForumManager.php @@ -14,7 +14,6 @@ use Drupal\Core\Session\AccountInterface; use Drupal\Core\StringTranslation\TranslationInterface; use Drupal\comment\CommentInterface; -use Drupal\field\FieldInfo; use Drupal\node\NodeInterface; /** @@ -99,13 +98,6 @@ class ForumManager extends DependencySerialization implements ForumManagerInterf protected $index; /** - * Field info service. - * - * @var \Drupal\field\FieldInfo - */ - protected $fieldInfo; - - /** * Translation manager service. * * @var \Drupal\Core\StringTranslation\TranslationInterface @@ -121,16 +113,13 @@ class ForumManager extends DependencySerialization implements ForumManagerInterf * The entity manager service. * @param \Drupal\Core\Database\Connection $connection * The current database connection. - * @param \Drupal\field\FieldInfo $field_info - * The field info service. * @param \Drupal\Core\StringTranslation\TranslationInterface $translation_manager * The translation manager service. */ - public function __construct(ConfigFactoryInterface $config_factory, EntityManagerInterface $entity_manager, Connection $connection, FieldInfo $field_info, TranslationInterface $translation_manager) { + public function __construct(ConfigFactoryInterface $config_factory, EntityManagerInterface $entity_manager, Connection $connection, TranslationInterface $translation_manager) { $this->configFactory = $config_factory; $this->entityManager = $entity_manager; $this->connection = $connection; - $this->fieldInfo = $field_info; $this->translationManager = $translation_manager; } @@ -488,8 +477,8 @@ public function getParents($tid) { */ public function checkNodeType(NodeInterface $node) { // Fetch information about the forum field. - $instances = $this->fieldInfo->getBundleInstances('node', $node->bundle()); - return !empty($instances['taxonomy_forums']); + $field_definitions = $this->entityManager->getFieldDefinitions('node', $node->bundle()); + return !empty($field_definitions['taxonomy_forums']); } /** diff --git a/core/modules/forum/lib/Drupal/forum/Tests/ForumUninstallTest.php b/core/modules/forum/lib/Drupal/forum/Tests/ForumUninstallTest.php index 1e4e9bd..130143f 100644 --- a/core/modules/forum/lib/Drupal/forum/Tests/ForumUninstallTest.php +++ b/core/modules/forum/lib/Drupal/forum/Tests/ForumUninstallTest.php @@ -9,6 +9,7 @@ use Drupal\comment\CommentInterface; use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface; +use Drupal\field\Entity\FieldConfig; use Drupal\simpletest\WebTestBase; /** @@ -36,7 +37,7 @@ public static function getInfo() { */ function testForumUninstallWithField() { // Ensure that the field exists before uninstallation. - $field = field_info_field('node', 'taxonomy_forums'); + $field = FieldConfig::loadByName('node', 'taxonomy_forums'); $this->assertNotNull($field, 'The taxonomy_forums field exists.'); // Create a taxonomy term. @@ -82,7 +83,7 @@ function testForumUninstallWithField() { $this->assertResponse(200); // Check that the field is now deleted. - $field = field_info_field('node', 'taxonomy_forums'); + $field = FieldConfig::loadByName('node', 'taxonomy_forums'); $this->assertNull($field, 'The taxonomy_forums field has been deleted.'); } @@ -92,12 +93,12 @@ function testForumUninstallWithField() { */ function testForumUninstallWithoutField() { // Manually delete the taxonomy_forums field before module uninstallation. - $field = field_info_field('node', 'taxonomy_forums'); + $field = FieldConfig::loadByName('node', 'taxonomy_forums'); $this->assertNotNull($field, 'The taxonomy_forums field exists.'); $field->delete(); // Check that the field is now deleted. - $field = field_info_field('node', 'taxonomy_forums'); + $field = FieldConfig::loadByName('node', 'taxonomy_forums'); $this->assertNull($field, 'The taxonomy_forums field has been deleted.'); // Ensure that uninstallation succeeds even if the field has already been diff --git a/core/modules/forum/tests/Drupal/forum/Tests/ForumManagerTest.php b/core/modules/forum/tests/Drupal/forum/Tests/ForumManagerTest.php index e1d4a0a..c49a604 100644 --- a/core/modules/forum/tests/Drupal/forum/Tests/ForumManagerTest.php +++ b/core/modules/forum/tests/Drupal/forum/Tests/ForumManagerTest.php @@ -70,15 +70,10 @@ public function testGetIndex() { ->disableOriginalConstructor() ->getMock(); - $field_info = $this->getMockBuilder('\Drupal\field\FieldInfo') - ->disableOriginalConstructor() - ->getMock(); - $manager = $this->getMock('\Drupal\forum\ForumManager', array('getChildren'), array( $config_factory, $entity_manager, $connection, - $field_info, $translation_manager, )); diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php index b49a4ac..dd9ae7c 100644 --- a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php +++ b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php @@ -8,6 +8,7 @@ namespace Drupal\image\Tests; use Drupal\Core\Field\FieldDefinitionInterface; +use Drupal\field\Entity\FieldConfig; /** * Test class to check that formatters and display settings are working. @@ -271,7 +272,7 @@ function testImageFieldDefaultImage() { $this->drupalPostForm("admin/structure/types/manage/article/fields/node.article.$field_name/field", $edit, t('Save field settings')); // Clear field info cache so the new default image is detected. field_info_cache_clear(); - $field = field_info_field('node', $field_name); + $field = FieldConfig::loadByName('node', $field_name); $default_image = $field->getSetting('default_image'); $file = file_load($default_image['fid']); $this->assertTrue($file->isPermanent(), 'The default image status is permanent.'); @@ -309,7 +310,7 @@ function testImageFieldDefaultImage() { $this->drupalPostForm("admin/structure/types/manage/article/fields/node.article.$field_name/field", $edit, t('Save field settings')); // Clear field info cache so the new default image is detected. field_info_cache_clear(); - $field = field_info_field('node', $field_name); + $field = FieldConfig::loadByName('node', $field_name); $default_image = $field->getSetting('default_image'); $this->assertFalse($default_image['fid'], 'Default image removed from field.'); // Create an image field that uses the private:// scheme and test that the @@ -326,7 +327,7 @@ function testImageFieldDefaultImage() { // Clear field info cache so the new default image is detected. field_info_cache_clear(); - $private_field = field_info_field('node', $private_field_name); + $private_field = FieldConfig::loadByName('node', $private_field_name); $default_image = $private_field->getSetting('default_image'); $file = file_load($default_image['fid']); $this->assertEqual('private', file_uri_scheme($file->getFileUri()), 'Default image uses private:// scheme.'); diff --git a/core/modules/migrate/lib/Drupal/migrate/Plugin/MigrateEntityDestinationFieldInterface.php b/core/modules/migrate/lib/Drupal/migrate/Plugin/MigrateEntityDestinationFieldInterface.php index 0fe3b86..4cefa2f 100644 --- a/core/modules/migrate/lib/Drupal/migrate/Plugin/MigrateEntityDestinationFieldInterface.php +++ b/core/modules/migrate/lib/Drupal/migrate/Plugin/MigrateEntityDestinationFieldInterface.php @@ -6,7 +6,7 @@ namespace Drupal\migrate\Plugin; -use Drupal\field\Entity\FieldInstance; +use Drupal\Core\Field\FieldDefinitionInterface; /** * Handle the importing of a specific configurable field type. @@ -16,14 +16,15 @@ /** * Convert an array of values into an array structure fit for entity_create. * - * @param \Drupal\field\Entity\FieldInstance $instance - * The field instance. For example, this can be used to check for required. + * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition + * The field definition. For example, this can be used to check for + * required values. * @param array $values * The array of values. * @return array|NULL * This will be set in the $values array passed to entity_create() as the * value of a configurable field of the type this class handles. */ - public function import(FieldInstance $instance, array $values = NULL); + public function import(FieldDefinitionInterface $field_definition, array $values = NULL); } diff --git a/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/destination/EntityComment.php b/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/destination/EntityComment.php index 53d01ac..94ad394 100644 --- a/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/destination/EntityComment.php +++ b/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/destination/EntityComment.php @@ -46,13 +46,13 @@ class EntityComment extends EntityContentBase { * The list of bundles this entity type has. * @param \Drupal\migrate\Plugin\MigratePluginManager $plugin_manager * The migrate plugin manager. - * @param \Drupal\field\FieldInfo $field_info - * The field and instance definitions service. + * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager + * The entity manager service. * @param \Drupal\Core\State\StateInterface $state * The state storage object. */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityStorageInterface $storage, array $bundles, MigratePluginManager $plugin_manager, FieldInfo $field_info, StateInterface $state) { - parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $storage, $bundles, $plugin_manager, $field_info); + public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityStorageInterface $storage, array $bundles, MigratePluginManager $plugin_manager, FieldInfo $entity_manager, StateInterface $state) { + parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $storage, $bundles, $plugin_manager, $entity_manager); $this->state = $state; } @@ -69,7 +69,7 @@ public static function create(ContainerInterface $container, array $configuratio $container->get('entity.manager')->getStorage($entity_type), array_keys($container->get('entity.manager')->getBundleInfo($entity_type)), $container->get('plugin.manager.migrate.entity_field'), - $container->get('field.info'), + $container->get('entity.manager'), $container->get('state') ); } diff --git a/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/destination/EntityContentBase.php b/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/destination/EntityContentBase.php index 8692947..f73bf10 100644 --- a/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/destination/EntityContentBase.php +++ b/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/destination/EntityContentBase.php @@ -9,9 +9,9 @@ use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\TypedData\TypedDataInterface; -use Drupal\field\FieldInfo; use Drupal\migrate\Entity\MigrationInterface; use Drupal\migrate\Plugin\MigratePluginManager; use Drupal\migrate\Row; @@ -23,9 +23,11 @@ class EntityContentBase extends Entity { /** - * @var \Drupal\field\FieldInfo + * Entity manager. + * + * @var \Drupal\Core\Entity\EntityManagerInterface */ - protected $fieldInfo; + protected $entityManager; /** * Constructs a content entity. @@ -44,13 +46,13 @@ class EntityContentBase extends Entity { * The list of bundles this entity type has. * @param \Drupal\migrate\Plugin\MigratePluginManager $plugin_manager * The plugin manager. - * @param \Drupal\Field\FieldInfo $field_info - * The field info. + * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager + * The entity manager service. */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityStorageInterface $storage, array $bundles, MigratePluginManager $plugin_manager, FieldInfo $field_info) { + public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityStorageInterface $storage, array $bundles, MigratePluginManager $plugin_manager, EntityManagerInterface $entity_manager) { parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $storage, $bundles); $this->migrateEntityFieldPluginManager = $plugin_manager; - $this->fieldInfo = $field_info; + $this->entityManager = $entity_manager; } /** @@ -66,7 +68,7 @@ public static function create(ContainerInterface $container, array $configuratio $container->get('entity.manager')->getStorage($entity_type), array_keys($container->get('entity.manager')->getBundleInfo($entity_type)), $container->get('plugin.manager.migrate.entity_field'), - $container->get('field.info') + $container->get('entity.manager') ); } @@ -74,23 +76,20 @@ public static function create(ContainerInterface $container, array $configuratio * {@inheritdoc} */ public function import(Row $row, array $old_destination_id_values = array()) { - if ($all_instances = $this->fieldInfo->getInstances($this->storage->getEntityTypeId())) { - /** @var \Drupal\Field\Entity\FieldInstanceConfig[] $instances */ - $instances = array(); - if ($bundle_key = $this->getKey('bundle')) { - $bundle = $row->getDestinationProperty($bundle_key); - if (isset($all_instances[$bundle])) { - $instances = $all_instances[$bundle]; - } - } - foreach ($instances as $field_name => $instance) { - $field_type = $instance->getType(); - if ($this->migrateEntityFieldPluginManager->getDefinition($field_type)) { - $destination_value = $this->migrateEntityFieldPluginManager->createInstance($field_type)->import($instance, $row->getDestinationProperty($field_name)); - // @TODO: check for NULL return? Add an unset to $row? Maybe needed in - // exception handling? Propagate exception? - $row->setDestinationProperty($field_name, $destination_value); - } + if ($bundle_key = $this->getKey('bundle')) { + $bundle = $row->getDestinationProperty($bundle_key); + } + else { + $bundle = $this->storage->getEntityTypeId(); + } + $field_definitions = $this->entityManager->getFieldDefinitions($this->storage->getEntityTypeId(), $bundle); + foreach ($field_definitions as $field_name => $field_definition) { + $field_type = $field_definition->getType(); + if ($this->migrateEntityFieldPluginManager->getDefinition($field_type)) { + $destination_value = $this->migrateEntityFieldPluginManager->createInstance($field_type)->import($field_definition, $row->getDestinationProperty($field_name)); + // @TODO: check for NULL return? Add an unset to $row? Maybe needed in + // exception handling? Propagate exception? + $row->setDestinationProperty($field_name, $destination_value); } } $entity = $this->getEntity($row, $old_destination_id_values); diff --git a/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/destination/EntityFile.php b/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/destination/EntityFile.php index 6ae4f30..6703f56 100644 --- a/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/destination/EntityFile.php +++ b/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/destination/EntityFile.php @@ -7,8 +7,8 @@ namespace Drupal\migrate\Plugin\migrate\destination; +use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Entity\EntityStorageInterface; -use Drupal\field\FieldInfo; use Drupal\migrate\Entity\MigrationInterface; use Drupal\migrate\Plugin\MigratePluginManager; use Drupal\migrate\Row; @@ -23,14 +23,14 @@ class EntityFile extends EntityContentBase { /** * {@inheritdoc} */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityStorageInterface $storage, array $bundles, MigratePluginManager $plugin_manager, FieldInfo $field_info) { + public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityStorageInterface $storage, array $bundles, MigratePluginManager $plugin_manager, EntityManagerInterface $entity_manager) { $configuration += array( 'source_base_path' => '', 'source_path_property' => 'filepath', 'destination_path_property' => 'uri', 'move' => FALSE, ); - parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $storage, $bundles, $plugin_manager, $field_info); + parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $storage, $bundles, $plugin_manager, $entity_manager); } /** diff --git a/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/destination/EntityUser.php b/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/destination/EntityUser.php index f8495ba..5cdcfc6 100644 --- a/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/destination/EntityUser.php +++ b/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/destination/EntityUser.php @@ -7,9 +7,9 @@ namespace Drupal\migrate\Plugin\migrate\destination; +use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Password\PasswordInterface; -use Drupal\field\FieldInfo; use Drupal\migrate\Entity\MigrationInterface; use Drupal\migrate\MigrateException; use Drupal\migrate\MigratePassword; @@ -48,13 +48,13 @@ class EntityUser extends EntityContentBase { * The list of bundles this entity type has. * @param \Drupal\migrate\Plugin\MigratePluginManager $plugin_manager * The migrate plugin manager. - * @param \Drupal\field\FieldInfo $field_info - * The field and instance definitions service. + * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager + * The entity manager service. * @param \Drupal\Core\Password\PasswordInterface $password * The password service. */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityStorageInterface $storage, array $bundles, MigratePluginManager $plugin_manager, FieldInfo $field_info, PasswordInterface $password) { - parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $storage, $bundles, $plugin_manager, $field_info); + public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityStorageInterface $storage, array $bundles, MigratePluginManager $plugin_manager, EntityManagerInterface $entity_manager, PasswordInterface $password) { + parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $storage, $bundles, $plugin_manager, $entity_manager); if (isset($configuration['md5_passwords'])) { $this->password = $password; } @@ -73,7 +73,7 @@ public static function create(ContainerInterface $container, array $configuratio $container->get('entity.manager')->getStorage($entity_type), array_keys($container->get('entity.manager')->getBundleInfo($entity_type)), $container->get('plugin.manager.migrate.entity_field'), - $container->get('field.info'), + $container->get('entity.manager'), $container->get('password') ); } diff --git a/core/modules/node/lib/Drupal/node/Tests/Config/NodeImportCreateTest.php b/core/modules/node/lib/Drupal/node/Tests/Config/NodeImportCreateTest.php index 1d59ca1..4ae1923 100644 --- a/core/modules/node/lib/Drupal/node/Tests/Config/NodeImportCreateTest.php +++ b/core/modules/node/lib/Drupal/node/Tests/Config/NodeImportCreateTest.php @@ -7,6 +7,7 @@ namespace Drupal\node\Tests\Config; +use Drupal\field\Entity\FieldInstanceConfig; use Drupal\simpletest\DrupalUnitTestBase; /** @@ -80,7 +81,7 @@ public function testImportCreate() { // Check that the content type was created. $node_type = entity_load('node_type', $node_type_id); $this->assertTrue($node_type, 'Import node type from staging was created.'); - $this->assertFalse(field_info_instance('node', 'body', $node_type_id)); + $this->assertFalse(FieldInstanceConfig::loadByName('node', $node_type_id, 'body')); } } diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php b/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php index 67b34e7..fd83b93 100644 --- a/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php +++ b/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php @@ -7,6 +7,7 @@ namespace Drupal\node\Tests; +use Drupal\field\Entity\FieldConfig; use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationUrl; use Drupal\simpletest\WebTestBase; use Drupal\Core\Language\Language; @@ -60,7 +61,7 @@ function setUp() { $this->assertRaw(t('The content type %type has been updated.', array('%type' => 'Basic page')), 'Basic page content type has been updated.'); // Make node body translatable. - $field = field_info_field('node', 'body'); + $field = FieldConfig::loadByName('node', 'body'); $field->translatable = TRUE; $field->save(); } diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeTypeTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeTypeTest.php index 6cfc32f..4b6ac42 100644 --- a/core/modules/node/lib/Drupal/node/Tests/NodeTypeTest.php +++ b/core/modules/node/lib/Drupal/node/Tests/NodeTypeTest.php @@ -6,6 +6,7 @@ */ namespace Drupal\node\Tests; +use Drupal\field\Entity\FieldInstanceConfig; /** * Tests related to node types. @@ -83,7 +84,7 @@ function testNodeTypeEditing() { $web_user = $this->drupalCreateUser(array('bypass node access', 'administer content types', 'administer node fields')); $this->drupalLogin($web_user); - $instance = field_info_instance('node', 'body', 'page'); + $instance = FieldInstanceConfig::loadByName('node', 'page', 'body'); $this->assertEqual($instance->getLabel(), 'Body', 'Body field was found.'); // Verify that title and body fields are displayed. diff --git a/core/modules/node/node.module b/core/modules/node/node.module index 6b77d21..fc8d6e6 100644 --- a/core/modules/node/node.module +++ b/core/modules/node/node.module @@ -12,6 +12,8 @@ use Drupal\Core\Language\Language; use Drupal\Core\Render\Element; use Drupal\Core\Url; +use Drupal\field\Entity\FieldConfig; +use Drupal\field\Entity\FieldInstanceConfig; use Symfony\Component\HttpFoundation\Response; use Drupal\Core\Cache\Cache; use Drupal\Core\Database\Query\AlterableInterface; @@ -394,8 +396,8 @@ function node_type_load($name) { */ function node_add_body_field(NodeTypeInterface $type, $label = 'Body') { // Add or remove the body field, as needed. - $field = field_info_field('node', 'body'); - $instance = field_info_instance('node', 'body', $type->id()); + $field = FieldConfig::loadByName('node', 'body'); + $instance = FieldInstanceConfig::loadByName('node', $type->id(), 'body'); if (empty($field)) { $field = entity_create('field_config', array( 'name' => 'body', diff --git a/core/modules/node/node.tokens.inc b/core/modules/node/node.tokens.inc index e06da3f..8789047 100644 --- a/core/modules/node/node.tokens.inc +++ b/core/modules/node/node.tokens.inc @@ -131,10 +131,9 @@ function node_tokens($type, $tokens, array $data = array(), array $options = arr case 'body': case 'summary': $translation = \Drupal::entityManager()->getTranslationFromContext($node, $langcode, array('operation' => 'node_tokens')); - if (($items = $translation->get('body')) && !$items->isEmpty()) { + if ($translation->hasField('body') && ($items = $translation->get('body')) && !$items->isEmpty()) { $item = $items[0]; - $instance = field_info_instance('node', 'body', $node->getType()); - $field_langcode = $translation->language()->id; + $field_definition = \Drupal::entityManager()->getFieldDefinitions('node', $node->bundle())['body']; // If the summary was requested and is not empty, use it. if ($name == 'summary' && !empty($item->summary)) { $output = $sanitize ? $item->summary_processed : $item->summary; @@ -157,7 +156,7 @@ function node_tokens($type, $tokens, array $data = array(), array $options = arr $length = $settings['trim_length']; } - $output = text_summary($output, $instance->getSetting('text_processing') ? $item->format : NULL, $length); + $output = text_summary($output, $field_definition->getSetting('text_processing') ? $item->format : NULL, $length); } } $replacements[$original] = $output; diff --git a/core/modules/options/lib/Drupal/options/Tests/OptionsFieldUITest.php b/core/modules/options/lib/Drupal/options/Tests/OptionsFieldUITest.php index dd6d13e..d4f99ec 100644 --- a/core/modules/options/lib/Drupal/options/Tests/OptionsFieldUITest.php +++ b/core/modules/options/lib/Drupal/options/Tests/OptionsFieldUITest.php @@ -7,6 +7,7 @@ namespace Drupal\options\Tests; +use Drupal\field\Entity\FieldConfig; use Drupal\field\Tests\FieldTestBase; /** @@ -231,7 +232,7 @@ function testOptionsAllowedValuesBoolean() { $this->drupalGet($this->admin_path); $this->assertFieldByName('on', $on, t("The 'On' value is stored correctly.")); $this->assertFieldByName('off', $off, t("The 'Off' value is stored correctly.")); - $field = field_info_field('node', $this->field_name); + $field = FieldConfig::loadByName('node', $this->field_name); $this->assertEqual($field->getSetting('allowed_values'), $allowed_values, 'The allowed value is correct'); $this->assertNull($field->getSetting('on'), 'The on value is not saved into settings'); $this->assertNull($field->getSetting('off'), 'The off value is not saved into settings'); @@ -295,7 +296,7 @@ function assertAllowedValuesInput($input_string, $result, $message) { } else { field_info_cache_clear(); - $field = field_info_field('node', $this->field_name); + $field = FieldConfig::loadByName('node', $this->field_name); $this->assertIdentical($field->getSetting('allowed_values'), $result, $message); } } diff --git a/core/modules/path/lib/Drupal/path/Tests/PathLanguageTest.php b/core/modules/path/lib/Drupal/path/Tests/PathLanguageTest.php index a2fcbb7..1ffb010 100644 --- a/core/modules/path/lib/Drupal/path/Tests/PathLanguageTest.php +++ b/core/modules/path/lib/Drupal/path/Tests/PathLanguageTest.php @@ -7,7 +7,7 @@ namespace Drupal\path\Tests; -use Drupal\field\Field; +use Drupal\field\Entity\FieldConfig; /** * Tests URL aliases for translated nodes. @@ -67,9 +67,7 @@ function setUp() { ); $this->drupalPostForm('admin/config/regional/content-language', $edit, t('Save')); - // Ensure configuration changes are picked up in the host environment. - Field::fieldInfo()->flush(); - $field = Field::fieldInfo()->getField('node', 'body'); + $field = FieldConfig::loadByName('node', 'body'); $this->assertTrue($field->isTranslatable(), 'Node body is translatable.'); } diff --git a/core/modules/quickedit/lib/Drupal/quickedit/QuickEditController.php b/core/modules/quickedit/lib/Drupal/quickedit/QuickEditController.php index d981936..2c1c093 100644 --- a/core/modules/quickedit/lib/Drupal/quickedit/QuickEditController.php +++ b/core/modules/quickedit/lib/Drupal/quickedit/QuickEditController.php @@ -14,7 +14,6 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Drupal\Core\Ajax\AjaxResponse; use Drupal\Core\Entity\EntityInterface; -use Drupal\field\FieldInfo; use Drupal\quickedit\Ajax\FieldFormCommand; use Drupal\quickedit\Ajax\FieldFormSavedCommand; use Drupal\quickedit\Ajax\FieldFormValidationErrorsCommand; @@ -48,13 +47,6 @@ class QuickEditController extends ControllerBase { protected $editorSelector; /** - * The field info service. - * - * @var \Drupal\field\FieldInfo - */ - protected $fieldInfo; - - /** * Constructs a new QuickEditController. * * @param \Drupal\user\TempStoreFactory $temp_store_factory @@ -63,14 +55,11 @@ class QuickEditController extends ControllerBase { * The in-place editing metadata generator. * @param \Drupal\quickedit\EditorSelectorInterface $editor_selector * The in-place editor selector. - * @param \Drupal\field\FieldInfo $field_info - * The field info service. */ - public function __construct(TempStoreFactory $temp_store_factory, MetadataGeneratorInterface $metadata_generator, EditorSelectorInterface $editor_selector, FieldInfo $field_info) { + public function __construct(TempStoreFactory $temp_store_factory, MetadataGeneratorInterface $metadata_generator, EditorSelectorInterface $editor_selector) { $this->tempStoreFactory = $temp_store_factory; $this->metadataGenerator = $metadata_generator; $this->editorSelector = $editor_selector; - $this->fieldInfo = $field_info; } /** @@ -80,8 +69,7 @@ public static function create(ContainerInterface $container) { return new static( $container->get('user.tempstore'), $container->get('quickedit.metadata.generator'), - $container->get('quickedit.editor.selector'), - $container->get('field.info') + $container->get('quickedit.editor.selector') ); } diff --git a/core/modules/search/lib/Drupal/search/Tests/SearchCommentTest.php b/core/modules/search/lib/Drupal/search/Tests/SearchCommentTest.php index b470ae6..b18290d 100644 --- a/core/modules/search/lib/Drupal/search/Tests/SearchCommentTest.php +++ b/core/modules/search/lib/Drupal/search/Tests/SearchCommentTest.php @@ -8,7 +8,7 @@ namespace Drupal\search\Tests; use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface; -use Drupal\field\Field; +use Drupal\field\Entity\FieldInstanceConfig; /** * Test integration searching comments. @@ -61,7 +61,7 @@ function testSearchResultsComment() { $comment_body = 'Test comment body'; // Make preview optional. - $instance = Field::fieldInfo()->getInstance('node', 'article', 'comment'); + $instance = FieldInstanceConfig::loadByName('node', 'article', 'comment'); $instance->settings['preview'] = DRUPAL_OPTIONAL; $instance->save(); // Enable check_plain() for 'Basic HTML' text format. @@ -138,7 +138,7 @@ function testSearchResultsCommentAccess() { // Create a node. // Make preview optional. - $instance = Field::fieldInfo()->getInstance('node', 'article', 'comment'); + $instance = FieldInstanceConfig::loadByName('node', 'article', 'comment'); $instance->settings['preview'] = DRUPAL_OPTIONAL; $instance->save(); $this->node = $this->drupalCreateNode(array('type' => 'article')); diff --git a/core/modules/search/lib/Drupal/search/Tests/SearchLanguageTest.php b/core/modules/search/lib/Drupal/search/Tests/SearchLanguageTest.php index 8dcec89..6897ba3 100644 --- a/core/modules/search/lib/Drupal/search/Tests/SearchLanguageTest.php +++ b/core/modules/search/lib/Drupal/search/Tests/SearchLanguageTest.php @@ -8,7 +8,7 @@ namespace Drupal\search\Tests; use Drupal\Core\Language\Language; -use Drupal\field\Field; +use Drupal\field\Entity\FieldConfig; /** * Test node search with multiple languages. @@ -47,7 +47,7 @@ function setUp() { // Make the body field translatable. The title is already translatable by // definition. The parent class has already created the article and page // content types. - $field = Field::fieldInfo()->getField('node', 'body'); + $field = FieldConfig::loadByName('node', 'body'); $field->translatable = TRUE; $field->save(); diff --git a/core/modules/search/lib/Drupal/search/Tests/SearchMultilingualEntityTest.php b/core/modules/search/lib/Drupal/search/Tests/SearchMultilingualEntityTest.php index 37e00e8..1b670bf 100644 --- a/core/modules/search/lib/Drupal/search/Tests/SearchMultilingualEntityTest.php +++ b/core/modules/search/lib/Drupal/search/Tests/SearchMultilingualEntityTest.php @@ -8,7 +8,7 @@ namespace Drupal\search\Tests; use Drupal\Core\Language\Language; -use Drupal\field\Field; +use Drupal\field\Entity\FieldConfig; /** * Tests entities with multilingual fields. @@ -58,7 +58,7 @@ function setUp() { // Make the body field translatable. The title is already translatable by // definition. The parent class has already created the article and page // content types. - $field = Field::fieldInfo()->getField('node', 'body'); + $field = FieldConfig::loadByName('node', 'body'); $field->translatable = TRUE; $field->save(); diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php index 4a05431..a838d2f 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php @@ -17,6 +17,7 @@ use Drupal\Core\TypedData\DataDefinitionInterface; use Drupal\Core\TypedData\Type\StringInterface; use Drupal\Core\TypedData\TypedDataInterface; +use Drupal\field\Entity\FieldInstanceConfig; /** * Tests Entity API base functionality. @@ -623,7 +624,7 @@ public function testComputedProperties() { */ protected function assertComputedProperties($entity_type) { // Make the test text field processed. - $instance = field_info_instance($entity_type, 'field_test_text', $entity_type); + $instance = FieldInstanceConfig::loadByName($entity_type, $entity_type, 'field_test_text'); $instance->settings['text_processing'] = 1; $instance->save(); diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityLanguageTestBase.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityLanguageTestBase.php index bd2ceb9..ada2fbd 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityLanguageTestBase.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityLanguageTestBase.php @@ -8,7 +8,7 @@ namespace Drupal\system\Tests\Entity; use Drupal\Core\Language\Language; -use Drupal\field\Field as FieldService; +use Drupal\field\Entity\FieldConfig; /** * Base class for language-aware entity tests. @@ -133,12 +133,11 @@ function setUp() { protected function toggleFieldTranslatability($entity_type) { $fields = array($this->field_name, $this->untranslatable_field_name); foreach ($fields as $field_name) { - $field = FieldService::fieldInfo()->getField($entity_type, $field_name); + $field = FieldConfig::loadByName($entity_type, $field_name); $translatable = !$field->isTranslatable(); $field->set('translatable', $translatable); $field->save(); - FieldService::fieldInfo()->flush(); - $field = FieldService::fieldInfo()->getField($entity_type, $field_name); + $field = FieldConfig::loadByName($entity_type, $field_name); $this->assertEqual($field->isTranslatable(), $translatable, 'Field translatability changed.'); } \Drupal::cache('entity')->deleteAll(); diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationFormTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationFormTest.php index 46b81bf..8c0288e 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationFormTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationFormTest.php @@ -7,6 +7,7 @@ namespace Drupal\system\Tests\Entity; +use Drupal\field\Entity\FieldConfig; use Drupal\simpletest\WebTestBase; use Drupal\Core\Language\Language; @@ -102,10 +103,10 @@ function testEntityFormLanguage() { $this->assertTrue($node, 'Node found in database.'); // Make body translatable. - $field = field_info_field('node', 'body'); + $field = FieldConfig::loadByName('node', 'body'); $field->translatable = TRUE; $field->save(); - $field = field_info_field('node', 'body'); + $field = FieldConfig::loadByName('node', 'body'); $this->assertTrue($field->isTranslatable(), 'Field body is translatable.'); // Create a body translation and check the form language. diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/FieldSqlStorageTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/FieldSqlStorageTest.php index 82e63b2..8549d99 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/FieldSqlStorageTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/FieldSqlStorageTest.php @@ -445,7 +445,7 @@ function testFieldSqlStorageForeignKeys() { $schema = $field->getSchema(); // Retrieve the field definition and check that the foreign key is in place. - $field = field_info_field('entity_test', $field_name); + $field = FieldConfig::loadByName('entity_test', $field_name); $this->assertEqual($schema['foreign keys'][$foreign_key_name]['table'], $foreign_key_name, 'Foreign key table name modified after update'); $this->assertEqual($schema['foreign keys'][$foreign_key_name]['columns'][$foreign_key_name], 'id', 'Foreign key column name modified after update'); diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/FieldTranslationSqlStorageTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/FieldTranslationSqlStorageTest.php index 2e68569..b9d8cec 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/FieldTranslationSqlStorageTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/FieldTranslationSqlStorageTest.php @@ -10,7 +10,7 @@ use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Entity\ContentEntityDatabaseStorage; use Drupal\Core\Language\Language; -use Drupal\field\Field as FieldService; +use Drupal\field\Entity\FieldConfig; /** * Tests entity translation. @@ -91,7 +91,7 @@ protected function assertFieldStorageLangcode(ContentEntityInterface $entity, $m $fields = array($this->field_name, $this->untranslatable_field_name); foreach ($fields as $field_name) { - $field = FieldService::fieldInfo()->getField($entity_type, $field_name); + $field = FieldConfig::loadByName($entity_type, $field_name); $tables = array( ContentEntityDatabaseStorage::_fieldTableName($field), ContentEntityDatabaseStorage::_fieldRevisionTableName($field), diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Controller/TermAutocompleteController.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Controller/TermAutocompleteController.php index ab1db7d..d6534f8 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Controller/TermAutocompleteController.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Controller/TermAutocompleteController.php @@ -11,9 +11,8 @@ use Drupal\Component\Utility\Unicode; use Drupal\Component\Utility\String; use Drupal\Core\DependencyInjection\ContainerInjectionInterface; +use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Entity\Query\QueryInterface; -use Drupal\field\FieldInfo; -use Drupal\taxonomy\TermStorageInterface; use Drupal\taxonomy\VocabularyInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Request; @@ -33,33 +32,23 @@ class TermAutocompleteController implements ContainerInjectionInterface { protected $termEntityQuery; /** - * Field info service. + * Entity manager. * - * @var \Drupal\field\FieldInfo + * @var \Drupal\Core\Entity\EntityManagerInterface */ - protected $fieldInfo; - - /** - * Term storage. - * - * @var \Drupal\taxonomy\TermStorageInterface - */ - protected $termStorage; + protected $entityManager; /** * Constructs a new \Drupal\taxonomy\Controller\TermAutocompleteController object. * * @param \Drupal\Core\Entity\Query\QueryInterface $term_entity_query * The entity query service. - * @param \Drupal\field\FieldInfo $field_info - * The field info service. - * @param \Drupal\taxonomy\TermStorageInterface $term_storage - * The term storage. + * @param \Drupal\Core\Entity\EntityManagerInterface + * The entity manager. */ - public function __construct(QueryInterface $term_entity_query, FieldInfo $field_info, TermStorageInterface $term_storage) { + public function __construct(QueryInterface $term_entity_query, EntityManagerInterface $entity_manager) { $this->termEntityQuery = $term_entity_query; - $this->fieldInfo = $field_info; - $this->termStorage = $term_storage; + $this->entityManager = $entity_manager; } /** @@ -68,8 +57,7 @@ public function __construct(QueryInterface $term_entity_query, FieldInfo $field_ public static function create(ContainerInterface $container) { return new static( $container->get('entity.query')->get('taxonomy_term'), - $container->get('field.info'), - $container->get('entity.manager')->getStorage('taxonomy_term') + $container->get('entity.manager') ); } @@ -110,11 +98,14 @@ public function autocomplete(Request $request, $entity_type, $field_name) { $tags_typed = $request->query->get('q'); // Make sure the field exists and is a taxonomy field. - if (!($field = $this->fieldInfo->getField($entity_type, $field_name)) || $field->getType() !== 'taxonomy_term_reference') { + $field_definitions = $this->entityManager->getFieldStorageDefinitions($entity_type); + + if (!isset($field_definitions[$field_name]) || $field_definitions[$field_name]->getType() !== 'taxonomy_term_reference') { // Error string. The JavaScript handler will realize this is not JSON and // will display it as debugging information. return new Response(t('Taxonomy field @field_name not found.', array('@field_name' => $field_name)), 403); } + $field = $field_definitions[$field_name]; // The user enters a comma-separated list of tags. We only autocomplete the // last tag. @@ -193,7 +184,7 @@ protected function getMatchingTerms($tags_typed, array $vids, $tag_last) { $prefix = count($tags_typed) ? Tags::implode($tags_typed) . ', ' : ''; if (!empty($tids)) { - $terms = $this->termStorage->loadMultiple(array_keys($tids)); + $terms = $this->entityManager->getStorage('taxonomy_term')->loadMultiple(array_keys($tids)); foreach ($terms as $term) { // Term names containing commas or quotes must be wrapped in quotes. $name = Tags::encode($term->getName()); diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Vocabulary.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Vocabulary.php index ec46b6b..6659ba3 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Vocabulary.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Vocabulary.php @@ -106,7 +106,7 @@ public function postSave(EntityStorageInterface $storage, $update = TRUE) { // Reflect machine name changes in the definitions of existing 'taxonomy' // fields. $field_ids = array(); - $field_map = Field::fieldInfo()->getFieldMap(); + $field_map = \Drupal::entityManager()->getFieldMap(); foreach ($field_map as $entity_type => $fields) { foreach ($fields as $field => $info) { if ($info['type'] == 'taxonomy_term_reference') { diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldMultipleVocabularyTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldMultipleVocabularyTest.php index afac0db..8ec55e7 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldMultipleVocabularyTest.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldMultipleVocabularyTest.php @@ -8,6 +8,7 @@ namespace Drupal\taxonomy\Tests; use Drupal\Core\Field\FieldDefinitionInterface; +use Drupal\field\Entity\FieldConfig; /** * Tests a taxonomy term reference field that allows multiple vocabularies. @@ -122,7 +123,7 @@ function testTaxonomyTermFieldMultipleVocabularies() { $this->assertNoText($term2->getName(), 'Term 2 name is not displayed.'); // Verify that field and instance settings are correct. - $field = field_info_field('entity_test', $this->field_name); + $field = FieldConfig::loadByName('entity_test', $this->field_name); $this->assertEqual(count($field->getSetting('allowed_values')), 1, 'Only one vocabulary is allowed for the field.'); // The widget should still be displayed. diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldTest.php index 1dd0aab..f61b91e 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldTest.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldTest.php @@ -6,6 +6,7 @@ */ namespace Drupal\taxonomy\Tests; +use Drupal\field\Entity\FieldConfig; /** * Tests for taxonomy term field and formatter. @@ -170,7 +171,7 @@ function testTaxonomyTermFieldChangeMachineName() { $this->vocabulary->save(); // Check that the field instance is still attached to the vocabulary. - $field = field_info_field('entity_test', $this->field_name); + $field = FieldConfig::loadByName('entity_test', $this->field_name); $allowed_values = $field->getSetting('allowed_values'); $this->assertEqual($allowed_values[0]['vocabulary'], $new_name, 'Index 0: Machine name was updated correctly.'); $this->assertEqual($allowed_values[1]['vocabulary'], $new_name, 'Index 1: Machine name was updated correctly.'); diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php index 966d45a..8076ed7 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php @@ -11,6 +11,7 @@ use Drupal\Component\Utility\Tags; use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Component\Utility\String; +use Drupal\field\Entity\FieldConfig; /** * Tests for taxonomy term functions. @@ -235,7 +236,7 @@ function testNodeTermCreationAndDeletion() { $field_name = $this->randomName(); $tag = $this->randomName(); $message = t("Taxonomy field @field_name not found.", array('@field_name' => $field_name)); - $this->assertFalse(field_info_field('node', $field_name), format_string('Field %field_name does not exist.', array('%field_name' => $field_name))); + $this->assertFalse(FieldConfig::loadByName('node', $field_name), format_string('Field %field_name does not exist.', array('%field_name' => $field_name))); $this->drupalGet('taxonomy/autocomplete/node/' . $field_name, array('query' => array('q' => $tag))); $this->assertRaw($message, 'Autocomplete returns correct error message when the taxonomy field does not exist.'); } diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/VocabularyUnitTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/VocabularyUnitTest.php index ae757f3..1d640ae 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/VocabularyUnitTest.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/VocabularyUnitTest.php @@ -6,6 +6,7 @@ */ namespace Drupal\taxonomy\Tests; +use Drupal\field\Entity\FieldInstanceConfig; /** * Tests for taxonomy vocabulary functions. @@ -168,7 +169,7 @@ function testTaxonomyVocabularyChangeMachineName() { $this->assertTrue(isset($info[$new_name]), 'The new bundle name appears in entity_get_bundles().'); // Check that the field instance is still attached to the vocabulary. - $this->assertTrue(field_info_instance('taxonomy_term', 'field_test', $new_name), 'The bundle name was updated correctly.'); + $this->assertTrue(FieldInstanceConfig::loadByName('taxonomy_term', $new_name, 'field_test'), 'The bundle name was updated correctly.'); } /** diff --git a/core/modules/user/lib/Drupal/user/UserStorage.php b/core/modules/user/lib/Drupal/user/UserStorage.php index d3f4990..78c48ff 100644 --- a/core/modules/user/lib/Drupal/user/UserStorage.php +++ b/core/modules/user/lib/Drupal/user/UserStorage.php @@ -9,11 +9,10 @@ use Drupal\Component\Uuid\UuidInterface; use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Password\PasswordInterface; use Drupal\Core\Database\Connection; -use Drupal\field\FieldInfo; -use Drupal\user\UserDataInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Drupal\Core\Entity\ContentEntityDatabaseStorage; @@ -46,8 +45,8 @@ class UserStorage extends ContentEntityDatabaseStorage implements UserStorageInt * The entity type definition. * @param \Drupal\Core\Database\Connection $database * The database connection to be used. - * @param \Drupal\field\FieldInfo $field_info - * The field info service. + * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager + * The entity manager. * @param \Drupal\Component\Uuid\UuidInterface $uuid_service * The UUID Service. * @param \Drupal\Core\Password\PasswordInterface $password @@ -55,8 +54,8 @@ class UserStorage extends ContentEntityDatabaseStorage implements UserStorageInt * @param \Drupal\user\UserDataInterface $user_data * The user data service. */ - public function __construct(EntityTypeInterface $entity_type, Connection $database, FieldInfo $field_info, UuidInterface $uuid_service, PasswordInterface $password, UserDataInterface $user_data) { - parent::__construct($entity_type, $database, $field_info, $uuid_service); + public function __construct(EntityTypeInterface $entity_type, Connection $database, EntityManagerInterface $entity_manager, UuidInterface $uuid_service, PasswordInterface $password, UserDataInterface $user_data) { + parent::__construct($entity_type, $database, $entity_manager, $uuid_service); $this->password = $password; $this->userData = $user_data; @@ -69,7 +68,7 @@ public static function createInstance(ContainerInterface $container, EntityTypeI return new static( $entity_type, $container->get('database'), - $container->get('field.info'), + $container->get('entity.manager'), $container->get('uuid'), $container->get('password'), $container->get('user.data') diff --git a/core/modules/user/user.install b/core/modules/user/user.install index 97515a2..0527cb4 100644 --- a/core/modules/user/user.install +++ b/core/modules/user/user.install @@ -5,9 +5,6 @@ * Install, update and uninstall functions for the user module. */ -use Drupal\Core\Language\Language; -use Drupal\field\Field; - /** * Implements hook_schema(). */ diff --git a/core/modules/user/user.module b/core/modules/user/user.module index 9dd87e8..23af29d 100644 --- a/core/modules/user/user.module +++ b/core/modules/user/user.module @@ -199,7 +199,8 @@ function user_attach_accounts(array $entities) { * preprocess stage. */ function user_picture_enabled() { - return (bool) field_info_instance('user', 'user_picture', 'user'); + $field_definitions = \Drupal::entityManager()->getFieldDefinitions('user', 'user'); + return isset($field_definitions['user_picture']); } /** diff --git a/core/modules/views_ui/admin.inc b/core/modules/views_ui/admin.inc index ca14056..930c569 100644 --- a/core/modules/views_ui/admin.inc +++ b/core/modules/views_ui/admin.inc @@ -225,7 +225,7 @@ function views_ui_taxonomy_autocomplete_validate($element, &$form_state) { if ($tags = $element['#value']) { // Get the machine names of the vocabularies we will search, keyed by the // vocabulary IDs. - $field = field_info_field($element['#entity_type'], $element['#field_name']); + $field = \Drupal::entityManager()->getFieldStorageDefinitions($element['#entity_type'])[$element['#field_name']]; $vocabularies = array(); $allowed_values = $field->getSetting('allowed_values'); if (!empty($allowed_values)) { diff --git a/core/tests/Drupal/Tests/Core/Entity/ContentEntityDatabaseStorageTest.php b/core/tests/Drupal/Tests/Core/Entity/ContentEntityDatabaseStorageTest.php index 41358a6..ff20c08 100644 --- a/core/tests/Drupal/Tests/Core/Entity/ContentEntityDatabaseStorageTest.php +++ b/core/tests/Drupal/Tests/Core/Entity/ContentEntityDatabaseStorageTest.php @@ -154,10 +154,7 @@ public function testCreate() { $connection = $this->getMockBuilder('Drupal\Core\Database\Connection') ->disableOriginalConstructor() ->getMock(); - $field_info = $this->getMockBuilder('\Drupal\field\FieldInfo') - ->disableOriginalConstructor() - ->getMock(); - $entity_storage = new ContentEntityDatabaseStorage($entity_type, $connection, $field_info); + $entity_storage = new ContentEntityDatabaseStorage($entity_type, $connection, $entity_manager); $entity = $entity_storage->create(); $entity->expects($this->atLeastOnce()) diff --git a/core/tests/Drupal/Tests/Core/Entity/EntityManagerTest.php b/core/tests/Drupal/Tests/Core/Entity/EntityManagerTest.php index 1c260a3..18d02f6 100644 --- a/core/tests/Drupal/Tests/Core/Entity/EntityManagerTest.php +++ b/core/tests/Drupal/Tests/Core/Entity/EntityManagerTest.php @@ -456,6 +456,7 @@ public function testGetAdminRouteInfo() { * Tests the getBaseFieldDefinitions() method. * * @covers ::getBaseFieldDefinitions() + * @covers ::buildBaseFieldDefinitions() */ public function testGetBaseFieldDefinitions() { $field_definition = $this->setUpEntityWithFieldDefinition(); @@ -468,6 +469,7 @@ public function testGetBaseFieldDefinitions() { * Tests the getFieldDefinitions() method. * * @covers ::getFieldDefinitions() + * @covers ::buildBundleFieldDefinitions() */ public function testGetFieldDefinitions() { $field_definition = $this->setUpEntityWithFieldDefinition(); @@ -480,6 +482,7 @@ public function testGetFieldDefinitions() { * Tests the getFieldStorageDefinitions() method. * * @covers ::getFieldStorageDefinitions() + * @covers ::buildFieldStorageDefinitions() */ public function testGetFieldStorageDefinitions() { $field_definition = $this->setUpEntityWithFieldDefinition(TRUE); @@ -625,6 +628,7 @@ public function testGetFieldStorageDefinitionsWithCaching() { * Tests the getBaseFieldDefinitions() method with an invalid definition. * * @covers ::getBaseFieldDefinitions() + * @covers ::buildBaseFieldDefinitions() * * @expectedException \LogicException */ @@ -641,6 +645,7 @@ public function testGetBaseFieldDefinitionsInvalidDefinition() { * Tests that getFieldDefinitions() method sets the 'provider' definition key. * * @covers ::getFieldDefinitions() + * @covers ::buildBundleFieldDefinitions() */ public function testGetFieldDefinitionsProvider() { $this->setUpEntityWithFieldDefinition(TRUE); @@ -954,6 +959,134 @@ function testgetExtraFields() { } /** + * @covers ::getFieldMap + */ + public function testGetFieldMap() { + // Set up a content entity type. + $entity_type = $this->getMock('Drupal\Core\Entity\ContentEntityTypeInterface'); + $entity = $this->getMock('Drupal\Tests\Core\Entity\TestContentEntityInterface'); + $entity_class = get_class($entity); + $entity_type->expects($this->any()) + ->method('getClass') + ->will($this->returnValue($entity_class)); + $entity_type->expects($this->any()) + ->method('getKeys') + ->will($this->returnValue(array())); + + // Set up the module handler to return two bundles for the fieldable entity + // type. + $this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface'); + $this->moduleHandler->expects($this->any()) + ->method('alter'); + $this->moduleHandler->expects($this->any()) + ->method('getImplementations') + ->will($this->returnValue(array())); + $module_implements_value_map = array( + array( + 'entity_bundle_info', array(), + array( + 'test_entity_type' => array( + 'first_bundle' => array(), + 'second_bundle' => array(), + ), + ), + ), + ); + $this->moduleHandler->expects($this->any()) + ->method('invokeAll') + ->will($this->returnValueMap($module_implements_value_map)); + + + // Define an ID field definition as a base field. + $id_definition = $this->getMockBuilder('Drupal\Core\Field\FieldDefinition') + ->disableOriginalConstructor() + ->getMock(); + $id_definition->expects($this->exactly(2)) + ->method('getType') + ->will($this->returnValue('integer')); + $base_field_definitions = array( + 'id' => $id_definition, + ); + $entity_class::staticExpects($this->once()) + ->method('baseFieldDefinitions') + ->will($this->returnValue($base_field_definitions)); + + // Set up a by bundle field definition that only exists on one bundle. + $bundle_definition = $this->getMockBuilder('Drupal\Core\Field\FieldDefinition') + ->disableOriginalConstructor() + ->getMock(); + $bundle_definition->expects($this->once()) + ->method('getType') + ->will($this->returnValue('string')); + $entity_class::staticExpects($this->any()) + ->method('bundleFieldDefinitions') + ->will($this->returnValueMap(array( + array( + $entity_type, + 'first_bundle', + $base_field_definitions, + array(), + ), + array( + $entity_type, + 'second_bundle', + $base_field_definitions, + array( + 'by_bundle' => $bundle_definition, + ), + ), + ))); + + // Set up a non-content entity type. + $non_content_entity_type = $this->getMock('Drupal\Core\Entity\EntityTypeInterface'); + $this->setUpEntityManager(array( + 'test_entity_type' => $entity_type, + 'non_fieldable' => $non_content_entity_type, + )); + + $expected = array( + 'test_entity_type' => array( + 'id' => array( + 'type' => 'integer', + 'bundles' => array('first_bundle', 'second_bundle'), + ), + 'by_bundle' => array( + 'type' => 'string', + 'bundles' => array('second_bundle'), + ), + ) + ); + $this->assertEquals($expected, $this->entityManager->getFieldMap()); + } + + /** + * @covers ::getFieldMap + */ + public function testGetFieldMapFromCache() { + $expected = array( + 'test_entity_type' => array( + 'id' => array( + 'type' => 'integer', + 'bundles' => array('first_bundle', 'second_bundle'), + ), + 'by_bundle' => array( + 'type' => 'string', + 'bundles' => array('second_bundle'), + ), + ) + ); + $this->setUpEntityManager(); + $this->cache->expects($this->once()) + ->method('get') + ->with('entity_field_map') + ->will($this->returnValue((object) array('data' => $expected))); + + // Call the field map twice to make sure the static cache works. + $this->assertEquals($expected, $this->entityManager->getFieldMap()); + $this->assertEquals($expected, $this->entityManager->getFieldMap()); + } + + /** * Gets a mock controller class name. * * @return string