diff --git a/core/modules/content_translation/content_translation.pages.inc b/core/modules/content_translation/content_translation.pages.inc index 16864bf4baa917a4378923932311a673922b6ea7..4d2fefcc85f57ed660cf974dd3bbddf891c1cdfc 100644 --- a/core/modules/content_translation/content_translation.pages.inc +++ b/core/modules/content_translation/content_translation.pages.inc @@ -37,8 +37,8 @@ function content_translation_overview(EntityInterface $entity) { // Determine whether the current entity is translatable. $translatable = FALSE; - foreach (field_info_instances($entity->getEntityTypeId(), $entity->bundle()) as $instance) { - if ($instance->isTranslatable()) { + foreach (\Drupal::entityManager()->getFieldDefinitions($entity->getEntityTypeId(), $entity->bundle()) as $field_definition) { + if ($field_definition->isTranslatable()) { $translatable = TRUE; break; } diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/ConfigurableEntityReferenceItem.php b/core/modules/entity_reference/lib/Drupal/entity_reference/ConfigurableEntityReferenceItem.php index e6818561f9e3a1f70b0a64274ca1829af14cdffb..372f2f8730a11f474870870165f9d718166fa529 100644 --- a/core/modules/entity_reference/lib/Drupal/entity_reference/ConfigurableEntityReferenceItem.php +++ b/core/modules/entity_reference/lib/Drupal/entity_reference/ConfigurableEntityReferenceItem.php @@ -14,6 +14,7 @@ use Drupal\Core\TypedData\AllowedValuesInterface; use Drupal\Core\TypedData\DataDefinition; use Drupal\Core\Validation\Plugin\Validation\Constraint\AllowedValuesConstraint; +use Drupal\field\FieldConfigInterface; /** * Alternative plugin implementation of the 'entity_reference' field type. @@ -142,7 +143,7 @@ public static function schema(FieldDefinitionInterface $field_definition) { $target_type = $field_definition->getSetting('target_type'); $target_type_info = \Drupal::entityManager()->getDefinition($target_type); - if ($target_type_info->isSubclassOf('\Drupal\Core\Entity\ContentEntityInterface')) { + if ($target_type_info->isSubclassOf('\Drupal\Core\Entity\ContentEntityInterface') && $field_definition instanceof FieldConfigInterface) { $schema['columns']['revision_id'] = array( 'description' => 'The revision ID of the target entity.', 'type' => 'int', diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/entity_reference/selection/SelectionBase.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/entity_reference/selection/SelectionBase.php index 5105a202048b45a6f1bf9ed40cb97547ba9889c4..9d67882e5a5f26d6d19f11fbb9e9329421a0be52 100644 --- a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/entity_reference/selection/SelectionBase.php +++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/entity_reference/selection/SelectionBase.php @@ -11,7 +11,6 @@ use Drupal\Core\Database\Query\SelectInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Field\FieldDefinitionInterface; -use Drupal\Component\Utility\NestedArray; use Drupal\entity_reference\Plugin\Type\Selection\SelectionInterface; /** @@ -53,10 +52,11 @@ public function __construct(FieldDefinitionInterface $field_definition, EntityIn * {@inheritdoc} */ public static function settingsForm(FieldDefinitionInterface $field_definition) { - $target_type = $field_definition->getSetting('target_type'); + $entity_manager = \Drupal::entityManager(); + $entity_type_id = $field_definition->getSetting('target_type'); $selection_handler_settings = $field_definition->getSetting('handler_settings') ?: array(); - $entity_type = \Drupal::entityManager()->getDefinition($target_type); - $bundles = entity_get_bundles($target_type); + $entity_type = $entity_manager->getDefinition($entity_type_id); + $bundles = $entity_manager->getBundleInfo($entity_type_id); // Merge-in default values. $selection_handler_settings += array( @@ -75,10 +75,10 @@ public static function settingsForm(FieldDefinitionInterface $field_definition) $target_bundles_title = t('Bundles'); // Default core entity types with sensible labels. - if ($target_type == 'node') { + if ($entity_type_id == 'node') { $target_bundles_title = t('Content types'); } - elseif ($target_type == 'taxonomy_term') { + elseif ($entity_type_id == 'taxonomy_term') { $target_bundles_title = t('Vocabularies'); } @@ -100,18 +100,26 @@ public static function settingsForm(FieldDefinitionInterface $field_definition) ); } - $target_type_info = \Drupal::entityManager()->getDefinition($target_type); - if ($target_type_info->isSubclassOf('\Drupal\Core\Entity\ContentEntityInterface')) { - // @todo Use Entity::getFieldDefinitions() when all entity types are - // converted to the new Field API. - $fields = drupal_schema_fields_sql($entity_type->getBaseTable()); - $fields = array_combine($fields, $fields); - foreach (field_info_instances($target_type) as $bundle_instances) { - foreach ($bundle_instances as $instance_name => $instance) { - foreach ($instance->getField()->getColumns() as $column_name => $column_info) { - $fields[$instance_name . '.' . $column_name] = t('@label (@column)', array('@label' => $instance->getLabel(), '@column' => $column_name)); + if ($entity_type->isSubclassOf('\Drupal\Core\Entity\ContentEntityInterface')) { + $fields = array(); + foreach (array_keys($bundles) as $bundle) { + $bundle_fields = array_filter($entity_manager->getFieldDefinitions($entity_type_id, $bundle), function ($field_definition) { + return !$field_definition->isComputed(); + }); + foreach ($bundle_fields as $instance_name => $field_definition) { + /* @var \Drupal\Core\Field\FieldDefinitionInterface $field_definition */ + $columns = $field_definition->getColumns(); + // If there is more than one column, display them all, otherwise just + // display the field label. + // @todo: Use property labels instead of the column name. + if (count($columns) > 1) { + foreach ($field_definition->getColumns() as $column_name => $column_info) { + $fields[$instance_name . '.' . $column_name] = t('@label (@column)', array('@label' => $field_definition->getLabel(), '@column' => $column_name)); + } + } + else { + $fields[$instance_name] = t('@label', array('@label' => $field_definition->getLabel())); } - } } diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAdminTest.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAdminTest.php index 37cf7bb9372744adfe3943b145521cb96c912b7f..545bc1bf28770899fa93401534b9280996ddf80f 100644 --- a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAdminTest.php +++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAdminTest.php @@ -13,6 +13,17 @@ * Tests the Entity Reference Admin UI. */ class EntityReferenceAdminTest extends WebTestBase { + + /** + * Modules to enable. + * + * @var array + */ + public static $modules = array('node', 'field_ui', 'entity_reference'); + + /** + * {@inheritdoc} + */ public static function getInfo() { return array( 'name' => 'Entity Reference admin UI', @@ -21,47 +32,22 @@ public static function getInfo() { ); } - public static $modules = array('node', 'field_ui', 'entity_reference'); - public function setUp() { parent::setUp(); // Create test user. - $this->admin_user = $this->drupalCreateUser(array('access content', 'administer node fields')); - $this->drupalLogin($this->admin_user); + $admin_user = $this->drupalCreateUser(array('access content', 'administer node fields')); + $this->drupalLogin($admin_user); - // Create content type, with underscores. + // Create a content type, with underscores. $type_name = strtolower($this->randomName(8)) . '_test'; $type = $this->drupalCreateContentType(array('name' => $type_name, 'type' => $type_name)); $this->type = $type->type; } - protected function assertFieldSelectOptions($name, $expected_options) { - $xpath = $this->buildXPathQuery('//select[@name=:name]', array(':name' => $name)); - $fields = $this->xpath($xpath); - if ($fields) { - $field = $fields[0]; - $options = $this->getAllOptionsList($field); - return $this->assertIdentical($options, $expected_options); - } - else { - return $this->fail(t('Unable to find field @name', array('@name' => $name))); - } - } - /** - * Extract all the options of a select element. + * Tests the Entity Reference Admin UI. */ - protected function getAllOptionsList($element) { - $options = array(); - // Add all options items. - foreach ($element->option as $option) { - $options[] = (string) $option['value']; - } - // TODO: support optgroup. - return $options; - } - public function testFieldAdminHandler() { $bundle_path = 'admin/structure/types/manage/' . $this->type; @@ -76,9 +62,7 @@ public function testFieldAdminHandler() { $this->assertFieldByName('field[settings][target_type]', 'node'); // Check that all entity types can be referenced. - foreach (\Drupal::entityManager()->getDefinitions() as $entity_type_id => $entity_type) { - $this->assertFieldByXPath("//select[@name='field[settings][target_type]']/option[@value='" . $entity_type_id . "']"); - } + $this->assertFieldSelectOptions('field[settings][target_type]', array_keys(\Drupal::entityManager()->getDefinitions())); // Second step: 'Instance settings' form. $this->drupalPostForm(NULL, array(), t('Save field settings')); @@ -102,8 +86,17 @@ public function testFieldAdminHandler() { // Option 1: sort by field. $this->drupalPostAjaxForm(NULL, array('instance[settings][handler_settings][sort][field]' => 'nid'), 'instance[settings][handler_settings][sort][field]'); $this->assertFieldByName('instance[settings][handler_settings][sort][direction]', 'ASC'); + + // Test that a non-translatable base field is a sort option. + $this->assertFieldByXPath("//select[@name='instance[settings][handler_settings][sort][field]']/option[@value='nid']"); + // Test that a translatable base field is a sort option. + $this->assertFieldByXPath("//select[@name='instance[settings][handler_settings][sort][field]']/option[@value='title']"); + // Test that a configurable field is a sort option. + $this->assertFieldByXPath("//select[@name='instance[settings][handler_settings][sort][field]']/option[@value='body.value']"); + // Set back to no sort. $this->drupalPostAjaxForm(NULL, array('instance[settings][handler_settings][sort][field]' => '_none'), 'instance[settings][handler_settings][sort][field]'); + $this->assertNoFieldByName('instance[settings][handler_settings][sort][direction]'); // Third step: confirm. $this->drupalPostForm(NULL, array( @@ -113,4 +106,52 @@ public function testFieldAdminHandler() { // Check that the field appears in the overview form. $this->assertFieldByXPath('//table[@id="field-overview"]//tr[@id="field-test"]/td[1]', 'Test label', 'Field was created and appears in the overview page.'); } + + /** + * Checks if a select element contains the specified options. + * + * @param string $name + * The field name. + * @param array $expected_options + * An array of expected options. + * + * @return bool + * TRUE if the assertion succeeded, FALSE otherwise. + */ + protected function assertFieldSelectOptions($name, array $expected_options) { + $xpath = $this->buildXPathQuery('//select[@name=:name]', array(':name' => $name)); + $fields = $this->xpath($xpath); + if ($fields) { + $field = $fields[0]; + $options = $this->getAllOptionsList($field); + return $this->assertIdentical($options, $expected_options); + } + else { + return $this->fail('Unable to find field ' . $name); + } + } + + /** + * Extracts all options from a select element. + * + * @param \SimpleXMLElement $element + * The select element field information. + * + * @return array + * An array of option values as strings. + */ + protected function getAllOptionsList(\SimpleXMLElement $element) { + $options = array(); + // Add all options items. + foreach ($element->option as $option) { + $options[] = (string) $option['value']; + } + + if (isset($element->optgroup)) { + $options += $this->getAllOptionsList($element->optgroup); + } + + return $options; + } + } diff --git a/core/modules/field/field.views.inc b/core/modules/field/field.views.inc index c14216354049f3905e027593e1f9f92e66269800..05b65ef76975f82af51d612a0ff3c11cd064ba93 100644 --- a/core/modules/field/field.views.inc +++ b/core/modules/field/field.views.inc @@ -9,6 +9,7 @@ use Drupal\Core\Entity\ContentEntityDatabaseStorage; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\field\FieldConfigInterface; +use Drupal\field\FieldInstanceConfigInterface; /** * Implements hook_views_data(). @@ -81,8 +82,10 @@ function field_views_field_label($entity_type, $field_name) { $label_counter = array(); $all_labels = array(); // Count the amount of instances per label per field. - $instances = field_info_instances($entity_type); - foreach ($instances as $bundle => $bundle_instances) { + foreach (array_keys(\Drupal::entityManager()->getBundleInfo($entity_type)) as $bundle) { + $bundle_instances = array_filter(\Drupal::entityManager()->getFieldDefinitions($entity_type, $bundle), function ($field_definition) { + return $field_definition instanceof FieldInstanceConfigInterface; + }); if (isset($bundle_instances[$field_name])) { $instance = $bundle_instances[$field_name]; $label = $instance->getLabel(); diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldAttachStorageTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldAttachStorageTest.php index 4b0e85e43a2dbaa613c8301914d36ff641f480a2..efb6ae80a6b7a33ef0dce3aeb1a7dd8bd78b67e8 100644 --- a/core/modules/field/lib/Drupal/field/Tests/FieldAttachStorageTest.php +++ b/core/modules/field/lib/Drupal/field/Tests/FieldAttachStorageTest.php @@ -2,7 +2,7 @@ /** * @file - * Definition of Drupal\field\Tests\FieldAttachStorageTest. + * Contains \Drupal\field\Tests\FieldAttachStorageTest. */ namespace Drupal\field\Tests; @@ -146,8 +146,10 @@ function testFieldAttachLoadMultiple() { foreach ($bundles as $index => $bundle) { $entities[$index] = entity_create($entity_type, array('id' => $index, 'revision_id' => $index, 'type' => $bundle)); $entity = clone($entities[$index]); - $instances = field_info_instances($entity_type, $bundle); - foreach ($instances as $field_name => $instance) { + foreach ($field_names as $field_name) { + if (!$entity->hasField($field_name)) { + continue; + } $values[$index][$field_name] = mt_rand(1, 127); $entity->$field_name->setValue(array('value' => $values[$index][$field_name])); } @@ -160,8 +162,10 @@ function testFieldAttachLoadMultiple() { $controller->resetCache(); $entities = $controller->loadMultiple(); foreach ($entities as $index => $entity) { - $instances = field_info_instances($entity_type, $bundles[$index]); - foreach ($instances as $field_name => $instance) { + foreach ($field_names as $field_name) { + if (!$entity->hasField($field_name)) { + continue; + } // The field value loaded matches the one inserted. $this->assertEqual($entity->{$field_name}->value, $values[$index][$field_name], format_string('Entity %index: expected value was found.', array('%index' => $index))); // The value added in hook_field_load() is found. 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 523f1b046e203a68253331ae630c6b7a6a6f3368..958d15a90c378bbec731fac774b50570be7d8db2 100644 --- a/core/modules/field_ui/lib/Drupal/field_ui/FieldOverview.php +++ b/core/modules/field_ui/lib/Drupal/field_ui/FieldOverview.php @@ -15,6 +15,7 @@ use Drupal\field_ui\OverviewBase; use Symfony\Component\DependencyInjection\ContainerInterface; use Drupal\field\Entity\FieldConfig; +use Drupal\field\FieldInstanceConfigInterface; /** * Field UI field overview form. @@ -79,7 +80,9 @@ public function buildForm(array $form, array &$form_state, $entity_type_id = NUL parent::buildForm($form, $form_state, $entity_type_id, $bundle); // Gather bundle information. - $instances = field_info_instances($this->entity_type, $this->bundle); + $instances = array_filter(\Drupal::entityManager()->getFieldDefinitions($this->entity_type, $this->bundle), function ($field_definition) { + return $field_definition instanceof FieldInstanceConfigInterface; + }); $field_types = $this->fieldTypeManager->getDefinitions(); // Field prefix. diff --git a/core/modules/file/file.field.inc b/core/modules/file/file.field.inc index d07bf9b874c23b8f9e96d79f123f156606f6f4c9..f9aa9f9620f7a3788685a8555cec96c8dfdb63d1 100644 --- a/core/modules/file/file.field.inc +++ b/core/modules/file/file.field.inc @@ -6,8 +6,8 @@ */ use Drupal\Component\Utility\Html; +use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Render\Element; -use Drupal\field\FieldConfigInterface; /** * Returns HTML for an individual file upload widget. @@ -214,14 +214,14 @@ function theme_file_upload_help($variables) { /** * Determine whether a field references files stored in {file_managed}. * - * @param Drupal\field\FieldConfigInterface $field + * @param \Drupal\Core\Field\FieldDefinitionInterface $field * A field definition. * - * @return + * @return bool * The field column if the field references {file_managed}.fid, typically - * fid, FALSE if it doesn't. + * fid, FALSE if it does not. */ -function file_field_find_file_reference_column(FieldConfigInterface $field) { +function file_field_find_file_reference_column(FieldDefinitionInterface $field) { $schema = $field->getSchema(); foreach ($schema['foreign keys'] as $data) { if ($data['table'] == 'file_managed') { diff --git a/core/modules/file/file.module b/core/modules/file/file.module index b707b57fc003ab817e3784c89dcac0664f2f0c26..389086287eddf56c6e97250f3bf8fe5410e51c9a 100644 --- a/core/modules/file/file.module +++ b/core/modules/file/file.module @@ -1880,13 +1880,12 @@ function file_get_file_references(File $file, $field = NULL, $age = EntityStorag if (!isset($file_fields[$entity_type_id][$bundle])) { $file_fields[$entity_type_id][$bundle] = array(); // This contains the possible field names. - $instances = field_info_instances($entity_type_id, $bundle); - foreach ($instances as $field_name => $instance) { - $field_type = $instance->getType(); + foreach ($entity->getFieldDefinitions() as $field_name => $field_definition) { + $field_type = $field_definition->getType(); // If this is the first time this field type is seen, check // whether it references files. if (!isset($field_columns[$field_type])) { - $field_columns[$field_type] = file_field_find_file_reference_column($instance->getField()); + $field_columns[$field_type] = file_field_find_file_reference_column($field_definition); } // If the field type does reference files then record it. if ($field_columns[$field_type]) { diff --git a/core/modules/node/lib/Drupal/node/Plugin/views/wizard/Node.php b/core/modules/node/lib/Drupal/node/Plugin/views/wizard/Node.php index a5c2e35386066237128670b66fb928b90619ef3d..fc5aadbb9525b8f829ac567e0b0122a75cfc9bc7 100644 --- a/core/modules/node/lib/Drupal/node/Plugin/views/wizard/Node.php +++ b/core/modules/node/lib/Drupal/node/Plugin/views/wizard/Node.php @@ -265,7 +265,10 @@ protected function buildFilters(&$form, &$form_state) { $tag_fields = array(); foreach ($bundles as $bundle) { $display = entity_get_form_display($this->entityTypeId, $bundle, 'default'); - foreach (field_info_instances($this->entityTypeId, $bundle) as $field_name => $instance) { + $taxonomy_fields = array_filter(\Drupal::entityManager()->getFieldDefinitions($this->entityTypeId, $bundle), function ($field_definition) { + return $field_definition->getType() == 'taxonomy_term_reference'; + }); + foreach ($taxonomy_fields as $field_name => $instance) { $widget = $display->getComponent($field_name); // We define "tag-like" taxonomy fields as ones that use the // "Autocomplete term widget (tagging)" widget. diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeTranslationUITest.php b/core/modules/node/lib/Drupal/node/Tests/NodeTranslationUITest.php index 40129081f6e1a91dbeef3f2508050e03c36976db..95eba8cafc284e0df06a38952209fa2fa53d6619 100644 --- a/core/modules/node/lib/Drupal/node/Tests/NodeTranslationUITest.php +++ b/core/modules/node/lib/Drupal/node/Tests/NodeTranslationUITest.php @@ -195,26 +195,6 @@ function testTranslateLinkContentAdminPage() { $this->assertNoLinkByHref('node/' . $page->id() . '/translations'); } - /** - * Tests field translation form. - */ - function testFieldTranslationForm() { - $this->drupalLogin($this->administrator); - - $article = $this->drupalCreateNode(array('type' => 'article', 'langcode' => 'en')); - - // Visit translation page. - $this->drupalGet('node/' . $article->id() . '/translations'); - $this->assertRaw('Not translated'); - - // Delete the only translatable field. - field_info_field($this->entityTypeId, 'field_test_et_ui_test')->delete(); - - // Visit translation page. - $this->drupalGet('node/' . $article->id() . '/translations'); - $this->assertRaw('No translatable fields'); - } - /** * Tests that no metadata is stored for a disabled bundle. */ diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/views/argument_default/Tid.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/views/argument_default/Tid.php index bbfefb97ab470d0fdd1b3ed2f6a2bc5505706968..33b35a8616cb2be933c642ee0d8a5e73abfd4d04 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/views/argument_default/Tid.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/views/argument_default/Tid.php @@ -168,12 +168,11 @@ public function getArgument() { // Just check, if a node could be detected. if (($node = $this->request->attributes->has('node')) && $node instanceof NodeInterface) { $taxonomy = array(); - $instances = field_info_instances('node', $node->getType()); - foreach ($instances as $instance) { - $field = $instance->getField(); - if ($field->type == 'taxonomy_term_reference') { - foreach ($node->get($field->name) as $item) { - $taxonomy[$item->target_id] = $field->settings['allowed_values'][0]['vocabulary']; + foreach ($node->getFieldDefinitions() as $field) { + if ($field->getType() == 'taxonomy_term_reference') { + foreach ($node->get($field->getName()) as $item) { + $allowed_values = $field->getSetting('allowed_values'); + $taxonomy[$item->target_id] = $allowed_values[0]['vocabulary']; } } } diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module index bc53e48e93bbf0373521f5626a75713e7af9d5e7..b808012fcfed8f9f74ddca994a147fb4bce78458 100644 --- a/core/modules/taxonomy/taxonomy.module +++ b/core/modules/taxonomy/taxonomy.module @@ -786,10 +786,9 @@ function taxonomy_build_node_index($node) { if ($status && $node->isDefaultRevision()) { // Collect a unique list of all the term IDs from all node fields. $tid_all = array(); - foreach (field_info_instances('node', $node->getType()) as $instance) { - $field = $instance->getField(); + foreach ($node->getFieldDefinitions() as $field) { $field_name = $field->getName(); - if ($field->module == 'taxonomy') { + if ($field->getType() == 'taxonomy_term_reference') { foreach ($node->getTranslationLanguages() as $language) { foreach ($node->getTranslation($language->id)->$field_name as $item) { if (!$item->isEmpty()) {