diff --git a/core/modules/entity_reference/entity_reference.module b/core/modules/entity_reference/entity_reference.module index e6d764bb8d3402768570c559465db3e0f0a05d0c..94f4843c61362c275fb55dcc52c45bcbfbab5e0a 100644 --- a/core/modules/entity_reference/entity_reference.module +++ b/core/modules/entity_reference/entity_reference.module @@ -33,7 +33,15 @@ function entity_reference_help($route_name, RouteMatchInterface $route_match) { $output .= '
' . t('Filtering and sorting reference fields') . '
'; $output .= '
' . t('Depending on the chosen entity type, additional filtering and sorting options are available for the list of entities that can be referred to, in the field settings. For example, the list of users can be filtered by role and sorted by name or ID.') . '
'; $output .= '
' . t('Displaying a reference') . '
'; - $output .= '
' . t('An entity reference can be displayed as a simple label with or without a link to the entity. Alternatively, the referenced entity can be displayed as a teaser (or any other available view mode) inside the referencing entity.') . '
'; + $output .= '
' . t('An entity reference can be displayed as a simple label with or without a link to the entity. Alternatively, the referenced entity can be displayed as a teaser (or any other available view mode) inside the referencing entity. Certain entity types may provide additional display options. You can configure how the entity reference is displayed on the Manage display page for the entity.') . '
'; + $output .= '
' . t('Configuring form displays') . '
'; + $output .= '
' . t('Reference fields have several widgets available on the Manage form display page:'); + $output .= ''; $output .= ''; return $output; } diff --git a/core/modules/field_ui/src/Tests/ManageFieldsTest.php b/core/modules/field_ui/src/Tests/ManageFieldsTest.php index 28b80ae9bb334b36dcee068a69154e03c4e41ae4..0db2dd5f73cd7780fd48c49fdc95b77b9c58f7aa 100644 --- a/core/modules/field_ui/src/Tests/ManageFieldsTest.php +++ b/core/modules/field_ui/src/Tests/ManageFieldsTest.php @@ -10,6 +10,7 @@ use Drupal\Component\Utility\String; use Drupal\Core\Field\FieldStorageDefinitionInterface; use Drupal\Core\Language\LanguageInterface; +use Drupal\entity_reference\Tests\EntityReferenceTestTrait; use Drupal\field\Entity\FieldConfig; use Drupal\field\Entity\FieldStorageConfig; use Drupal\simpletest\WebTestBase; @@ -22,6 +23,7 @@ class ManageFieldsTest extends WebTestBase { use FieldUiTestTrait; + use EntityReferenceTestTrait; /** * Modules to install. @@ -91,18 +93,12 @@ protected function setUp() { )); $vocabulary->save(); - entity_create('field_storage_config', array( - 'field_name' => 'field_' . $vocabulary->id(), - 'entity_type' => 'node', - 'type' => 'taxonomy_term_reference', - ))->save(); - - entity_create('field_config', array( - 'field_name' => 'field_' . $vocabulary->id(), - 'entity_type' => 'node', - 'label' => 'Tags', - 'bundle' => 'article', - ))->save(); + $handler_settings = array( + 'target_bundles' => array( + $vocabulary->id() => $vocabulary->id(), + ), + ); + $this->createEntityReferenceField('node', 'article', 'field_' . $vocabulary->id(), 'Tags', 'taxonomy_term', 'default', $handler_settings); entity_get_form_display('node', 'article', 'default') ->setComponent('field_' . $vocabulary->id()) @@ -606,7 +602,7 @@ function testDuplicateFieldName() { $edit = array( 'field_name' => 'tags', 'label' => $this->randomMachineName(), - 'new_storage_type' => 'taxonomy_term_reference', + 'new_storage_type' => 'entity_reference', ); $url = 'admin/structure/types/manage/' . $this->contentType . '/fields/add-field'; $this->drupalPostForm($url, $edit, t('Save and continue')); diff --git a/core/modules/forum/config/install/core.entity_view_display.node.forum.default.yml b/core/modules/forum/config/install/core.entity_view_display.node.forum.default.yml index 70e589f320dedd08058993c5582789dc696513d9..8da8d3b401c1e5eb81cbbc89ddd397aa39e018f4 100644 --- a/core/modules/forum/config/install/core.entity_view_display.node.forum.default.yml +++ b/core/modules/forum/config/install/core.entity_view_display.node.forum.default.yml @@ -17,10 +17,11 @@ bundle: forum mode: default content: taxonomy_forums: - type: taxonomy_term_reference_link + type: entity_reference_label weight: -1 label: above - settings: { } + settings: + link: true third_party_settings: { } body: label: hidden diff --git a/core/modules/forum/config/install/core.entity_view_display.node.forum.teaser.yml b/core/modules/forum/config/install/core.entity_view_display.node.forum.teaser.yml index f8bc4fe90a4094662d12bf6054df5c8910d4d47f..2333ad8bd0ca2e850bc2e7c98f14f75c21094068 100644 --- a/core/modules/forum/config/install/core.entity_view_display.node.forum.teaser.yml +++ b/core/modules/forum/config/install/core.entity_view_display.node.forum.teaser.yml @@ -17,10 +17,11 @@ bundle: forum mode: teaser content: taxonomy_forums: - type: taxonomy_term_reference_link + type: entity_reference_label weight: 10 label: above - settings: { } + settings: + link: true third_party_settings: { } body: label: hidden diff --git a/core/modules/forum/config/install/field.field.node.forum.taxonomy_forums.yml b/core/modules/forum/config/install/field.field.node.forum.taxonomy_forums.yml index 9847752071925f912f7d14da463d8917c5a907a6..b5e73320835a3feb846e98689fcfffdd76e92a43 100644 --- a/core/modules/forum/config/install/field.field.node.forum.taxonomy_forums.yml +++ b/core/modules/forum/config/install/field.field.node.forum.taxonomy_forums.yml @@ -18,5 +18,11 @@ default_value: { } default_value_callback: '' settings: handler: default + handler_settings: + target_bundles: + forums: forums + sort: + field: _none + auto_create: true third_party_settings: { } -field_type: taxonomy_term_reference +field_type: entity_reference diff --git a/core/modules/forum/config/install/field.storage.node.taxonomy_forums.yml b/core/modules/forum/config/install/field.storage.node.taxonomy_forums.yml index e05c0df90a5b049c8548a6f7ec23aba3e257ac8d..0f1e8ae3b29e85ad4d2529151c707f7b6148c0cc 100644 --- a/core/modules/forum/config/install/field.storage.node.taxonomy_forums.yml +++ b/core/modules/forum/config/install/field.storage.node.taxonomy_forums.yml @@ -7,15 +7,9 @@ dependencies: id: node.taxonomy_forums field_name: taxonomy_forums entity_type: node -type: taxonomy_term_reference +type: entity_reference settings: - allowed_values: - - - vocabulary: forums - parent: 0 target_type: taxonomy_term - options_list_callback: null - target_bundle: null module: taxonomy locked: false cardinality: 1 diff --git a/core/modules/migrate_drupal/config/install/migrate.migration.d6_vocabulary_entity_display.yml b/core/modules/migrate_drupal/config/install/migrate.migration.d6_vocabulary_entity_display.yml index c91b1d8703fda637bb9bbd75b6e59188babf9cf0..ac8815f715ffa69b7c86934fed52ba5f12348c51 100644 --- a/core/modules/migrate_drupal/config/install/migrate.migration.d6_vocabulary_entity_display.yml +++ b/core/modules/migrate_drupal/config/install/migrate.migration.d6_vocabulary_entity_display.yml @@ -9,7 +9,7 @@ source: view_mode: default options: label: hidden - type: taxonomy_term_reference_link + type: entity_reference_label weight: 20 process: diff --git a/core/modules/migrate_drupal/config/install/migrate.migration.d6_vocabulary_field.yml b/core/modules/migrate_drupal/config/install/migrate.migration.d6_vocabulary_field.yml index a833cbd0a2af378a6b9df46caac4c51eba7516ea..f838a74a0a90085040c952d3478ec01d63dee2d1 100644 --- a/core/modules/migrate_drupal/config/install/migrate.migration.d6_vocabulary_field.yml +++ b/core/modules/migrate_drupal/config/install/migrate.migration.d6_vocabulary_field.yml @@ -6,8 +6,8 @@ source: plugin: d6_taxonomy_vocabulary constants: entity_type: node - type: taxonomy_term_reference - parent: 0 + type: entity_reference + target_entity_type: taxonomy_term cardinality: -1 process: entity_type: 'constants/entity_type' @@ -16,8 +16,7 @@ process: plugin: migration migration: d6_taxonomy_vocabulary source: vid - 'settings/allowed_values/0/vocabulary': @field_name - 'settings/allowed_values/0/parent': 'constants/parent' + 'settings/target_type': 'constants/target_entity_type' cardinality: 'constants/cardinality' destination: plugin: entity:field_storage_config diff --git a/core/modules/migrate_drupal/config/install/migrate.migration.d6_vocabulary_field_instance.yml b/core/modules/migrate_drupal/config/install/migrate.migration.d6_vocabulary_field_instance.yml index 15d818655c40cd8353d51402b70146c425a6ef41..a9ada0842e63c54af42b20e348824cb7b369e0b1 100644 --- a/core/modules/migrate_drupal/config/install/migrate.migration.d6_vocabulary_field_instance.yml +++ b/core/modules/migrate_drupal/config/install/migrate.migration.d6_vocabulary_field_instance.yml @@ -6,7 +6,8 @@ source: plugin: d6_taxonomy_vocabulary_per_type constants: entity_type: node - parent: 0 + auto_create: true + selection_handler: 'default:taxonomy_term' process: entity_type: 'constants/entity_type' bundle: type @@ -14,6 +15,9 @@ process: plugin: migration migration: d6_taxonomy_vocabulary source: vid + 'settings/handler': 'constants/selection_handler' + 'settings/handler_settings/target_bundles/0': @field_name + 'settings/handler_settings/auto_create': 'constants/auto_create' destination: plugin: entity:field_config migration_dependencies: diff --git a/core/modules/migrate_drupal/config/schema/migrate_drupal.source.schema.yml b/core/modules/migrate_drupal/config/schema/migrate_drupal.source.schema.yml index e43ffe8bceab18c119ce0bf181394d009aa80355..f48c43e395bda97dd88b6ff64b58f85194318604 100644 --- a/core/modules/migrate_drupal/config/schema/migrate_drupal.source.schema.yml +++ b/core/modules/migrate_drupal/config/schema/migrate_drupal.source.schema.yml @@ -290,6 +290,9 @@ migrate_entity_constant: id: type: string label: 'ID' + target_entity_type: + type: string + label: 'Target entity type' view_mode: type: string label: 'View mode' @@ -360,3 +363,9 @@ migrate_entity_constant: sequence: type: string label: 'Settings' + selection_handler: + type: string + label: 'Entity reference selection handler' + auto_create: + type: boolean + label: 'Entity reference selection setting: Auto-create new entities' diff --git a/core/modules/migrate_drupal/src/Tests/d6/MigrateDrupal6Test.php b/core/modules/migrate_drupal/src/Tests/d6/MigrateDrupal6Test.php index 7bdc93be3dfd2a7891d985bf1ff3edf0e282e8f6..a644a9923e9a5779d05cc05221505e4db862909e 100644 --- a/core/modules/migrate_drupal/src/Tests/d6/MigrateDrupal6Test.php +++ b/core/modules/migrate_drupal/src/Tests/d6/MigrateDrupal6Test.php @@ -31,6 +31,7 @@ class MigrateDrupal6Test extends MigrateFullDrupalTestBase { 'block_content', 'datetime', 'dblog', + 'entity_reference', 'file', 'forum', 'image', diff --git a/core/modules/migrate_drupal/src/Tests/d6/MigrateTermNodeTestBase.php b/core/modules/migrate_drupal/src/Tests/d6/MigrateTermNodeTestBase.php index 753b0f8466f62429a87759a1f7a4968dbfc0a2b8..2dd8890ae1ad9e3be0fb0dcd02ff981b06fa9a32 100644 --- a/core/modules/migrate_drupal/src/Tests/d6/MigrateTermNodeTestBase.php +++ b/core/modules/migrate_drupal/src/Tests/d6/MigrateTermNodeTestBase.php @@ -7,13 +7,16 @@ namespace Drupal\migrate_drupal\Tests\d6; -use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase; +use Drupal\Core\Field\FieldStorageDefinitionInterface; +use Drupal\entity_reference\Tests\EntityReferenceTestTrait; /** * Base class for Taxonomy/Node migration tests. */ abstract class MigrateTermNodeTestBase extends MigrateDrupal6TestBase { + use EntityReferenceTestTrait; + /** * {@inheritdoc} */ @@ -31,26 +34,13 @@ protected function setUp() { $node_type = entity_create('node_type', array('type' => 'story')); $node_type->save(); foreach (array('vocabulary_1_i_0_', 'vocabulary_2_i_1_', 'vocabulary_3_i_2_') as $name) { - entity_create('field_storage_config', array( - 'field_name' => $name, - 'entity_type' => 'node', - 'type' => 'taxonomy_term_reference', - 'cardinality' => -1, - 'settings' => array( - 'allowed_values' => array( - array( - 'vocabulary' => $vocabulary->id(), - 'parent' => '0', - ), - ), + $handler_settings = array( + 'target_bundles' => array( + $vocabulary->id() => $vocabulary->id(), ), - ))->save(); - entity_create('field_config', array( - 'field_name' => $name, - 'entity_type' => 'node', - 'bundle' => 'story', - ))->save(); - + 'auto_create' => TRUE, + ); + $this->createEntityReferenceField('node', 'story', $name, NULL, 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); } $id_mappings = array( 'd6_vocabulary_field_instance' => array( diff --git a/core/modules/migrate_drupal/src/Tests/d6/MigrateVocabularyEntityDisplayTest.php b/core/modules/migrate_drupal/src/Tests/d6/MigrateVocabularyEntityDisplayTest.php index dfff824f4c38287ca3f461fd3553011d419368d8..f250ba0c0fecc36f085f41cdf2b84bde064ae1f3 100644 --- a/core/modules/migrate_drupal/src/Tests/d6/MigrateVocabularyEntityDisplayTest.php +++ b/core/modules/migrate_drupal/src/Tests/d6/MigrateVocabularyEntityDisplayTest.php @@ -33,7 +33,10 @@ protected function setUp() { entity_create('field_storage_config', array( 'entity_type' => 'node', 'field_name' => 'tags', - 'type' => 'taxonomy_term_reference', + 'type' => 'entity_reference', + 'settings' => array( + 'target_type' => 'taxonomy_term', + ), ))->save(); foreach (array('page', 'article', 'story') as $type) { @@ -45,6 +48,15 @@ protected function setUp() { 'entity_type' => 'node', 'bundle' => $type, 'required' => 1, + 'settings' => array( + 'handler' => 'default', + 'handler_settings' => array( + 'target_bundles' => array( + 'tags' => 'tags', + ), + 'auto_create' => TRUE, + ), + ), ))->save(); } @@ -75,7 +87,7 @@ protected function setUp() { public function testVocabularyEntityDisplay() { // Test that the field exists. $component = entity_get_display('node', 'page', 'default')->getComponent('tags'); - $this->assertIdentical('taxonomy_term_reference_link', $component['type']); + $this->assertIdentical('entity_reference_label', $component['type']); $this->assertIdentical(20, $component['weight']); // Test the Id map. $this->assertIdentical(array('node', 'article', 'default', 'tags'), entity_load('migration', 'd6_vocabulary_entity_display')->getIdMap()->lookupDestinationID(array(4, 'article'))); diff --git a/core/modules/migrate_drupal/src/Tests/d6/MigrateVocabularyEntityFormDisplayTest.php b/core/modules/migrate_drupal/src/Tests/d6/MigrateVocabularyEntityFormDisplayTest.php index eadfabe1b44054ab372c9c8d12e615852e22e8fc..cbbab33ebd51d2f55b9709413b006407be45cdd1 100644 --- a/core/modules/migrate_drupal/src/Tests/d6/MigrateVocabularyEntityFormDisplayTest.php +++ b/core/modules/migrate_drupal/src/Tests/d6/MigrateVocabularyEntityFormDisplayTest.php @@ -33,7 +33,10 @@ protected function setUp() { entity_create('field_storage_config', array( 'entity_type' => 'node', 'field_name' => 'tags', - 'type' => 'taxonomy_term_reference', + 'type' => 'entity_reference', + 'settings' => array( + 'target_type' => 'taxonomy_term', + ), ))->save(); foreach (array('page', 'article', 'story') as $type) { @@ -45,6 +48,15 @@ protected function setUp() { 'entity_type' => 'node', 'bundle' => $type, 'required' => 1, + 'settings' => array( + 'handler' => 'default', + 'handler_settings' => array( + 'target_bundles' => array( + 'tags' => 'tags', + ), + 'auto_create' => TRUE, + ), + ), ))->save(); } diff --git a/core/modules/migrate_drupal/src/Tests/d6/MigrateVocabularyFieldInstanceTest.php b/core/modules/migrate_drupal/src/Tests/d6/MigrateVocabularyFieldInstanceTest.php index 5e9d0ac819b6cee8c2bd1d7a279ad2e2e3747159..6b84d596cf5599a97818744505beef5028cc84e5 100644 --- a/core/modules/migrate_drupal/src/Tests/d6/MigrateVocabularyFieldInstanceTest.php +++ b/core/modules/migrate_drupal/src/Tests/d6/MigrateVocabularyFieldInstanceTest.php @@ -57,15 +57,10 @@ protected function setUp() { entity_create('field_storage_config', array( 'entity_type' => 'node', 'field_name' => 'tags', - 'type' => 'taxonomy_term_reference', + 'type' => 'entity_reference', 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, 'settings' => array( - 'allowed_values' => array( - array( - 'vocabulary' => 'tags', - 'parent' => 0, - ), - ), + 'target_type' => 'taxonomy_term', ), ))->save(); @@ -93,6 +88,11 @@ public function testVocabularyFieldInstance() { $field = FieldConfig::load($field_id); $this->assertIdentical($field_id, $field->id(), 'Field instance exists on page bundle.'); + $settings = $field->getSettings(); + $this->assertIdentical('default:taxonomy_term', $settings['handler'], 'The handler plugin ID is correct.'); + $this->assertIdentical(['tags'], $settings['handler_settings']['target_bundles'], 'The target_bundle handler setting is correct.'); + $this->assertIdentical(TRUE, $settings['handler_settings']['auto_create'], 'The "auto_create" setting is correct.'); + $this->assertIdentical(array('node', 'article', 'tags'), entity_load('migration', 'd6_vocabulary_field_instance')->getIdMap()->lookupDestinationID(array(4, 'article'))); } diff --git a/core/modules/migrate_drupal/src/Tests/d6/MigrateVocabularyFieldTest.php b/core/modules/migrate_drupal/src/Tests/d6/MigrateVocabularyFieldTest.php index 4b03f6f7771948e2c0869b3fa84fce66f56a7b95..6fdfd458fd15652e5f9675c81e2b1d1a395ebc99 100644 --- a/core/modules/migrate_drupal/src/Tests/d6/MigrateVocabularyFieldTest.php +++ b/core/modules/migrate_drupal/src/Tests/d6/MigrateVocabularyFieldTest.php @@ -63,8 +63,10 @@ public function testVocabularyField() { $field_storage_id = 'node.tags'; $field_storage = FieldStorageConfig::load($field_storage_id); $this->assertIdentical($field_storage_id, $field_storage->id()); + $settings = $field_storage->getSettings(); - $this->assertIdentical($settings['allowed_values'][0]['vocabulary'], 'tags', "Vocabulary has correct settings."); + $this->assertIdentical('taxonomy_term', $settings['target_type'], "Target type is correct."); + $this->assertIdentical(array('node', 'tags'), entity_load('migration', 'd6_vocabulary_field')->getIdMap()->lookupDestinationID(array(4)), "Test IdMap"); } diff --git a/core/modules/node/src/Plugin/views/wizard/Node.php b/core/modules/node/src/Plugin/views/wizard/Node.php index 8271f35a9b4f23c3841d04e43cbe5dd240840e7d..deda7fe2ac8a482eb2ce089c4f49a8b467d00295 100644 --- a/core/modules/node/src/Plugin/views/wizard/Node.php +++ b/core/modules/node/src/Plugin/views/wizard/Node.php @@ -8,7 +8,6 @@ namespace Drupal\node\Plugin\views\wizard; use Drupal\Core\Form\FormStateInterface; -use Drupal\field\Entity\FieldStorageConfig; use Drupal\views\Plugin\views\wizard\WizardPluginBase; /** @@ -121,7 +120,7 @@ protected function defaultDisplayFiltersUser(array $form, FormStateInterface $fo } } if (!empty($tids)) { - $vid = $form['displays']['show']['tagged_with']['#selection_settings']['target_bundles'][0]; + $vid = reset($form['displays']['show']['tagged_with']['#selection_settings']['target_bundles']); $filters['tid'] = array( 'id' => 'tid', 'table' => 'taxonomy_index', @@ -229,18 +228,17 @@ protected function buildFilters(&$form, FormStateInterface $form_state) { foreach ($bundles as $bundle) { $display = entity_get_form_display($this->entityTypeId, $bundle, 'default'); $taxonomy_fields = array_filter(\Drupal::entityManager()->getFieldDefinitions($this->entityTypeId, $bundle), function ($field_definition) { - return $field_definition->getType() == 'taxonomy_term_reference'; + return $field_definition->getType() == 'entity_reference' && $field_definition->getSetting('target_type') == 'taxonomy_term'; }); foreach ($taxonomy_fields as $field_name => $field) { $widget = $display->getComponent($field_name); // We define "tag-like" taxonomy fields as ones that use the - // "Autocomplete term widget (tagging)" widget. - if ($widget['type'] == 'taxonomy_autocomplete') { - $tag_fields[] = $field_name; + // "Autocomplete (Tags style)" widget. + if ($widget['type'] == 'entity_reference_autocomplete_tags') { + $tag_fields[$field_name] = $field; } } } - $tag_fields = array_unique($tag_fields); if (!empty($tag_fields)) { // If there is more than one "tag-like" taxonomy field available to // the view, we can only make our filter apply to one of them (as @@ -248,14 +246,14 @@ protected function buildFilters(&$form, FormStateInterface $form_state) { // that is created by the Standard install profile in core and also // commonly used by contrib modules; thus, it is most likely to be // associated with the "main" free-tagging vocabulary on the site. - if (in_array('field_tags', $tag_fields)) { + if (array_key_exists('field_tags', $tag_fields)) { $tag_field_name = 'field_tags'; } else { - $tag_field_name = reset($tag_fields); + $tag_field_name = key($tag_fields); } // Add the autocomplete textfield to the wizard. - $target_bundles = [FieldStorageConfig::loadByName('node', $tag_field_name)->getSetting('allowed_values')[0]['vocabulary']]; + $target_bundles = $tag_fields[$tag_field_name]->getSetting('handler_settings')['target_bundles']; $form['displays']['show']['tagged_with'] = array( '#type' => 'entity_autocomplete', '#title' => $this->t('tagged with'), diff --git a/core/modules/node/src/Tests/NodeAccessBaseTableTest.php b/core/modules/node/src/Tests/NodeAccessBaseTableTest.php index 231c98bab992ad54bc3466f3d2d7b8e51e5ff02a..3ef939affce9246d83999412374a1e0b427edaab 100644 --- a/core/modules/node/src/Tests/NodeAccessBaseTableTest.php +++ b/core/modules/node/src/Tests/NodeAccessBaseTableTest.php @@ -75,11 +75,11 @@ function testNodeAccessBasic() { if ($is_private) { $edit['private[0][value]'] = TRUE; $edit['body[0][value]'] = 'private node'; - $edit['field_tags'] = 'private'; + $edit['field_tags[target_id]'] = 'private'; } else { $edit['body[0][value]'] = 'public node'; - $edit['field_tags'] = 'public'; + $edit['field_tags[target_id]'] = 'public'; } $this->drupalPostForm('node/add/article', $edit, t('Save')); diff --git a/core/modules/node/src/Tests/PagePreviewTest.php b/core/modules/node/src/Tests/PagePreviewTest.php index 13a051bc4d9451a018d0a30dd03c7a777c766729..fa387bf131a0f4d84c1d222373b5d4920cbe399c 100644 --- a/core/modules/node/src/Tests/PagePreviewTest.php +++ b/core/modules/node/src/Tests/PagePreviewTest.php @@ -7,8 +7,10 @@ namespace Drupal\node\Tests; +use Drupal\Core\Field\FieldStorageDefinitionInterface; use Drupal\Component\Utility\Unicode; use Drupal\Core\Language\LanguageInterface; +use Drupal\entity_reference\Tests\EntityReferenceTestTrait; use Drupal\node\Entity\NodeType; /** @@ -18,6 +20,8 @@ */ class PagePreviewTest extends NodeTestBase { + use EntityReferenceTestTrait; + /** * Enable the node and taxonomy modules to test both on the preview. * @@ -63,41 +67,29 @@ protected function setUp() { // Create a field. $this->field_name = Unicode::strtolower($this->randomMachineName()); - entity_create('field_storage_config', array( - 'field_name' => $this->field_name, - 'entity_type' => 'node', - 'type' => 'taxonomy_term_reference', - 'settings' => array( - 'allowed_values' => array( - array( - 'vocabulary' => $this->vocabulary->id(), - 'parent' => '0', - ), - ), + $handler_settings = array( + 'target_bundles' => array( + $this->vocabulary->id() => $this->vocabulary->id(), ), - 'cardinality' => '-1', - ))->save(); - entity_create('field_config', array( - 'field_name' => $this->field_name, - 'entity_type' => 'node', - 'bundle' => 'page', - ))->save(); + 'auto_create' => TRUE, + ); + $this->createEntityReferenceField('node', 'page', $this->field_name, 'Tags', 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); entity_get_form_display('node', 'page', 'default') ->setComponent($this->field_name, array( - 'type' => 'taxonomy_autocomplete', + 'type' => 'entity_reference_autocomplete_tags', )) ->save(); // Show on default display and teaser. entity_get_display('node', 'page', 'default') ->setComponent($this->field_name, array( - 'type' => 'taxonomy_term_reference_link', + 'type' => 'entity_reference_label', )) ->save(); entity_get_display('node', 'page', 'teaser') ->setComponent($this->field_name, array( - 'type' => 'taxonomy_term_reference_link', + 'type' => 'entity_reference_label', )) ->save(); } @@ -108,7 +100,7 @@ protected function setUp() { function testPagePreview() { $title_key = 'title[0][value]'; $body_key = 'body[0][value]'; - $term_key = $this->field_name; + $term_key = $this->field_name . '[target_id]'; // Fill in node creation form and preview node. $edit = array(); @@ -145,13 +137,13 @@ function testPagePreview() { $this->clickLink(t('Back to content editing')); $this->assertFieldByName($title_key, $edit[$title_key], 'Title field displayed.'); $this->assertFieldByName($body_key, $edit[$body_key], 'Body field displayed.'); - $this->assertFieldByName($term_key, $edit[$term_key], 'Term field displayed.'); + $this->assertFieldByName($term_key, $edit[$term_key] . ' (' . $this->term->id() . ')', 'Term field displayed.'); // Assert the content is kept when reloading the page. $this->drupalGet('node/add/page', array('query' => array('uuid' => $uuid))); $this->assertFieldByName($title_key, $edit[$title_key], 'Title field displayed.'); $this->assertFieldByName($body_key, $edit[$body_key], 'Body field displayed.'); - $this->assertFieldByName($term_key, $edit[$term_key], 'Term field displayed.'); + $this->assertFieldByName($term_key, $edit[$term_key] . ' (' . $this->term->id() . ')', 'Term field displayed.'); // Save the node. $this->drupalPostForm('node/add/page', $edit, t('Save')); @@ -163,7 +155,7 @@ function testPagePreview() { // Check the term appears again on the edit form. $this->drupalGet('node/' . $node->id() . '/edit'); - $this->assertFieldByName($term_key, $edit[$term_key], 'Term field displayed.'); + $this->assertFieldByName($term_key, $edit[$term_key] . ' (' . $this->term->id() . ')', 'Term field displayed.'); // Check with two new terms on the edit form, additionally to the existing // one. @@ -227,7 +219,7 @@ function testPagePreview() { function testPagePreviewWithRevisions() { $title_key = 'title[0][value]'; $body_key = 'body[0][value]'; - $term_key = $this->field_name; + $term_key = $this->field_name . '[target_id]'; // Force revision on "Basic page" content. $node_type = NodeType::load('page'); $node_type->setNewRevision(TRUE); diff --git a/core/modules/quickedit/src/Tests/QuickEditAutocompleteTermTest.php b/core/modules/quickedit/src/Tests/QuickEditAutocompleteTermTest.php index 3c424095f2a36ca12e8f6b9ef276574c89409bf2..467a66c8616efab0080922b28a274f0127f9143a 100644 --- a/core/modules/quickedit/src/Tests/QuickEditAutocompleteTermTest.php +++ b/core/modules/quickedit/src/Tests/QuickEditAutocompleteTermTest.php @@ -10,6 +10,7 @@ use Drupal\Component\Serialization\Json; use Drupal\Core\Field\FieldStorageDefinitionInterface; use Drupal\Core\Language\LanguageInterface; +use Drupal\entity_reference\Tests\EntityReferenceTestTrait; use Drupal\simpletest\WebTestBase; /** @@ -19,6 +20,8 @@ */ class QuickEditAutocompleteTermTest extends WebTestBase { + use EntityReferenceTestTrait; + /** * Modules to enable. * @@ -81,44 +84,31 @@ protected function setUp() { ]); $this->vocabulary->save(); $this->fieldName = 'field_' . $this->vocabulary->id(); - entity_create('field_storage_config', [ - 'field_name' => $this->fieldName, - 'entity_type' => 'node', - 'type' => 'taxonomy_term_reference', - // Set cardinality to unlimited for tagging. - 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, - 'settings' => [ - 'allowed_values' => [ - [ - 'vocabulary' => $this->vocabulary->id(), - 'parent' => 0, - ], - ], - ], - ])->save(); - entity_create('field_config', [ - 'field_name' => $this->fieldName, - 'entity_type' => 'node', - 'label' => 'Tags', - 'bundle' => 'article', - ])->save(); + + $handler_settings = array( + 'target_bundles' => array( + $this->vocabulary->id() => $this->vocabulary->id(), + ), + 'auto_create' => TRUE, + ); + $this->createEntityReferenceField('node', 'article', $this->fieldName, 'Tags', 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); entity_get_form_display('node', 'article', 'default') ->setComponent($this->fieldName, [ - 'type' => 'taxonomy_autocomplete', + 'type' => 'entity_reference_autocomplete_tags', 'weight' => -4, ]) ->save(); entity_get_display('node', 'article', 'default') ->setComponent($this->fieldName, [ - 'type' => 'taxonomy_term_reference_link', + 'type' => 'entity_reference_label', 'weight' => 10, ]) ->save(); entity_get_display('node', 'article', 'teaser') ->setComponent($this->fieldName, [ - 'type' => 'taxonomy_term_reference_link', + 'type' => 'entity_reference_label', 'weight' => 10, ]) ->save(); @@ -156,7 +146,7 @@ public function testAutocompleteQuickEdit() { 'form_id' => 'quickedit_field_form', 'form_token' => $token_match[1], 'form_build_id' => $build_id_match[1], - $this->fieldName => implode(', ', array($this->term1->getName(), 'new term', $this->term2->getName())), + $this->fieldName . '[target_id]' => implode(', ', array($this->term1->getName(), 'new term', $this->term2->getName())), 'op' => t('Save'), ); @@ -182,7 +172,12 @@ public function testAutocompleteQuickEdit() { // taxonomy terms, including the one that has just been newly created and // which is not yet stored. $this->setRawContent($ajax_commands[0]['data']); - $this->assertFieldByName($this->fieldName, implode(', ', array($this->term1->getName(), 'new term', $this->term2->label()))); + $expected = array( + $this->term1->getName() . ' (' . $this->term1->id() . ')', + 'new term', + $this->term2->getName() . ' (' . $this->term2->id() . ')', + ); + $this->assertFieldByName($this->fieldName . '[target_id]', implode(', ', $expected)); // Save the entity. $post = array('nocssjs' => 'true'); diff --git a/core/modules/rdf/src/Tests/TaxonomyTermFieldAttributesTest.php b/core/modules/rdf/src/Tests/EntityReferenceFieldAttributesTest.php similarity index 76% rename from core/modules/rdf/src/Tests/TaxonomyTermFieldAttributesTest.php rename to core/modules/rdf/src/Tests/EntityReferenceFieldAttributesTest.php index 5e698c2140a5a7fe67cfc1aa70d321a7fc170bd2..a92ed7c1b351e55067468b25eafce72da6cc1a34 100644 --- a/core/modules/rdf/src/Tests/TaxonomyTermFieldAttributesTest.php +++ b/core/modules/rdf/src/Tests/EntityReferenceFieldAttributesTest.php @@ -2,7 +2,7 @@ /** * @file - * Contains \Drupal\rdf\Tests\TaxonomyTermFieldAttributesTest. + * Contains \Drupal\rdf\Tests\EntityReferenceFieldAttributesTest. */ namespace Drupal\rdf\Tests; @@ -15,7 +15,7 @@ * * @group rdf */ -class TaxonomyTermFieldAttributesTest extends TaxonomyTestBase { +class EntityReferenceFieldAttributesTest extends TaxonomyTestBase { /** * Modules to enable. @@ -47,7 +47,20 @@ protected function setUp() { // Create the field. $this->fieldName = 'field_taxonomy_test'; - $this->createTaxonomyTermReferenceField($this->fieldName, $this->vocabulary); + $handler_settings = array( + 'target_bundles' => array( + $this->vocabulary->id() => $this->vocabulary->id(), + ), + 'auto_create' => TRUE, + ); + $this->createEntityReferenceField('node', 'article', $this->fieldName, 'Tags', 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); + + entity_get_form_display('node', 'article', 'default') + ->setComponent($this->fieldName, array('type' => 'options_select')) + ->save(); + entity_get_display('node', 'article', 'full') + ->setComponent($this->fieldName, array('type' => 'entity_reference_label')) + ->save(); // Set the RDF mapping for the new field. rdf_get_mapping('node', 'article') @@ -72,7 +85,7 @@ protected function setUp() { function testNodeTeaser() { // Set the teaser display to show this field. entity_get_display('node', 'article', 'teaser') - ->setComponent($this->fieldName, array('type' => 'taxonomy_term_reference_link')) + ->setComponent($this->fieldName, array('type' => 'entity_reference_label')) ->save(); // Create a term in each vocabulary. @@ -136,42 +149,4 @@ function testNodeTeaser() { //$this->assertTrue($graph->hasProperty($taxonomy_term_2_uri, 'http://www.w3.org/2000/01/rdf-schema#label', $expected_value), 'Taxonomy term name found in RDF output (rdfs:label).'); } - /** - * Create the taxonomy term reference field for testing. - * - * @param string $field_name - * The name of the field to create. - * @param \Drupal\taxonomy\Entity\Vocabulary $vocabulary - * The vocabulary that the field should use. - * - * @todo Move this to TaxonomyTestBase, like the other field modules. - */ - protected function createTaxonomyTermReferenceField($field_name, $vocabulary) { - entity_create('field_storage_config', array( - 'field_name' => $field_name, - 'entity_type' => 'node', - 'type' => 'taxonomy_term_reference', - 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, - 'settings' => array( - 'allowed_values' => array( - array( - 'vocabulary' => $vocabulary->id(), - 'parent' => '0', - ), - ), - ), - ))->save(); - entity_create('field_config', array( - 'field_name' => $field_name, - 'entity_type' => 'node', - 'bundle' => 'article', - ))->save(); - entity_get_form_display('node', 'article', 'default') - ->setComponent($field_name, array('type' => 'options_select')) - ->save(); - entity_get_display('node', 'article', 'full') - ->setComponent($field_name, array('type' => 'taxonomy_term_reference_link')) - ->save(); - } - } diff --git a/core/modules/rdf/src/Tests/Field/TaxonomyTermReferenceRdfaTest.php b/core/modules/rdf/src/Tests/Field/TaxonomyTermReferenceRdfaTest.php deleted file mode 100644 index e90314b83f3c3f5206aa25e0ae391b6867ad5755..0000000000000000000000000000000000000000 --- a/core/modules/rdf/src/Tests/Field/TaxonomyTermReferenceRdfaTest.php +++ /dev/null @@ -1,113 +0,0 @@ -installEntitySchema('taxonomy_term'); - - $vocabulary = entity_create('taxonomy_vocabulary', array( - 'name' => $this->randomMachineName(), - 'vid' => Unicode::strtolower($this->randomMachineName()), - 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED, - )); - $vocabulary->save(); - - entity_create('field_storage_config', array( - 'field_name' => $this->fieldName, - 'entity_type' => 'entity_test', - 'type' => 'taxonomy_term_reference', - 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, - 'settings' => array( - 'allowed_values' => array( - array( - 'vocabulary' => $vocabulary->id(), - 'parent' => 0, - ), - ), - ), - ))->save(); - entity_create('field_config', array( - 'entity_type' => 'entity_test', - 'field_name' => $this->fieldName, - 'bundle' => 'entity_test', - ))->save(); - - $this->term = entity_create('taxonomy_term', array( - 'name' => $this->randomMachineName(), - 'vid' => $vocabulary->id(), - 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED, - )); - $this->term->save(); - - // Add the mapping. - $mapping = rdf_get_mapping('entity_test', 'entity_test'); - $mapping->setFieldMapping($this->fieldName, array( - 'properties' => array('schema:about'), - ))->save(); - - // Set up test values. - $this->entity = entity_create('entity_test'); - $this->entity->{$this->fieldName}->target_id = $this->term->id(); - $this->entity->save(); - $this->uri = $this->getAbsoluteUri($this->entity); - } - - /** - * Tests the plain formatter. - */ - public function testAllFormatters() { - // Tests the plain formatter. - $this->assertFormatterRdfa(array('type' => 'taxonomy_term_reference_plain'), 'http://schema.org/about', array('value' => $this->term->getName(), 'type' => 'literal')); - // Grant the access content permission to the anonymous user. - Role::create(array('id' => RoleInterface::ANONYMOUS_ID)) - ->grantPermission('access content') - ->save(); - // Tests the link formatter. - $term_uri = $this->getAbsoluteUri($this->term); - $this->assertFormatterRdfa(array('type'=>'taxonomy_term_reference_link'), 'http://schema.org/about', array('value' => $term_uri, 'type' => 'uri')); - } - -} diff --git a/core/modules/system/src/Tests/Entity/EntityQueryRelationshipTest.php b/core/modules/system/src/Tests/Entity/EntityQueryRelationshipTest.php index 681ebaad506e884803e45ba9b1d31dbf7a4d1de5..89bc9dab2b83b0f3811b14afa63e7259ebcc7550 100644 --- a/core/modules/system/src/Tests/Entity/EntityQueryRelationshipTest.php +++ b/core/modules/system/src/Tests/Entity/EntityQueryRelationshipTest.php @@ -7,6 +7,7 @@ namespace Drupal\system\Tests\Entity; use Drupal\Component\Utility\Unicode; +use Drupal\entity_reference\Tests\EntityReferenceTestTrait; /** * Tests the Entity Query relationship API. @@ -15,6 +16,8 @@ */ class EntityQueryRelationshipTest extends EntityUnitTestBase { + use EntityReferenceTestTrait; + /** * Modules to enable. * @@ -67,33 +70,24 @@ protected function setUp() { $this->installEntitySchema('taxonomy_term'); - // We want a taxonomy term reference field. It needs a vocabulary, terms, - // a field storage and a field. First, create the vocabulary. + // We want an entity reference field. It needs a vocabulary, terms, a field + // storage and a field. First, create the vocabulary. $vocabulary = entity_create('taxonomy_vocabulary', array( 'vid' => Unicode::strtolower($this->randomMachineName()), )); $vocabulary->save(); + // Second, create the field. - $this->fieldName = strtolower($this->randomMachineName()); - entity_create('field_storage_config', array( - 'field_name' => $this->fieldName, - 'entity_type' => 'entity_test', - 'type' => 'taxonomy_term_reference', - 'settings' => array( - 'allowed_values' => array( - array( - 'vocabulary' => $vocabulary->id(), - ), - ), - ), - ))->save(); entity_test_create_bundle('test_bundle'); - // Third, create the instance. - entity_create('field_config', array( - 'entity_type' => 'entity_test', - 'field_name' => $this->fieldName, - 'bundle' => 'test_bundle', - ))->save(); + $this->fieldName = strtolower($this->randomMachineName()); + $handler_settings = array( + 'target_bundles' => array( + $vocabulary->id() => $vocabulary->id(), + ), + 'auto_create' => TRUE, + ); + $this->createEntityReferenceField('entity_test', 'test_bundle', $this->fieldName, NULL, 'taxonomy_term', 'default', $handler_settings); + // Create two terms and also two accounts. for ($i = 0; $i <= 1; $i++) { $term = entity_create('taxonomy_term', array( diff --git a/core/modules/system/src/Tests/Menu/BreadcrumbTest.php b/core/modules/system/src/Tests/Menu/BreadcrumbTest.php index 0ae13995a0acd4124d933488f09f259cce081de5..96d627780d7fdbcf3b1c0ca368244ade61b9d1f5 100644 --- a/core/modules/system/src/Tests/Menu/BreadcrumbTest.php +++ b/core/modules/system/src/Tests/Menu/BreadcrumbTest.php @@ -216,7 +216,7 @@ function testBreadCrumbs() { 'Breadcrumbs' => array(), ); $edit = array( - 'field_tags' => implode(',', array_keys($tags)), + 'field_tags[target_id]' => implode(',', array_keys($tags)), ); $this->drupalPostForm('node/' . $parent->id() . '/edit', $edit, t('Save and keep published')); diff --git a/core/modules/taxonomy/config/schema/taxonomy.schema.yml b/core/modules/taxonomy/config/schema/taxonomy.schema.yml index 25124f734177d48a79db5b1a1e75ba98ee4b13cf..ef56111625be5bfdc68ed25e652bfcf8f29a5ddb 100644 --- a/core/modules/taxonomy/config/schema/taxonomy.schema.yml +++ b/core/modules/taxonomy/config/schema/taxonomy.schema.yml @@ -34,72 +34,6 @@ taxonomy.vocabulary.*: type: integer label: 'Weight' -field.storage_settings.taxonomy_term_reference: - type: base_entity_reference_field_settings - label: 'Taxonomy term reference settings' - mapping: - options_list_callback: - type: string - label: 'Options list callback' - allowed_values: - type: sequence - label: 'Allowed values' - sequence: - type: mapping - label: 'Allowed values' - mapping: - vocabulary: - type: string - label: 'Vocabulary' - parent: - type: integer - value: 'Parent' - -field.field_settings.taxonomy_term_reference: - type: mapping - label: 'Taxonomy term reference settings' - mapping: - handler: - type: string - label: 'Reference method' - handler_settings: - type: entity_reference_selection.[%parent.handler] - label: 'Entity reference selection settings' - -field.value.taxonomy_term_reference: - type: mapping - label: 'Default value' - mapping: - target_id: - type: integer - label: 'Term ID' - field.formatter.settings.entity_reference_rss_category: type: mapping label: 'Taxonomy format settings' - -field.formatter.settings.taxonomy_term_reference_plain: - type: mapping - label: 'Taxonomy format settings' - -field.formatter.settings.taxonomy_term_reference_rss_category: - type: mapping - label: 'Taxonomy format settings' - -field.formatter.settings.taxonomy_term_reference_link: - type: mapping - label: 'Taxonomy format settings' - -field.widget.settings.taxonomy_autocomplete: - type: mapping - label: 'Autocomplete term widget (tagging) format settings' - mapping: - size: - type: integer - label: 'Size' - autocomplete_route_name: - type: string - label: 'Autocomplete route name' - placeholder: - type: label - label: 'Placeholder' diff --git a/core/modules/taxonomy/src/Controller/TermAutocompleteController.php b/core/modules/taxonomy/src/Controller/TermAutocompleteController.php deleted file mode 100644 index 08a01fc2e787d6be53058ea59de802059028a4ee..0000000000000000000000000000000000000000 --- a/core/modules/taxonomy/src/Controller/TermAutocompleteController.php +++ /dev/null @@ -1,171 +0,0 @@ -termEntityQuery = $term_entity_query; - $this->entityManager = $entity_manager; - } - - /** - * {@inheritdoc} - */ - public static function create(ContainerInterface $container) { - return new static( - $container->get('entity.query')->get('taxonomy_term'), - $container->get('entity.manager') - ); - } - - /** - * Retrieves suggestions for taxonomy term autocompletion. - * - * This function outputs term name suggestions in response to Ajax requests - * made by the taxonomy autocomplete widget for taxonomy term reference - * fields. The output is a JSON object of plain-text term suggestions, keyed - * by the user-entered value with the completed term name appended. - * Term names containing commas are wrapped in quotes. - * - * For example, suppose the user has entered the string 'red fish, blue' in - * the field, and there are two taxonomy terms, 'blue fish' and 'blue moon'. - * The JSON output would have the following structure: - * @code - * { - * "red fish, blue fish": "blue fish", - * "red fish, blue moon": "blue moon", - * }; - * @endcode - * - * @param \Symfony\Component\HttpFoundation\Request $request - * The request object. - * @param string $entity_type - * The entity_type. - * @param string $field_name - * The name of the term reference field. - * - * @return \Symfony\Component\HttpFoundation\JsonResponse|\Symfony\Component\HttpFoundation\Response - * When valid field name is specified, a JSON response containing the - * autocomplete suggestions for taxonomy terms. Otherwise a normal response - * containing an error message. - */ - public function autocomplete(Request $request, $entity_type, $field_name) { - // A comma-separated list of term names entered in the autocomplete form - // element. Only the last term is used for autocompletion. - $tags_typed = $request->query->get('q'); - - // Make sure the field exists and is a taxonomy field. - $field_storage_definitions = $this->entityManager->getFieldStorageDefinitions($entity_type); - - if (!isset($field_storage_definitions[$field_name]) || $field_storage_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_storage = $field_storage_definitions[$field_name]; - - // The user enters a comma-separated list of tags. We only autocomplete the - // last tag. - $tags_typed = Tags::explode($tags_typed); - $tag_last = Unicode::strtolower(array_pop($tags_typed)); - - $matches = array(); - if ($tag_last != '') { - - // Part of the criteria for the query come from the field's own settings. - $vids = array(); - foreach ($field_storage->getSetting('allowed_values') as $tree) { - $vids[] = $tree['vocabulary']; - } - - $matches = $this->getMatchingTerms($tags_typed, $vids, $tag_last); - } - - return new JsonResponse($matches); - } - - /** - * Gets terms which matches some typed terms. - * - * @param string $tags_typed - * The full typed tags string. - * @param array $vids - * An array of vocabulary IDs which - * @param $tag_last - * The lasted typed tag. - * - * @return array - * Returns an array of matching terms. - */ - protected function getMatchingTerms($tags_typed, array $vids, $tag_last) { - $matches = array(); - $this->termEntityQuery->addTag('term_access'); - - // Do not select already entered terms. - if (!empty($tags_typed)) { - $this->termEntityQuery->condition('name', $tags_typed, 'NOT IN'); - } - // Select rows that match by term name. - $tids = $this->termEntityQuery - ->condition('vid', $vids, 'IN') - ->condition('name', $tag_last, 'CONTAINS') - ->range(0, 10) - ->execute(); - - $prefix = count($tags_typed) ? Tags::implode($tags_typed) . ', ' : ''; - if (!empty($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()); - $matches[] = array('value' => $prefix . $name, 'label' => String::checkPlain($term->getName())); - } - return $matches; - } - return $matches; - } - -} diff --git a/core/modules/taxonomy/src/Entity/Term.php b/core/modules/taxonomy/src/Entity/Term.php index 7a1cc5f8871234ddda18d0c00dfabca98846e819..7ca9dd7a647fdc0dd14f071203bf3b219a53a994 100644 --- a/core/modules/taxonomy/src/Entity/Term.php +++ b/core/modules/taxonomy/src/Entity/Term.php @@ -45,6 +45,7 @@ * }, * bundle_entity_type = "taxonomy_vocabulary", * field_ui_base_route = "entity.taxonomy_vocabulary.overview_form", + * common_reference_target = TRUE, * links = { * "canonical" = "/taxonomy/term/{taxonomy_term}", * "delete-form" = "/taxonomy/term/{taxonomy_term}/delete", diff --git a/core/modules/taxonomy/src/Entity/Vocabulary.php b/core/modules/taxonomy/src/Entity/Vocabulary.php index b8edfde693ba540b8e71103a9311f72843a6665a..7b2def3c478b6fa51e215a20b4e2104880fdd659 100644 --- a/core/modules/taxonomy/src/Entity/Vocabulary.php +++ b/core/modules/taxonomy/src/Entity/Vocabulary.php @@ -125,7 +125,7 @@ public function postSave(EntityStorageInterface $storage, $update = TRUE) { // Reflect machine name changes in the definitions of existing 'taxonomy' // fields. $field_ids = array(); - $field_map = \Drupal::entityManager()->getFieldMapByFieldType('taxonomy_term_reference'); + $field_map = \Drupal::entityManager()->getFieldMapByFieldType('entity_reference'); foreach ($field_map as $entity_type => $field_storages) { foreach ($field_storages as $field_storage => $info) { $field_ids[] = $entity_type . '.' . $field_storage; @@ -133,8 +133,11 @@ public function postSave(EntityStorageInterface $storage, $update = TRUE) { } $field_storages = \Drupal::entityManager()->getStorage('field_storage_config')->loadMultiple($field_ids); + $taxonomy_fields = array_filter($field_storages, function ($field_storage) { + return $field_storage->getType() == 'entity_reference' && $field_storage->getSetting('target_type') == 'taxonomy_term'; + }); - foreach ($field_storages as $field_storage) { + foreach ($taxonomy_fields as $field_storage) { $update_storage = FALSE; $allowed_values = $field_storage->getSetting('allowed_values'); diff --git a/core/modules/taxonomy/src/Plugin/Field/FieldFormatter/EntityReferenceTaxonomyTermRssFormatter.php b/core/modules/taxonomy/src/Plugin/Field/FieldFormatter/EntityReferenceTaxonomyTermRssFormatter.php index 9f062a9ccfbad6267115b0311209c29db059ac10..614f165c6cc220f78b7d097571c6d74fdbe138cf 100644 --- a/core/modules/taxonomy/src/Plugin/Field/FieldFormatter/EntityReferenceTaxonomyTermRssFormatter.php +++ b/core/modules/taxonomy/src/Plugin/Field/FieldFormatter/EntityReferenceTaxonomyTermRssFormatter.php @@ -29,10 +29,11 @@ class EntityReferenceTaxonomyTermRssFormatter extends EntityReferenceFormatterBa * {@inheritdoc} */ public function viewElements(FieldItemListInterface $items) { + $parent_entity = $items->getEntity(); $elements = array(); foreach ($this->getEntitiesToView($items) as $delta => $entity) { - $entity->rss_elements[] = array( + $parent_entity->rss_elements[] = array( 'key' => 'category', 'value' => $entity->label(), 'attributes' => array( diff --git a/core/modules/taxonomy/src/Plugin/Field/FieldFormatter/LinkFormatter.php b/core/modules/taxonomy/src/Plugin/Field/FieldFormatter/LinkFormatter.php deleted file mode 100644 index d94e2bfa8a82b600daae3f089b435cc1db1da584..0000000000000000000000000000000000000000 --- a/core/modules/taxonomy/src/Plugin/Field/FieldFormatter/LinkFormatter.php +++ /dev/null @@ -1,66 +0,0 @@ - $item) { - if ($item->hasNewEntity()) { - $elements[$delta] = array( - '#markup' => String::checkPlain($item->entity->label()), - ); - } - else { - /** @var $term \Drupal\taxonomy\TermInterface */ - $term = $item->entity; - $elements[$delta] = array( - '#type' => 'link', - '#title' => $term->getName(), - '#url' => $term->urlInfo(), - ); - - if (!empty($item->_attributes)) { - $options = $elements[$delta]['#url']->getOptions(); - $options += ['attributes' => []]; - $options['attributes'] += $item->_attributes; - $elements[$delta]['#url']->setOptions($options); - // Unset field item attributes since they have been included in the - // formatter output and should not be rendered in the field template. - unset($item->_attributes); - } - - $elements[$delta]['#cache']['tags'] = $item->entity->getCacheTags(); - } - } - - return $elements; - } - -} diff --git a/core/modules/taxonomy/src/Plugin/Field/FieldFormatter/PlainFormatter.php b/core/modules/taxonomy/src/Plugin/Field/FieldFormatter/PlainFormatter.php deleted file mode 100644 index 1bf4ab4790c40fdce7b8d34af4d64c950870c225..0000000000000000000000000000000000000000 --- a/core/modules/taxonomy/src/Plugin/Field/FieldFormatter/PlainFormatter.php +++ /dev/null @@ -1,41 +0,0 @@ - $item) { - $elements[$delta] = array( - '#markup' => String::checkPlain($item->entity->label()), - ); - } - - return $elements; - } - -} diff --git a/core/modules/taxonomy/src/Plugin/Field/FieldFormatter/RSSCategoryFormatter.php b/core/modules/taxonomy/src/Plugin/Field/FieldFormatter/RSSCategoryFormatter.php deleted file mode 100644 index 927370d282cd00af0aca5fc9fdf6616abd0bebf3..0000000000000000000000000000000000000000 --- a/core/modules/taxonomy/src/Plugin/Field/FieldFormatter/RSSCategoryFormatter.php +++ /dev/null @@ -1,53 +0,0 @@ -getEntity(); - - // Terms whose target_id is 'autocreate' do not exist yet and - // $item->entity is not set. Theme such terms as just their name. - foreach ($items as $item) { - if ($item->target_id) { - $value = $item->entity->label(); - - $domain = $item->entity->url('canonical', array('absolute' => TRUE)); - } - else { - $value = $item->entity->label(); - $domain = ''; - } - $entity->rss_elements[] = array( - 'key' => 'category', - 'value' => $value, - 'attributes' => array( - 'domain' => $domain, - ), - ); - } - } - -} diff --git a/core/modules/taxonomy/src/Plugin/Field/FieldFormatter/TaxonomyFormatterBase.php b/core/modules/taxonomy/src/Plugin/Field/FieldFormatter/TaxonomyFormatterBase.php deleted file mode 100644 index 610967439f2c01a1839e5b20d4e967589d3ba3a2..0000000000000000000000000000000000000000 --- a/core/modules/taxonomy/src/Plugin/Field/FieldFormatter/TaxonomyFormatterBase.php +++ /dev/null @@ -1,76 +0,0 @@ -getEntity(); - $active_langcode = $parent->language()->getId(); - /* @var \Drupal\taxonomy\Entity\Term $term */ - foreach ($items->referencedEntities() as $term) { - if ($term->hasTranslation($active_langcode)) { - $translated_term = $term->getTranslation($active_langcode); - if ($translated_term->access('view')) { - $term = $translated_term; - } - } - if (!$term->isNew()) { - $terms[$term->id()] = $term; - } - } - } - if ($terms) { - // Iterate through the fieldable entities again to attach the loaded term - // data. - foreach ($entities_items as $items) { - $rekey = FALSE; - - foreach ($items as $item) { - // Check whether the taxonomy term field value could be loaded. - if (isset($terms[$item->target_id])) { - // Replace the instance value with the term data. - $item->entity = $terms[$item->target_id]; - } - // Terms to be created are not in $terms, but are still legitimate. - elseif ($item->hasNewEntity()) { - // Leave the item in place. - } - // Otherwise, unset the instance value, since the term does not exist. - else { - $item->setValue(NULL); - $rekey = TRUE; - } - } - - // Rekey the items array if needed. - if ($rekey) { - $items->filterEmptyItems(); - } - } - } - } - -} diff --git a/core/modules/taxonomy/src/Plugin/Field/FieldType/TaxonomyTermReferenceItem.php b/core/modules/taxonomy/src/Plugin/Field/FieldType/TaxonomyTermReferenceItem.php deleted file mode 100644 index 48fb389d4fdf021b7fd4fedc01ee54d71bddc087..0000000000000000000000000000000000000000 --- a/core/modules/taxonomy/src/Plugin/Field/FieldType/TaxonomyTermReferenceItem.php +++ /dev/null @@ -1,171 +0,0 @@ - 'taxonomy_term', - 'options_list_callback' => NULL, - 'allowed_values' => array( - array( - 'vocabulary' => '', - 'parent' => 0, - ), - ), - ) + parent::defaultStorageSettings(); - } - - /** - * {@inheritdoc} - */ - public static function defaultFieldSettings() { - return array( - 'handler' => 'default:taxonomy_term', - ) + parent::defaultFieldSettings(); - } - - /** - * {@inheritdoc} - */ - public function getPossibleValues(AccountInterface $account = NULL) { - // Flatten options firstly, because Possible Options may contain group - // arrays. - $flatten_options = OptGroup::flattenOptions($this->getPossibleOptions($account)); - return array_keys($flatten_options); - } - - /** - * {@inheritdoc} - */ - public function getPossibleOptions(AccountInterface $account = NULL) { - return $this->getSettableOptions($account); - } - - /** - * {@inheritdoc} - */ - public function getSettableValues(AccountInterface $account = NULL) { - // Flatten options firstly, because Settable Options may contain group - // arrays. - $values = array_keys(OptGroup::flattenOptions($this->getSettableOptions($account))); - $values[] = static::$NEW_ENTITY_MARKER; - return $values; - } - - /** - * {@inheritdoc} - */ - public function getSettableOptions(AccountInterface $account = NULL) { - if ($callback = $this->getSetting('options_list_callback')) { - return call_user_func_array($callback, array($this->getFieldDefinition(), $this->getEntity())); - } - else { - $options = array(); - foreach ($this->getSetting('allowed_values') as $tree) { - if ($vocabulary = Vocabulary::load($tree['vocabulary'])) { - if ($terms = taxonomy_get_tree($vocabulary->id(), $tree['parent'], NULL, TRUE)) { - foreach ($terms as $term) { - $options[$term->id()] = str_repeat('-', $term->depth) . $term->getName(); - } - } - } - } - return $options; - } - } - - /** - * {@inheritdoc} - */ - public static function schema(FieldStorageDefinitionInterface $field_definition) { - return array( - 'columns' => array( - 'target_id' => array( - 'type' => 'int', - 'unsigned' => TRUE, - ), - ), - 'indexes' => array( - 'target_id' => array('target_id'), - ), - 'foreign keys' => array( - 'target_id' => array( - 'table' => 'taxonomy_term_data', - 'columns' => array('target_id' => 'tid'), - ), - ), - ); - } - - /** - * {@inheritdoc} - */ - public function storageSettingsForm(array &$form, FormStateInterface $form_state, $has_data) { - $vocabularies = Vocabulary::loadMultiple(); - $options = array(); - foreach ($vocabularies as $vocabulary) { - $options[$vocabulary->id()] = $vocabulary->label(); - } - - $element = array(); - $element['#tree'] = TRUE; - - foreach ($this->getSetting('allowed_values') as $delta => $tree) { - $element['allowed_values'][$delta]['vocabulary'] = array( - '#type' => 'select', - '#title' => t('Vocabulary'), - '#default_value' => $tree['vocabulary'], - '#options' => $options, - '#required' => TRUE, - '#description' => t('The vocabulary which supplies the options for this field.'), - '#disabled' => $has_data, - ); - $element['allowed_values'][$delta]['parent'] = array( - '#type' => 'value', - '#value' => $tree['parent'], - ); - } - - return $element; - } - - /** - * {@inheritdoc} - */ - public function fieldSettingsForm(array $form, FormStateInterface $form_state) { - return array(); - } - -} diff --git a/core/modules/taxonomy/src/Plugin/Field/FieldWidget/TaxonomyAutocompleteWidget.php b/core/modules/taxonomy/src/Plugin/Field/FieldWidget/TaxonomyAutocompleteWidget.php deleted file mode 100644 index 8182b440d9c92848d9e30fdce7d8e83a899f6eef..0000000000000000000000000000000000000000 --- a/core/modules/taxonomy/src/Plugin/Field/FieldWidget/TaxonomyAutocompleteWidget.php +++ /dev/null @@ -1,176 +0,0 @@ -termStorage = $term_storage; - $this->vocabularyStorage = $vocabulary_storage; - } - - /** - * {@inheritdoc} - */ - public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { - return new static( - $plugin_id, - $plugin_definition, - $configuration['field_definition'], - $configuration['settings'], - $configuration['third_party_settings'], - $container->get('entity.manager')->getStorage('taxonomy_term'), - $container->get('entity.manager')->getStorage('taxonomy_vocabulary') - ); - } - - /** - * {@inheritdoc} - */ - public static function defaultSettings() { - return array( - 'size' => '60', - 'autocomplete_route_name' => 'taxonomy.autocomplete', - 'placeholder' => '', - ) + parent::defaultSettings(); - } - - /** - * {@inheritdoc} - */ - public function settingsForm(array $form, FormStateInterface $form_state) { - $element['placeholder'] = array( - '#type' => 'textfield', - '#title' => t('Placeholder'), - '#default_value' => $this->getSetting('placeholder'), - '#description' => t('Text that will be shown inside the field until a value is entered. This hint is usually a sample value or a brief description of the expected format.'), - ); - return $element; - } - - /** - * {@inheritdoc} - */ - public function settingsSummary() { - $summary = array(); - - $summary[] = t('Textfield size: !size', array('!size' => $this->getSetting('size'))); - $placeholder = $this->getSetting('placeholder'); - if (!empty($placeholder)) { - $summary[] = t('Placeholder: @placeholder', array('@placeholder' => $placeholder)); - } - else { - $summary[] = t('No placeholder'); - } - - return $summary; - } - - /** - * {@inheritdoc} - */ - public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) { - $tags = array(); - if (!$items->isEmpty()) { - foreach ($items as $item) { - $tags[] = isset($item->entity) ? $item->entity : $this->termStorage->load($item->target_id); - } - } - $element += array( - '#type' => 'textfield', - '#default_value' => taxonomy_implode_tags($tags), - '#autocomplete_route_name' => $this->getSetting('autocomplete_route_name'), - '#autocomplete_route_parameters' => array( - 'entity_type' => $items->getEntity()->getEntityTypeId(), - 'field_name' => $this->fieldDefinition->getName(), - ), - '#size' => $this->getSetting('size'), - '#placeholder' => $this->getSetting('placeholder'), - '#maxlength' => 1024, - '#element_validate' => array('taxonomy_autocomplete_validate'), - ); - - return $element; - } - - /** - * {@inheritdoc} - */ - public function massageFormValues(array $values, array $form, FormStateInterface $form_state) { - // Autocomplete widgets do not send their tids in the form, so we must detect - // them here and process them independently. - $items = array(); - - // Collect candidate vocabularies. - foreach ($this->getFieldSetting('allowed_values') as $tree) { - if ($vocabulary = $this->vocabularyStorage->load($tree['vocabulary'])) { - $vocabularies[$vocabulary->id()] = $vocabulary; - } - } - - // Translate term names into actual terms. - foreach($values as $value) { - // See if the term exists in the chosen vocabulary and return the tid; - // otherwise, create a new term. - if ($possibilities = entity_load_multiple_by_properties('taxonomy_term', array('name' => trim($value), 'vid' => array_keys($vocabularies)))) { - $term = array_pop($possibilities); - $item = array('target_id' => $term->id()); - } - else { - $vocabulary = reset($vocabularies); - $term = entity_create('taxonomy_term', array( - 'vid' => $vocabulary->id(), - 'name' => $value, - )); - $item = array('entity' => $term); - } - $items[] = $item; - } - - return $items; - } - -} diff --git a/core/modules/taxonomy/src/Plugin/views/argument_default/Tid.php b/core/modules/taxonomy/src/Plugin/views/argument_default/Tid.php index a8751d57ab52ec13300b9425acc351fff3d7145f..b439c060e74ad147656dad1f7c2b64830fb4fc0a 100644 --- a/core/modules/taxonomy/src/Plugin/views/argument_default/Tid.php +++ b/core/modules/taxonomy/src/Plugin/views/argument_default/Tid.php @@ -187,10 +187,11 @@ public function getArgument() { if (($node = $this->routeMatch->getParameter('node')) && $node instanceof NodeInterface) { $taxonomy = array(); foreach ($node->getFieldDefinitions() as $field) { - if ($field->getType() == 'taxonomy_term_reference') { + if ($field->getType() == 'entity_reference' && $field->getSetting('target_type') == 'taxonomy_term') { foreach ($node->get($field->getName()) as $item) { - $allowed_values = $field->getSetting('allowed_values'); - $taxonomy[$item->target_id] = $allowed_values[0]['vocabulary']; + if (($handler_settings = $field->getSetting('handler_settings')) && isset($handler_settings['target_bundles'])) { + $taxonomy[$item->target_id] = reset($handler_settings['target_bundles']); + } } } } diff --git a/core/modules/taxonomy/src/Tests/LegacyTest.php b/core/modules/taxonomy/src/Tests/LegacyTest.php index b2f02e5d05cf93d93988ba525d668cb279db9e9d..1da22ac0deb418a2e73e7ce697f526d8b6463ca2 100644 --- a/core/modules/taxonomy/src/Tests/LegacyTest.php +++ b/core/modules/taxonomy/src/Tests/LegacyTest.php @@ -35,30 +35,17 @@ protected function setUp() { $vocabulary->save(); $field_name = 'field_' . $vocabulary->id(); - entity_create('field_storage_config', array( - 'field_name' => $field_name, - 'entity_type' => 'node', - 'type' => 'taxonomy_term_reference', - 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, - 'settings' => array( - 'allowed_values' => array( - array( - 'vocabulary' => $vocabulary->id(), - 'parent' => 0, - ), - ), + $handler_settings = array( + 'target_bundles' => array( + $vocabulary->id() => $vocabulary->id(), ), - ))->save(); - entity_create('field_config', array( - 'entity_type' => 'node', - 'field_name' => $field_name, - 'bundle' => 'article', - 'label' => 'Tags', - ))->save(); + 'auto_create' => TRUE, + ); + $this->createEntityReferenceField('node', 'article', $field_name, 'Tags', 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); entity_get_form_display('node', 'article', 'default') ->setComponent($field_name, array( - 'type' => 'taxonomy_autocomplete', + 'type' => 'entity_reference_autocomplete_tags', )) ->save(); @@ -76,7 +63,7 @@ function testTaxonomyLegacyNode() { $edit['created[0][value][date]'] = $date->format('Y-m-d'); $edit['created[0][value][time]'] = $date->format('H:i:s'); $edit['body[0][value]'] = $this->randomMachineName(); - $edit['field_tags'] = $this->randomMachineName(); + $edit['field_tags[target_id]'] = $this->randomMachineName(); $this->drupalPostForm('node/add/article', $edit, t('Save and publish')); // Checks that the node has been saved. $node = $this->drupalGetNodeByTitle($edit['title[0][value]']); diff --git a/core/modules/taxonomy/src/Tests/RssTest.php b/core/modules/taxonomy/src/Tests/RssTest.php index d0b5c3aae80080d26f5bdd91838502d69cb41a8f..7fa3f10cedb71f83d34e2f60e796aa448418c627 100644 --- a/core/modules/taxonomy/src/Tests/RssTest.php +++ b/core/modules/taxonomy/src/Tests/RssTest.php @@ -46,25 +46,14 @@ protected function setUp() { $this->vocabulary = $this->createVocabulary(); $this->fieldName = 'taxonomy_' . $this->vocabulary->id(); - $field_storage = entity_create('field_storage_config', array( - 'field_name' => $this->fieldName, - 'entity_type' => 'node', - 'type' => 'taxonomy_term_reference', - 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, - 'settings' => array( - 'allowed_values' => array( - array( - 'vocabulary' => $this->vocabulary->id(), - 'parent' => 0, - ), - ), + $handler_settings = array( + 'target_bundles' => array( + $this->vocabulary->id() => $this->vocabulary->id(), ), - )); - $field_storage->save(); - entity_create('field_config', array( - 'field_storage' => $field_storage, - 'bundle' => 'article', - ))->save(); + 'auto_create' => TRUE, + ); + $this->createEntityReferenceField('node', 'article', $this->fieldName, NULL, 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); + entity_get_form_display('node', 'article', 'default') ->setComponent($this->fieldName, array( 'type' => 'options_select', @@ -72,7 +61,7 @@ protected function setUp() { ->save(); entity_get_display('node', 'article', 'default') ->setComponent($this->fieldName, array( - 'type' => 'taxonomy_term_reference_link', + 'type' => 'entity_reference_label', )) ->save(); } @@ -96,7 +85,7 @@ function testTaxonomyRss() { // Change the format to 'RSS category'. $this->drupalGet("admin/structure/types/manage/article/display/rss"); $edit = array( - "fields[taxonomy_" . $this->vocabulary->id() . "][type]" => 'taxonomy_term_reference_rss_category', + "fields[taxonomy_" . $this->vocabulary->id() . "][type]" => 'entity_reference_rss_category', ); $this->drupalPostForm(NULL, $edit, t('Save')); diff --git a/core/modules/taxonomy/src/Tests/TaxonomyTermReferenceItemTest.php b/core/modules/taxonomy/src/Tests/TaxonomyTermReferenceItemTest.php deleted file mode 100644 index ef5617edef2c4e70ce694fefbe11fbd8e8a5d6c0..0000000000000000000000000000000000000000 --- a/core/modules/taxonomy/src/Tests/TaxonomyTermReferenceItemTest.php +++ /dev/null @@ -1,122 +0,0 @@ -installEntitySchema('taxonomy_term'); - - $vocabulary = entity_create('taxonomy_vocabulary', array( - 'name' => $this->randomMachineName(), - 'vid' => Unicode::strtolower($this->randomMachineName()), - 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED, - )); - $vocabulary->save(); - - entity_create('field_storage_config', array( - 'field_name' => 'field_test_taxonomy', - 'entity_type' => 'entity_test', - 'type' => 'taxonomy_term_reference', - 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, - 'settings' => array( - 'allowed_values' => array( - array( - 'vocabulary' => $vocabulary->id(), - 'parent' => 0, - ), - ), - ), - ))->save(); - entity_create('field_config', array( - 'entity_type' => 'entity_test', - 'field_name' => 'field_test_taxonomy', - 'bundle' => 'entity_test', - ))->save(); - $this->term = entity_create('taxonomy_term', array( - 'name' => $this->randomMachineName(), - 'vid' => $vocabulary->id(), - 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED, - )); - $this->term->save(); - } - - /** - * Tests using entity fields of the taxonomy term reference field type. - */ - public function testTaxonomyTermReferenceItem() { - $tid = $this->term->id(); - // Just being able to create the entity like this verifies a lot of code. - $entity = entity_create('entity_test'); - $entity->field_test_taxonomy->target_id = $this->term->id(); - $entity->name->value = $this->randomMachineName(); - $entity->save(); - - $entity = entity_load('entity_test', $entity->id()); - $this->assertTrue($entity->field_test_taxonomy instanceof FieldItemListInterface, 'Field implements interface.'); - $this->assertTrue($entity->field_test_taxonomy[0] instanceof FieldItemInterface, 'Field item implements interface.'); - $this->assertEqual($entity->field_test_taxonomy->target_id, $this->term->id(), 'Field item contains the expected TID.'); - $this->assertEqual($entity->field_test_taxonomy->entity->getName(), $this->term->getName(), 'Field item entity contains the expected name.'); - $this->assertEqual($entity->field_test_taxonomy->entity->id(), $tid, 'Field item entity contains the expected ID.'); - $this->assertEqual($entity->field_test_taxonomy->entity->uuid(), $this->term->uuid(), 'Field item entity contains the expected UUID.'); - - // Change the name of the term via the reference. - $new_name = $this->randomMachineName(); - $entity->field_test_taxonomy->entity->setName($new_name); - $entity->field_test_taxonomy->entity->save(); - // Verify it is the correct name. - $term = Term::load($tid); - $this->assertEqual($term->getName(), $new_name, 'The name of the term was changed.'); - - // Make sure the computed term reflects updates to the term id. - $term2 = entity_create('taxonomy_term', array( - 'name' => $this->randomMachineName(), - 'vid' => $this->term->getVocabularyId(), - 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED, - )); - $term2->save(); - - $entity->field_test_taxonomy->target_id = $term2->id(); - $this->assertEqual($entity->field_test_taxonomy->entity->id(), $term2->id(), 'Field item entity contains the new TID.'); - $this->assertEqual($entity->field_test_taxonomy->entity->getName(), $term2->getName(), 'Field item entity contains the new name.'); - - // Test sample item generation. - $entity = entity_create('entity_test'); - $entity->field_test_taxonomy->generateSampleItems(); - $this->entityValidateAndSave($entity); - } - -} diff --git a/core/modules/taxonomy/src/Tests/TaxonomyTestBase.php b/core/modules/taxonomy/src/Tests/TaxonomyTestBase.php index 11a2f63ffb284c702717889a0a41ef3c527ba680..e18a9ed33b9cd121d1b9db236eab56492cfee65c 100644 --- a/core/modules/taxonomy/src/Tests/TaxonomyTestBase.php +++ b/core/modules/taxonomy/src/Tests/TaxonomyTestBase.php @@ -7,8 +7,8 @@ namespace Drupal\taxonomy\Tests; +use Drupal\entity_reference\Tests\EntityReferenceTestTrait; use Drupal\simpletest\WebTestBase; -use Drupal\taxonomy\Tests\TaxonomyTestTrait; /** * Provides common helper methods for Taxonomy module tests. @@ -16,6 +16,7 @@ abstract class TaxonomyTestBase extends WebTestBase { use TaxonomyTestTrait; + use EntityReferenceTestTrait; /** * Modules to enable. diff --git a/core/modules/taxonomy/src/Tests/TaxonomyTranslationTestTrait.php b/core/modules/taxonomy/src/Tests/TaxonomyTranslationTestTrait.php index dffd0b4b4bf1b69c0eaaec6d8d1727947d4ffd29..61e45bd692c32f872cefaa69c3cf6da2d90cad27 100644 --- a/core/modules/taxonomy/src/Tests/TaxonomyTranslationTestTrait.php +++ b/core/modules/taxonomy/src/Tests/TaxonomyTranslationTestTrait.php @@ -8,6 +8,8 @@ namespace Drupal\taxonomy\Tests; use Drupal\Core\Field\FieldStorageDefinitionInterface; +use Drupal\entity_reference\Tests\EntityReferenceTestTrait; +use Drupal\field\Entity\FieldStorageConfig; use Drupal\language\Entity\ConfigurableLanguage; /** @@ -15,6 +17,8 @@ */ trait TaxonomyTranslationTestTrait { + use EntityReferenceTestTrait; + /** * The vocabulary. * @@ -76,36 +80,25 @@ protected function enableTranslation() { * Adds term reference field for the article content type. */ protected function setUpTermReferenceField() { - entity_create('field_storage_config', array( - 'field_name' => $this->termFieldName, - 'entity_type' => 'node', - 'type' => 'taxonomy_term_reference', - 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, - 'settings' => array( - 'allowed_values' => array( - array( - 'vocabulary' => $this->vocabulary->id(), - 'parent' => 0, - ), - ), + $handler_settings = array( + 'target_bundles' => array( + $this->vocabulary->id() => $this->vocabulary->id(), ), - ))->save(); + 'auto_create' => TRUE, + ); + $this->createEntityReferenceField('node', 'article', $this->termFieldName, NULL, 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); + $field_storage = FieldStorageConfig::loadByName('node', $this->termFieldName); + $field_storage->setTranslatable(FALSE); + $field_storage->save(); - $field = entity_create('field_config', array( - 'field_name' => $this->termFieldName, - 'bundle' => 'article', - 'entity_type' => 'node', - 'translatable' => FALSE, - )); - $field->save(); entity_get_form_display('node', 'article', 'default') ->setComponent($this->termFieldName, array( - 'type' => 'taxonomy_autocomplete', + 'type' => 'entity_reference_autocomplete_tags', )) ->save(); entity_get_display('node', 'article', 'default') ->setComponent($this->termFieldName, array( - 'type' => 'taxonomy_term_reference_link', + 'type' => 'entity_reference_label', )) ->save(); } diff --git a/core/modules/taxonomy/src/Tests/TermFieldMultipleVocabularyTest.php b/core/modules/taxonomy/src/Tests/TermFieldMultipleVocabularyTest.php deleted file mode 100644 index a83d43e08ebf9c851868f484b0195154c5c0eddf..0000000000000000000000000000000000000000 --- a/core/modules/taxonomy/src/Tests/TermFieldMultipleVocabularyTest.php +++ /dev/null @@ -1,151 +0,0 @@ -drupalLogin($this->drupalCreateUser(['view test entity', 'administer entity_test content', 'administer taxonomy'])); - $this->vocabulary1 = $this->createVocabulary(); - $this->vocabulary2 = $this->createVocabulary(); - - // Set up a field storage and a field. - $this->fieldName = Unicode::strtolower($this->randomMachineName()); - entity_create('field_storage_config', array( - 'field_name' => $this->fieldName, - 'entity_type' => 'entity_test', - 'type' => 'taxonomy_term_reference', - 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, - 'settings' => array( - 'allowed_values' => array( - array( - 'vocabulary' => $this->vocabulary1->id(), - 'parent' => '0', - ), - array( - 'vocabulary' => $this->vocabulary2->id(), - 'parent' => '0', - ), - ), - ) - ))->save(); - entity_create('field_config', array( - 'field_name' => $this->fieldName, - 'entity_type' => 'entity_test', - 'bundle' => 'entity_test', - ))->save(); - entity_get_form_display('entity_test', 'entity_test', 'default') - ->setComponent($this->fieldName, array( - 'type' => 'options_select', - )) - ->save(); - entity_get_display('entity_test', 'entity_test', 'full') - ->setComponent($this->fieldName, array( - 'type' => 'taxonomy_term_reference_link', - )) - ->save(); - } - - /** - * Tests term reference field and widget with multiple vocabularies. - */ - function testTaxonomyTermFieldMultipleVocabularies() { - // Create a term in each vocabulary. - $term1 = $this->createTerm($this->vocabulary1); - $term2 = $this->createTerm($this->vocabulary2); - - // Submit an entity with both terms. - $this->drupalGet('entity_test/add'); - // Just check if the widget for the select is displayed, the NULL value is - // used to ignore the value check. - $this->assertFieldByName("{$this->fieldName}[]", NULL, 'Widget is displayed.'); - $edit = array( - "{$this->fieldName}[]" => array($term1->id(), $term2->id()), - ); - $this->drupalPostForm(NULL, $edit, t('Save')); - preg_match('|entity_test/manage/(\d+)|', $this->url, $match); - $id = $match[1]; - $this->assertText(t('entity_test @id has been created.', array('@id' => $id)), 'Entity was created.'); - - // Render the entity. - $entity = entity_load('entity_test', $id); - $display = entity_get_display($entity->getEntityTypeId(), $entity->bundle(), 'full'); - $content = $display->build($entity); - $this->setRawContent(drupal_render($content)); - $this->assertText($term1->getName(), 'Term 1 name is displayed.'); - $this->assertText($term2->getName(), 'Term 2 name is displayed.'); - - // Delete vocabulary 2. - $this->vocabulary2->delete(); - - // Re-render the content. - $entity = entity_load('entity_test', $id); - $display = entity_get_display($entity->getEntityTypeId(), $entity->bundle(), 'full'); - $content = $display->build($entity); - $this->setRawContent(drupal_render($content)); - - // Term 1 should still be displayed; term 2 should not be. - $this->assertText($term1->getName(), 'Term 1 name is displayed.'); - $this->assertNoText($term2->getName(), 'Term 2 name is not displayed.'); - - // Verify that field storage settings and field settings are correct. - $field_storage = FieldStorageConfig::loadByName('entity_test', $this->fieldName); - $this->assertEqual(count($field_storage->getSetting('allowed_values')), 1, 'Only one vocabulary is allowed for the field.'); - - // The widget should still be displayed. - $this->drupalGet('entity_test/add'); - // Just check if the widget for the select is displayed, the NULL value is - // used to ignore the value check. - $this->assertFieldByName("{$this->fieldName}[]", NULL, 'Widget is still displayed.'); - - // Term 1 should still pass validation. - $edit = array( - "{$this->fieldName}[]" => array($term1->id()), - ); - $this->drupalPostForm(NULL, $edit, t('Save')); - } -} diff --git a/core/modules/taxonomy/src/Tests/TermFieldTest.php b/core/modules/taxonomy/src/Tests/TermFieldTest.php deleted file mode 100644 index c9e9dbc003ec29cd45deead901ba2a89d6ba2517..0000000000000000000000000000000000000000 --- a/core/modules/taxonomy/src/Tests/TermFieldTest.php +++ /dev/null @@ -1,191 +0,0 @@ -drupalCreateUser(array( - 'view test entity', - 'administer entity_test content', - 'administer taxonomy', - 'administer entity_test fields', - )); - $this->drupalLogin($web_user); - $this->vocabulary = $this->createVocabulary(); - - // Setup a field. - $this->fieldName = Unicode::strtolower($this->randomMachineName()); - $this->fieldStorage = entity_create('field_storage_config', array( - 'field_name' => $this->fieldName, - 'entity_type' => 'entity_test', - 'type' => 'taxonomy_term_reference', - 'settings' => array( - 'allowed_values' => array( - array( - 'vocabulary' => $this->vocabulary->id(), - 'parent' => '0', - ), - ), - ) - )); - $this->fieldStorage->save(); - entity_create('field_config', array( - 'field_storage' => $this->fieldStorage, - 'bundle' => 'entity_test', - ))->save(); - entity_get_form_display('entity_test', 'entity_test', 'default') - ->setComponent($this->fieldName, array( - 'type' => 'options_select', - )) - ->save(); - entity_get_display('entity_test', 'entity_test', 'full') - ->setComponent($this->fieldName, array( - 'type' => 'taxonomy_term_reference_link', - )) - ->save(); - } - - /** - * Test term field validation. - */ - function testTaxonomyTermFieldValidation() { - // Test validation with a valid value. - $term = $this->createTerm($this->vocabulary); - $entity = entity_create('entity_test'); - $entity->{$this->fieldName}->target_id = $term->id(); - $violations = $entity->{$this->fieldName}->validate(); - $this->assertEqual(count($violations) , 0, 'Correct term does not cause validation error.'); - - // Test validation with an invalid valid value (wrong vocabulary). - $bad_term = $this->createTerm($this->createVocabulary()); - $entity = entity_create('entity_test'); - $entity->{$this->fieldName}->target_id = $bad_term->id(); - $violations = $entity->{$this->fieldName}->validate(); - $this->assertEqual(count($violations) , 1, 'Wrong term causes validation error.'); - } - - /** - * Test widgets. - */ - function testTaxonomyTermFieldWidgets() { - // Create a term in the vocabulary. - $term = $this->createTerm($this->vocabulary); - - // Display creation form. - $this->drupalGet('entity_test/add'); - $this->assertFieldByName($this->fieldName, NULL, 'Widget is displayed.'); - - // Submit with some value. - $edit = array( - $this->fieldName => array($term->id()), - ); - $this->drupalPostForm(NULL, $edit, t('Save')); - preg_match('|entity_test/manage/(\d+)|', $this->url, $match); - $id = $match[1]; - $this->assertText(t('entity_test @id has been created.', array('@id' => $id))); - - // Display the object. - $entity = entity_load('entity_test', $id); - $display = entity_get_display($entity->getEntityTypeId(), $entity->bundle(), 'full'); - $content = $display->build($entity); - $this->setRawContent(drupal_render($content)); - $this->assertText($term->getName(), 'Term label is displayed.'); - - // Delete the vocabulary and verify that the widget is gone. - $this->vocabulary->delete(); - $this->drupalGet('entity_test/add'); - $this->assertNoFieldByName($this->fieldName, '', 'Widget is not displayed.'); - } - - /** - * No php error message on the field setting page for autocomplete widget. - */ - function testTaxonomyTermFieldSettingsAutocompleteWidget() { - entity_get_form_display('entity_test', 'entity_test', 'default') - ->setComponent($this->fieldName, array( - 'type' => 'taxonomy_autocomplete', - 'weight' => 1, - )) - ->save(); - $this->drupalGet('entity_test/structure/entity_test/fields/entity_test.entity_test.' . $this->fieldName); - $this->assertNoErrorsLogged(); - } - - /** - * Tests that vocabulary machine name changes are mirrored in field definitions. - */ - function testTaxonomyTermFieldChangeMachineName() { - // Add several entries in the 'allowed_values' setting, to make sure that - // they all get updated. - $this->fieldStorage->setSetting('allowed_values', [ - array( - 'vocabulary' => $this->vocabulary->id(), - 'parent' => '0', - ), - array( - 'vocabulary' => $this->vocabulary->id(), - 'parent' => '0', - ), - array( - 'vocabulary' => 'foo', - 'parent' => '0', - ), - ]); - $this->fieldStorage->save(); - // Change the machine name. - $new_name = Unicode::strtolower($this->randomMachineName()); - $this->vocabulary->set('vid', $new_name); - $this->vocabulary->save(); - - // Check that the field is still attached to the vocabulary. - $field_storage = FieldStorageConfig::loadByName('entity_test', $this->fieldName); - $allowed_values = $field_storage->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.'); - $this->assertEqual($allowed_values[2]['vocabulary'], 'foo', 'Index 2: Machine name was left untouched.'); - } -} diff --git a/core/modules/taxonomy/src/Tests/TermIndexTest.php b/core/modules/taxonomy/src/Tests/TermIndexTest.php index 62310a682c3df0b30f982434052f782071a3cd4a..43f97d57d9dcea17b33167771a13073776103b27 100644 --- a/core/modules/taxonomy/src/Tests/TermIndexTest.php +++ b/core/modules/taxonomy/src/Tests/TermIndexTest.php @@ -8,7 +8,6 @@ namespace Drupal\taxonomy\Tests; use Drupal\Component\Utility\Unicode; -use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Field\FieldStorageDefinitionInterface; /** @@ -56,25 +55,14 @@ protected function setUp() { $this->vocabulary = $this->createVocabulary(); $this->fieldName1 = Unicode::strtolower($this->randomMachineName()); - entity_create('field_storage_config', array( - 'field_name' => $this->fieldName1, - 'entity_type' => 'node', - 'type' => 'taxonomy_term_reference', - 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, - 'settings' => array( - 'allowed_values' => array( - array( - 'vocabulary' => $this->vocabulary->id(), - 'parent' => 0, - ), - ), - ), - ))->save(); - entity_create('field_config', array( - 'field_name' => $this->fieldName1, - 'bundle' => 'article', - 'entity_type' => 'node', - ))->save(); + $handler_settings = array( + 'target_bundles' => array( + $this->vocabulary->id() => $this->vocabulary->id(), + ), + 'auto_create' => TRUE, + ); + $this->createEntityReferenceField('node', 'article', $this->fieldName1, NULL, 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); + entity_get_form_display('node', 'article', 'default') ->setComponent($this->fieldName1, array( 'type' => 'options_select', @@ -82,30 +70,13 @@ protected function setUp() { ->save(); entity_get_display('node', 'article', 'default') ->setComponent($this->fieldName1, array( - 'type' => 'taxonomy_term_reference_link', + 'type' => 'entity_reference_label', )) ->save(); $this->fieldName2 = Unicode::strtolower($this->randomMachineName()); - entity_create('field_storage_config', array( - 'field_name' => $this->fieldName2, - 'entity_type' => 'node', - 'type' => 'taxonomy_term_reference', - 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, - 'settings' => array( - 'allowed_values' => array( - array( - 'vocabulary' => $this->vocabulary->id(), - 'parent' => 0, - ), - ), - ), - ))->save(); - entity_create('field_config', array( - 'field_name' => $this->fieldName2, - 'bundle' => 'article', - 'entity_type' => 'node', - ))->save(); + $this->createEntityReferenceField('node', 'article', $this->fieldName2, NULL, 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); + entity_get_form_display('node', 'article', 'default') ->setComponent($this->fieldName2, array( 'type' => 'options_select', @@ -113,7 +84,7 @@ protected function setUp() { ->save(); entity_get_display('node', 'article', 'default') ->setComponent($this->fieldName2, array( - 'type' => 'taxonomy_term_reference_link', + 'type' => 'entity_reference_label', )) ->save(); } diff --git a/core/modules/taxonomy/src/Tests/TermTest.php b/core/modules/taxonomy/src/Tests/TermTest.php index 083e28b9fa4f1c3050a347354ac7b76ededb1f98..eaa0617cb7da7a5e6f06f478339b6ad4667bc08b 100644 --- a/core/modules/taxonomy/src/Tests/TermTest.php +++ b/core/modules/taxonomy/src/Tests/TermTest.php @@ -7,12 +7,10 @@ namespace Drupal\taxonomy\Tests; -use Drupal\Component\Serialization\Json; -use Drupal\Component\Utility\String; use Drupal\Component\Utility\Tags; use Drupal\Component\Utility\Unicode; use Drupal\Core\Field\FieldStorageDefinitionInterface; -use Drupal\field\Entity\FieldStorageConfig; +use Drupal\field\Entity\FieldConfig; use Drupal\taxonomy\Entity\Term; use Drupal\taxonomy\Entity\Vocabulary; @@ -43,27 +41,16 @@ protected function setUp() { $this->vocabulary = $this->createVocabulary(); $field_name = 'taxonomy_' . $this->vocabulary->id(); - entity_create('field_storage_config', array( - 'field_name' => $field_name, - 'entity_type' => 'node', - 'type' => 'taxonomy_term_reference', - 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, - 'settings' => array( - 'allowed_values' => array( - array( - 'vocabulary' => $this->vocabulary->id(), - 'parent' => 0, - ), - ), + + $handler_settings = array( + 'target_bundles' => array( + $this->vocabulary->id() => $this->vocabulary->id(), ), - ))->save(); + 'auto_create' => TRUE, + ); + $this->createEntityReferenceField('node', 'article', $field_name, NULL, 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); + $this->field = FieldConfig::loadByName('node', 'article', $field_name); - $this->field = entity_create('field_config', array( - 'field_name' => $field_name, - 'bundle' => 'article', - 'entity_type' => 'node', - )); - $this->field->save(); entity_get_form_display('node', 'article', 'default') ->setComponent($field_name, array( 'type' => 'options_select', @@ -71,7 +58,7 @@ protected function setUp() { ->save(); entity_get_display('node', 'article', 'default') ->setComponent($field_name, array( - 'type' => 'taxonomy_term_reference_link', + 'type' => 'entity_reference_label', )) ->save(); } @@ -213,7 +200,7 @@ function testNodeTermCreationAndDeletion() { $field = $this->field; entity_get_form_display($field->entity_type, $field->bundle, 'default') ->setComponent($field->getName(), array( - 'type' => 'taxonomy_autocomplete', + 'type' => 'entity_reference_autocomplete_tags', 'settings' => array( 'placeholder' => 'Start typing here.', ), @@ -234,7 +221,7 @@ function testNodeTermCreationAndDeletion() { $edit['body[0][value]'] = $this->randomMachineName(); // Insert the terms in a comma separated list. Vocabulary 1 is a // free-tagging field created by the default profile. - $edit[$field->getName()] = Tags::implode($terms); + $edit[$field->getName() . '[target_id]'] = Tags::implode($terms); // Verify the placeholder is there. $this->drupalGet('node/add/article'); @@ -291,82 +278,6 @@ function testNodeTermCreationAndDeletion() { } $this->assertNoText($term_objects['term1']->getName(), format_string('The deleted term %name does not appear on the node page.', array('%name' => $term_objects['term1']->getName()))); $this->assertNoText($term_objects['term2']->getName(), format_string('The deleted term %name does not appear on the node page.', array('%name' => $term_objects['term2']->getName()))); - - // Test autocomplete on term 3, which contains a comma. - // The term will be quoted, and the " will be encoded in unicode (\u0022). - $input = substr($term_objects['term3']->getName(), 0, 3); - $json = $this->drupalGet('taxonomy/autocomplete/node/taxonomy_' . $this->vocabulary->id(), array('query' => array('q' => $input))); - $this->assertEqual($json, '[{"value":"\u0022' . $term_objects['term3']->getName() . '\u0022","label":"' . $term_objects['term3']->getName() . '"}]', format_string('Autocomplete returns term %term_name after typing the first 3 letters.', array('%term_name' => $term_objects['term3']->getName()))); - - // Test autocomplete on term 4 - it is alphanumeric only, so no extra - // quoting. - $input = substr($term_objects['term4']->getName(), 0, 3); - $this->drupalGet('taxonomy/autocomplete/node/taxonomy_' . $this->vocabulary->id(), array('query' => array('q' => $input))); - $this->assertRaw('[{"value":"' . $term_objects['term4']->getName() . '","label":"' . $term_objects['term4']->getName() . '"}', format_string('Autocomplete returns term %term_name after typing the first 3 letters.', array('%term_name' => $term_objects['term4']->getName()))); - - // Test taxonomy autocomplete with a nonexistent field. - $field_name = $this->randomMachineName(); - $tag = $this->randomMachineName(); - $message = t("Taxonomy field @field_name not found.", array('@field_name' => $field_name)); - $this->assertFalse(FieldStorageConfig::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.'); - } - - /** - * Tests term autocompletion edge cases with slashes in the names. - */ - function testTermAutocompletion() { - // Add a term with a slash in the name. - $first_term = $this->createTerm($this->vocabulary); - $first_term->setName('10/16/2011'); - $first_term->save(); - // Add another term that differs after the slash character. - $second_term = $this->createTerm($this->vocabulary); - $second_term->setName('10/17/2011'); - $second_term->save(); - // Add another term that has both a comma and a slash character. - $third_term = $this->createTerm($this->vocabulary); - $third_term->setName('term with, a comma and / a slash'); - $third_term->save(); - - // Try to autocomplete a term name that matches both terms. - // We should get both terms in a json encoded string. - $input = '10/'; - $path = 'taxonomy/autocomplete/node/taxonomy_' . $this->vocabulary->id(); - // The result order is not guaranteed, so check each term separately. - $result = $this->drupalGet($path, array('query' => array('q' => $input))); - // Pull the label properties from the array of arrays. - $data = Json::decode($result); - $data = array_map(function ($item) { - return $item['label']; - }, $data); - - $this->assertTrue(in_array(String::checkPlain($first_term->getName()), $data), 'Autocomplete returned the first matching term'); - $this->assertTrue(in_array(String::checkPlain($second_term->getName()), $data), 'Autocomplete returned the second matching term'); - - // Try to autocomplete a term name that matches first term. - // We should only get the first term in a json encoded string. - $input = '10/16'; - $path = 'taxonomy/autocomplete/node/taxonomy_' . $this->vocabulary->id(); - $this->drupalGet($path, array('query' => array('q' => $input))); - $target = array(array( - 'value' => String::checkPlain($first_term->getName()), - 'label' => $first_term->getName(), - )); - $this->assertRaw(Json::encode($target), 'Autocomplete returns only the expected matching term.'); - - // Try to autocomplete a term name with both a comma and a slash. - $input = '"term with, comma and / a'; - $path = 'taxonomy/autocomplete/node/taxonomy_' . $this->vocabulary->id(); - $this->drupalGet($path, array('query' => array('q' => $input))); - // Term names containing commas or quotes must be wrapped in quotes. - $n = Tags::encode($third_term->getName()); - $target = array(array( - 'value' => $n, - 'label' => String::checkPlain($third_term->getName()), - )); - $this->assertRaw(Json::encode($target), 'Autocomplete returns a term containing a comma and a slash.'); } /** @@ -601,7 +512,7 @@ function testReSavingTags() { $field = $this->field; entity_get_form_display($field->entity_type, $field->bundle, 'default') ->setComponent($field->getName(), array( - 'type' => 'taxonomy_autocomplete', + 'type' => 'entity_reference_autocomplete_tags', )) ->save(); @@ -610,7 +521,7 @@ function testReSavingTags() { $edit = array(); $edit['title[0][value]'] = $this->randomMachineName(8); $edit['body[0][value]'] = $this->randomMachineName(16); - $edit[$this->field->getName()] = $term->getName(); + $edit[$this->field->getName() . '[target_id]'] = $term->getName(); $this->drupalPostForm('node/add/article', $edit, t('Save')); // Check that the term is displayed when editing and saving the node with no diff --git a/core/modules/taxonomy/src/Tests/TokenReplaceTest.php b/core/modules/taxonomy/src/Tests/TokenReplaceTest.php index 242a23e9443fc8a15449922aa8295bb3d54520b7..4ea3c4bee72be51ee341d979a2729841d8c1c060 100644 --- a/core/modules/taxonomy/src/Tests/TokenReplaceTest.php +++ b/core/modules/taxonomy/src/Tests/TokenReplaceTest.php @@ -38,26 +38,15 @@ protected function setUp() { $this->drupalLogin($this->drupalCreateUser(['administer taxonomy', 'bypass node access'])); $this->vocabulary = $this->createVocabulary(); $this->fieldName = 'taxonomy_' . $this->vocabulary->id(); - entity_create('field_storage_config', array( - 'field_name' => $this->fieldName, - 'entity_type' => 'node', - 'type' => 'taxonomy_term_reference', - 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, - 'settings' => array( - 'allowed_values' => array( - array( - 'vocabulary' => $this->vocabulary->id(), - 'parent' => 0, - ), - ), + + $handler_settings = array( + 'target_bundles' => array( + $this->vocabulary->id() => $this->vocabulary->id(), ), - ))->save(); + 'auto_create' => TRUE, + ); + $this->createEntityReferenceField('node', 'article', $this->fieldName, NULL, 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); - entity_create('field_config', array( - 'field_name' => $this->fieldName, - 'bundle' => 'article', - 'entity_type' => 'node', - ))->save(); entity_get_form_display('node', 'article', 'default') ->setComponent($this->fieldName, array( 'type' => 'options_select', @@ -65,7 +54,7 @@ protected function setUp() { ->save(); entity_get_display('node', 'article', 'default') ->setComponent($this->fieldName, array( - 'type' => 'taxonomy_term_reference_link', + 'type' => 'entity_reference_label', )) ->save(); } diff --git a/core/modules/taxonomy/src/Tests/Views/TaxonomyTermViewTest.php b/core/modules/taxonomy/src/Tests/Views/TaxonomyTermViewTest.php index a0edac2580e194dfb4e616709e67c219c027b743..78f0d8c183349493eb4d191d1bea04eef3981615 100644 --- a/core/modules/taxonomy/src/Tests/Views/TaxonomyTermViewTest.php +++ b/core/modules/taxonomy/src/Tests/Views/TaxonomyTermViewTest.php @@ -55,25 +55,15 @@ protected function setUp() { // Create a vocabulary and add two term reference fields to article nodes. $this->fieldName1 = Unicode::strtolower($this->randomMachineName()); - entity_create('field_storage_config', array( - 'field_name' => $this->fieldName1, - 'entity_type' => 'node', - 'type' => 'taxonomy_term_reference', - 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, - 'settings' => array( - 'allowed_values' => array( - array( - 'vocabulary' => $this->vocabulary->id(), - 'parent' => 0, - ), - ), + + $handler_settings = array( + 'target_bundles' => array( + $this->vocabulary->id() => $this->vocabulary->id(), ), - ))->save(); - entity_create('field_config', array( - 'field_name' => $this->fieldName1, - 'bundle' => 'article', - 'entity_type' => 'node', - ))->save(); + 'auto_create' => TRUE, + ); + $this->createEntityReferenceField('node', 'article', $this->fieldName1, NULL, 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); + entity_get_form_display('node', 'article', 'default') ->setComponent($this->fieldName1, array( 'type' => 'options_select', @@ -81,7 +71,7 @@ protected function setUp() { ->save(); entity_get_display('node', 'article', 'default') ->setComponent($this->fieldName1, array( - 'type' => 'taxonomy_term_reference_link', + 'type' => 'entity_reference_label', )) ->save(); } diff --git a/core/modules/taxonomy/src/Tests/Views/TaxonomyTestBase.php b/core/modules/taxonomy/src/Tests/Views/TaxonomyTestBase.php index b54d3b8a51f2cf4400266fefbb573d5af1801756..9fa56bcdce9185b2913d4548e1f6640571d0754a 100644 --- a/core/modules/taxonomy/src/Tests/Views/TaxonomyTestBase.php +++ b/core/modules/taxonomy/src/Tests/Views/TaxonomyTestBase.php @@ -9,6 +9,7 @@ use Drupal\Core\Field\FieldStorageDefinitionInterface; use Drupal\Core\Language\LanguageInterface; +use Drupal\entity_reference\Tests\EntityReferenceTestTrait; use Drupal\views\Tests\ViewTestBase; use Drupal\views\Tests\ViewTestData; @@ -17,6 +18,8 @@ */ abstract class TaxonomyTestBase extends ViewTestBase { + use EntityReferenceTestTrait; + /** * Modules to enable. * @@ -85,44 +88,31 @@ protected function mockStandardInstall() { )); $this->vocabulary->save(); $field_name = 'field_' . $this->vocabulary->id(); - entity_create('field_storage_config', array( - 'field_name' => $field_name, - 'entity_type' => 'node', - 'type' => 'taxonomy_term_reference', - // Set cardinality to unlimited for tagging. - 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, - 'settings' => array( - 'allowed_values' => array( - array( - 'vocabulary' => $this->vocabulary->id(), - 'parent' => 0, - ), - ), + + $handler_settings = array( + 'target_bundles' => array( + $this->vocabulary->id() => $this->vocabulary->id(), ), - ))->save(); - entity_create('field_config', array( - 'field_name' => $field_name, - 'entity_type' => 'node', - 'label' => 'Tags', - 'bundle' => 'article', - ))->save(); + 'auto_create' => TRUE, + ); + $this->createEntityReferenceField('node', 'article', $field_name, 'Tags', 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); entity_get_form_display('node', 'article', 'default') ->setComponent($field_name, array( - 'type' => 'taxonomy_autocomplete', + 'type' => 'entity_reference_autocomplete_tags', 'weight' => -4, )) ->save(); entity_get_display('node', 'article', 'default') ->setComponent($field_name, array( - 'type' => 'taxonomy_term_reference_link', + 'type' => 'entity_reference_label', 'weight' => 10, )) ->save(); entity_get_display('node', 'article', 'teaser') ->setComponent($field_name, array( - 'type' => 'taxonomy_term_reference_link', + 'type' => 'entity_reference_label', 'weight' => 10, )) ->save(); diff --git a/core/modules/taxonomy/taxonomy.info.yml b/core/modules/taxonomy/taxonomy.info.yml index ceca3dd91c50089757f8a5b6f0dca71f4a4e33ea..a54f7d1dd4d4e9e3a46842a42da5f32daf8b0048 100644 --- a/core/modules/taxonomy/taxonomy.info.yml +++ b/core/modules/taxonomy/taxonomy.info.yml @@ -5,6 +5,7 @@ package: Core version: VERSION core: 8.x dependencies: + - entity_reference - node - text configure: entity.taxonomy_vocabulary.collection diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module index c1896fd94545e5ed3dbaa1caa81f3f2708597a2f..42c543a1eb539739c36f2405e1b4e2ee6d370ffe 100644 --- a/core/modules/taxonomy/taxonomy.module +++ b/core/modules/taxonomy/taxonomy.module @@ -9,17 +9,13 @@ use Drupal\Component\Utility\Unicode; use Drupal\Core\Entity\Sql\SqlContentEntityStorage; use Drupal\Core\Entity\EntityInterface; -use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Render\Element; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Url; -use Drupal\file\FileInterface; -use Drupal\node\Entity\Node; use Drupal\taxonomy\Entity\Term; use Drupal\taxonomy\Entity\Vocabulary; use Drupal\taxonomy\TermInterface; use Drupal\taxonomy\VocabularyInterface; -use Drupal\Component\Utility\String; /** * Denotes that no term in the vocabulary has a parent. @@ -36,14 +32,6 @@ */ const TAXONOMY_HIERARCHY_MULTIPLE = 2; -/** - * Users can create new terms in a free-tagging vocabulary when - * submitting a taxonomy_autocomplete_widget. We store a term object - * whose tid is 'autocreate' as a field data item during widget - * validation and then actually create the term if/when that field - * data item makes it to taxonomy_field_insert/update(). - */ - /** * Implements hook_help(). */ @@ -62,25 +50,11 @@ function taxonomy_help($route_name, RouteMatchInterface $route_match) { $output .= '
' . t('Managing terms') . '
'; $output .= '
' . t('Users who have the Administer vocabularies and terms permission or the Edit terms permission for a particular vocabulary can add, edit, and organize the terms in a vocabulary from a vocabulary\'s term listing page, which can be accessed by going to the Taxonomy administration page and clicking List terms in the Operations column. Users must have the Administer vocabularies and terms permission or the Delete terms permission for a particular vocabulary to delete terms.' , array('!taxonomy_admin' => \Drupal::url('entity.taxonomy_vocabulary.collection'))) . '
'; $output .= '
' . t('Classifying entity content') . '
'; - $output .= '
' . t('A user with the Administer fields permission for a certain entity type may add reference fields to the entity, which will allow entities to be classified using taxonomy terms. See the Field module help and the Field UI help pages for general information on fields and how to create and manage them. The reference field can either be a Taxonomy Term reference or an Entity reference field:' , array('!field_ui' => $field_ui_url, '!field' => \Drupal::url('help.page', array('name' => 'field')))); - $output .= ''; - $output .= '
'; + $output .= '
' . t('A user with the Administer fields permission for a certain entity type may add Taxonomy term reference fields to the entity type, which will allow entities to be classified using taxonomy terms. See the Entity Reference help for more information about reference fields. See the Field module help and the Field UI help pages for general information on fields and how to create and manage them.' , array('!field_ui' => $field_ui_url, '!field' => \Drupal::url('help.page', array('name' => 'field')), '!entity_reference' => \Drupal::url('help.page', array('name' => 'entity_reference')))) . '
'; $output .= '
' . t('Adding new terms during content creation') . '
'; - $output .= '
' . t('Allowing users to add new terms gradually builds a vocabulary as content is added and edited. Users can add new terms if the Autocomplete term widget (tagging) is chosen for a Taxonomy Term reference field, or if either of the two Autocomplete widgets is chosen for an Entity reference field. In this case you need to enable the Create referenced entity option, and restrict the field to one vocabulary.') . '
'; - $output .= '
' . t('Configuring displays and form displays ') . '
'; - $output .= '
' . t('The reference fields have several formatters and widgets available on the Manage display and Manage form display pages, respectively:'); - $output .= ''; $output .= '
'; $output .= ''; @@ -529,27 +503,6 @@ function taxonomy_implode_tags($tags, $vid = NULL) { return implode(', ', $typed_tags); } -/** - * Implements hook_field_widget_info_alter(). - */ -function taxonomy_field_widget_info_alter(&$info) { - if (isset($info['options_select'])) { - $info['options_select']['field_types'][] = 'taxonomy_term_reference'; - } - if (isset($info['options_buttons'])) { - $info['options_buttons']['field_types'][] = 'taxonomy_term_reference'; - } -} - -/** - * Implements hook_field_formatter_info_alter(). - */ -function taxonomy_field_formatter_info_alter(array &$info) { - if (!\Drupal::moduleHandler()->moduleExists('entity_reference')) { - unset($info['entity_reference_rss_category']); - } -} - /** * Title callback for term pages. * @@ -563,19 +516,6 @@ function taxonomy_term_title(Term $term) { return $term->getName(); } -/** - * Form element validate handler for taxonomy term autocomplete element. - */ -function taxonomy_autocomplete_validate($element, FormStateInterface $form_state) { - // Split the values into an array. - // @see \Drupal\taxonomy\Plugin\Field\FieldWidget\TaxonomyAutocompleteWidget:massageFormValues() - $typed_terms = array(); - if ($tags = $element['#value']) { - $typed_terms = Tags::explode($tags); - } - $form_state->setValueForElement($element, $typed_terms); -} - /** * @defgroup taxonomy_index Taxonomy indexing * @{ @@ -626,7 +566,7 @@ function taxonomy_build_node_index($node) { $tid_all = array(); foreach ($node->getFieldDefinitions() as $field) { $field_name = $field->getName(); - if ($field->getType() == 'taxonomy_term_reference') { + if (is_subclass_of($field->getItemDefinition()->getClass(), '\Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem') && $field->getSetting('target_type') == 'taxonomy_term') { foreach ($node->getTranslationLanguages() as $language) { foreach ($node->getTranslation($language->getId())->$field_name as $item) { if (!$item->isEmpty()) { diff --git a/core/modules/taxonomy/taxonomy.routing.yml b/core/modules/taxonomy/taxonomy.routing.yml index 9c96d43405e90f92e2f6dee3f6d3c530907d6190..a7a75f30f0fcbad3d4624865d09fa43cf1f250e5 100644 --- a/core/modules/taxonomy/taxonomy.routing.yml +++ b/core/modules/taxonomy/taxonomy.routing.yml @@ -66,13 +66,6 @@ entity.taxonomy_vocabulary.reset_form: requirements: _permission: 'administer taxonomy' -taxonomy.autocomplete: - path: '/taxonomy/autocomplete/{entity_type}/{field_name}' - defaults: - _controller: '\Drupal\taxonomy\Controller\TermAutocompleteController::autocomplete' - requirements: - _permission: 'access content' - entity.taxonomy_vocabulary.overview_form: path: '/admin/structure/taxonomy/manage/{taxonomy_vocabulary}/overview' defaults: diff --git a/core/modules/taxonomy/taxonomy.views.inc b/core/modules/taxonomy/taxonomy.views.inc index 3160ea1008d43d0df6986e128f4cd29978946979..5360d508147d6c01515a6ee5c54f811bf13308e1 100644 --- a/core/modules/taxonomy/taxonomy.views.inc +++ b/core/modules/taxonomy/taxonomy.views.inc @@ -52,73 +52,23 @@ function taxonomy_views_data_alter(&$data) { } /** - * Implements hook_field_views_data(). + * Implements hook_field_views_data_alter(). * - * Views integration for taxonomy_term_reference fields. Adds a term relationship to the default - * field data. + * Views integration for entity reference fields which reference taxonomy terms. + * Adds a term relationship to the default field data. * * @see views_field_default_views_data() */ -function taxonomy_field_views_data(FieldStorageConfigInterface $field_storage) { - $data = views_field_default_views_data($field_storage); - foreach ($data as $table_name => $table_data) { - foreach ($table_data as $field_name => $field_data) { - if (isset($field_data['filter']) && $field_name != 'delta') { - $data[$table_name][$field_name]['filter']['id'] = 'taxonomy_index_tid'; - $allowed_values = $field_storage->getSetting('allowed_values'); - $data[$table_name][$field_name]['filter']['vocabulary'] = $allowed_values[0]['vocabulary']; +function taxonomy_field_views_data_alter(array &$data, FieldStorageConfigInterface $field_storage) { + if ($field_storage->getType() == 'entity_reference' && $field_storage->getSetting('target_type') == 'taxonomy_term') { + foreach ($data as $table_name => $table_data) { + foreach ($table_data as $field_name => $field_data) { + if (isset($field_data['filter']) && $field_name != 'delta') { + $data[$table_name][$field_name]['filter']['id'] = 'taxonomy_index_tid'; + } } } - - // Add the relationship only on the tid field. - $field_name = $field_storage->getName(); - $data[$table_name][$field_name . '_target_id']['relationship'] = array( - 'id' => 'standard', - 'base' => 'taxonomy_term_data', - 'base field' => 'tid', - 'label' => t('term from !field_name', array('!field_name' => $field_name)), - ); - } - - return $data; -} - -/** - * Implements hook_field_views_data_views_data_alter(). - * - * Views integration to provide reverse relationships on term references. - */ -function taxonomy_field_views_data_views_data_alter(array &$data, FieldStorageConfigInterface $field_storage) { - $field_name = $field_storage->getName(); - $entity_type_id = $field_storage->getTargetEntityTypeId(); - $entity_manager = \Drupal::entityManager(); - $entity_type = $entity_manager->getDefinition($entity_type_id); - $pseudo_field_name = 'reverse_' . $field_name . '_' . $entity_type_id; - /** @var \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping */ - $table_mapping = $entity_manager->getStorage($entity_type_id)->getTableMapping(); - - list($label) = views_entity_field_label($entity_type_id, $field_name); - - $data['taxonomy_term_data'][$pseudo_field_name]['relationship'] = array( - 'title' => t('@entity using @field', array('@entity' => $entity_type->getLabel(), '@field' => $label)), - 'help' => t('Relate each @entity with a @field set to the term.', array('@entity' => $entity_type->getLabel(), '@field' => $label)), - 'id' => 'entity_reverse', - 'field_name' => $field_name, - 'entity_type' => $entity_type_id, - 'field table' => $table_mapping->getDedicatedDataTableName($field_storage), - 'field field' => $field_name . '_target_id', - 'base' => $entity_type->getBaseTable(), - 'base field' => $entity_type->getKey('id'), - 'label' => t('!field_name', array('!field_name' => $field_name)), - 'join_extra' => array( - 0 => array( - 'field' => 'deleted', - 'value' => 0, - 'numeric' => TRUE, - ), - ), - ); } /** diff --git a/core/modules/views/src/Tests/DefaultViewsTest.php b/core/modules/views/src/Tests/DefaultViewsTest.php index 1d1186872d0e747ea78bfe120b8d3dcd8492fb71..4ef50916c85e1086e0c1b3f94e62d1fc83a40c56 100644 --- a/core/modules/views/src/Tests/DefaultViewsTest.php +++ b/core/modules/views/src/Tests/DefaultViewsTest.php @@ -10,10 +10,10 @@ use Drupal\comment\CommentInterface; use Drupal\comment\Tests\CommentTestTrait; use Drupal\Component\Utility\Unicode; +use Drupal\Core\Field\FieldStorageDefinitionInterface; use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Url; -use Drupal\simpletest\WebTestBase; -use Drupal\views\ViewExecutable; +use Drupal\entity_reference\Tests\EntityReferenceTestTrait; use Drupal\views\Views; /** @@ -24,6 +24,7 @@ class DefaultViewsTest extends ViewTestBase { use CommentTestTrait; + use EntityReferenceTestTrait; /** * Modules to enable. @@ -62,24 +63,14 @@ protected function setUp() { // Create a field. $field_name = Unicode::strtolower($this->randomMachineName()); - entity_create('field_storage_config', array( - 'field_name' => $field_name, - 'entity_type' => 'node', - 'type' => 'taxonomy_term_reference', - 'settings' => array( - 'allowed_values' => array( - array( - 'vocabulary' => $vocabulary->id(), - 'parent' => '0', - ), - ), - ) - ))->save(); - entity_create('field_config', array( - 'field_name' => $field_name, - 'entity_type' => 'node', - 'bundle' => 'page', - ))->save(); + + $handler_settings = array( + 'target_bundles' => array( + $vocabulary->id() => $vocabulary->id(), + ), + 'auto_create' => TRUE, + ); + $this->createEntityReferenceField('node', 'page', $field_name, NULL, 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); // Create a time in the past for the archive. $time = REQUEST_TIME - 3600; diff --git a/core/modules/views/src/Tests/Wizard/TaggedWithTest.php b/core/modules/views/src/Tests/Wizard/TaggedWithTest.php index e44fe5999d64d4c6a448a7b8c593d70b46bbc308..caf95bebd3731446608bbba89e787dc4d0d02b8c 100644 --- a/core/modules/views/src/Tests/Wizard/TaggedWithTest.php +++ b/core/modules/views/src/Tests/Wizard/TaggedWithTest.php @@ -8,6 +8,7 @@ namespace Drupal\views\Tests\Wizard; use Drupal\Core\Field\FieldStorageDefinitionInterface; +use Drupal\entity_reference\Tests\EntityReferenceTestTrait; /** * Tests the ability of the views wizard to create views filtered by taxonomy. @@ -16,6 +17,8 @@ */ class TaggedWithTest extends WizardTestBase { + use EntityReferenceTestTrait; + /** * Modules to enable. * @@ -82,45 +85,30 @@ protected function setUp() { // Create the tag field itself. $this->tagFieldName = 'field_views_testing_tags'; - $this->tagFieldStorage = entity_create('field_storage_config', array( - 'field_name' => $this->tagFieldName, - 'entity_type' => 'node', - 'type' => 'taxonomy_term_reference', - 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, - 'settings' => array( - 'allowed_values' => array( - array( - 'vocabulary' => $this->tagVocabulary->id(), - 'parent' => 0, - ), - ), - ), - )); - $this->tagFieldStorage->save(); - // Create an instance of the tag field on one of the content types, and - // configure it to display an autocomplete widget. - $this->tagField = array( - 'field_storage' => $this->tagFieldStorage, - 'bundle' => $this->nodeTypeWithTags->id(), + $handler_settings = array( + 'target_bundles' => array( + $this->tagVocabulary->id() => $this->tagVocabulary->id(), + ), + 'auto_create' => TRUE, ); - entity_create('field_config', $this->tagField)->save(); + $this->createEntityReferenceField('node', $this->nodeTypeWithTags->id(), $this->tagFieldName, NULL, 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); entity_get_form_display('node', $this->nodeTypeWithTags->id(), 'default') - ->setComponent('field_views_testing_tags', array( - 'type' => 'taxonomy_autocomplete', + ->setComponent($this->tagFieldName, array( + 'type' => 'entity_reference_autocomplete_tags', )) ->save(); entity_get_display('node', $this->nodeTypeWithTags->id(), 'default') - ->setComponent('field_views_testing_tags', array( - 'type' => 'taxonomy_term_reference_link', + ->setComponent($this->tagFieldName, array( + 'type' => 'entity_reference_label', 'weight' => 10, )) ->save(); entity_get_display('node', $this->nodeTypeWithTags->id(), 'teaser') ->setComponent('field_views_testing_tags', array( - 'type' => 'taxonomy_term_reference_link', + 'type' => 'entity_reference_label', 'weight' => 10, )) ->save(); @@ -137,11 +125,11 @@ function testTaggedWith() { // Create three nodes, with different tags. $edit = array(); $edit['title[0][value]'] = $node_tag1_title = $this->randomMachineName(); - $edit[$this->tagFieldName] = 'tag1'; + $edit[$this->tagFieldName . '[target_id]'] = 'tag1'; $this->drupalPostForm($node_add_path, $edit, t('Save')); $edit = array(); $edit['title[0][value]'] = $node_tag1_tag2_title = $this->randomMachineName(); - $edit[$this->tagFieldName] = 'tag1, tag2'; + $edit[$this->tagFieldName . '[target_id]'] = 'tag1, tag2'; $this->drupalPostForm($node_add_path, $edit, t('Save')); $edit = array(); $edit['title[0][value]'] = $node_no_tags_title = $this->randomMachineName(); @@ -213,12 +201,23 @@ function testTaggedWithByNodeType() { // If we add an instance of the tagging field to the second node type, the // "tagged with" form element should not appear for it too. - $field = $this->tagField; - $field['bundle'] = $this->nodeTypeWithoutTags->id(); - entity_create('field_config', $field)->save(); + entity_create('field_config', array( + 'field_name' => $this->tagFieldName, + 'entity_type' => 'node', + 'bundle' => $this->nodeTypeWithoutTags->id(), + 'settings' => array( + 'handler' => 'default', + 'handler_settings' => array( + 'target_bundles' => array( + $this->tagVocabulary->id() => $this->tagVocabulary->id(), + ), + 'auto_create' => TRUE, + ), + ), + ))->save(); entity_get_form_display('node', $this->nodeTypeWithoutTags->id(), 'default') - ->setComponent('field_views_testing_tags', array( - 'type' => 'taxonomy_autocomplete', + ->setComponent($this->tagFieldName, array( + 'type' => 'entity_reference_autocomplete_tags', )) ->save(); diff --git a/core/profiles/standard/config/install/core.entity_form_display.node.article.default.yml b/core/profiles/standard/config/install/core.entity_form_display.node.article.default.yml index 9e54f2a043cba15b18e8b6ac23349bbdaaa7a563..64f8efcb7a3367cf80139e8299d1d8371efe23fc 100644 --- a/core/profiles/standard/config/install/core.entity_form_display.node.article.default.yml +++ b/core/profiles/standard/config/install/core.entity_form_display.node.article.default.yml @@ -35,7 +35,7 @@ content: placeholder: '' third_party_settings: { } field_tags: - type: taxonomy_autocomplete + type: entity_reference_autocomplete_tags weight: 3 settings: { } third_party_settings: { } diff --git a/core/profiles/standard/config/install/core.entity_view_display.node.article.default.yml b/core/profiles/standard/config/install/core.entity_view_display.node.article.default.yml index d8e8ad0d8d77565c660e89b77e77476c21c6d59f..0689b2235dbcc0ae4374ff2a8e552c004c89ffc8 100644 --- a/core/profiles/standard/config/install/core.entity_view_display.node.article.default.yml +++ b/core/profiles/standard/config/install/core.entity_view_display.node.article.default.yml @@ -33,10 +33,11 @@ content: third_party_settings: { } label: hidden field_tags: - type: taxonomy_term_reference_link + type: entity_reference_label weight: 10 label: above - settings: { } + settings: + link: true third_party_settings: { } comment: label: above diff --git a/core/profiles/standard/config/install/core.entity_view_display.node.article.teaser.yml b/core/profiles/standard/config/install/core.entity_view_display.node.article.teaser.yml index aa28ff0456cf3dddb10833da47114ddc894c5d55..464606dc4a147a8fdd4d793151968795debc8575 100644 --- a/core/profiles/standard/config/install/core.entity_view_display.node.article.teaser.yml +++ b/core/profiles/standard/config/install/core.entity_view_display.node.article.teaser.yml @@ -34,9 +34,10 @@ content: third_party_settings: { } label: hidden field_tags: - type: taxonomy_term_reference_link + type: entity_reference_label weight: 10 - settings: { } + settings: + link: true third_party_settings: { } label: above links: diff --git a/core/profiles/standard/config/install/field.field.node.article.field_tags.yml b/core/profiles/standard/config/install/field.field.node.article.field_tags.yml index cfce273783efbff898757b75f2e17ec86cbec408..d69a558e50e36382b483febd53ca6092debd21af 100644 --- a/core/profiles/standard/config/install/field.field.node.article.field_tags.yml +++ b/core/profiles/standard/config/install/field.field.node.article.field_tags.yml @@ -2,16 +2,25 @@ id: node.article.field_tags entity_type: node bundle: article field_name: field_tags -field_type: taxonomy_term_reference +field_type: entity_reference label: Tags description: 'Enter a comma-separated list. For example: Amsterdam, Mexico City, "Cleveland, Ohio"' required: false default_value: { } default_value_callback: '' -settings: { } +settings: + handler: default + handler_settings: + target_bundles: + tags: tags + sort: + field: _none + auto_create: true status: true langcode: en dependencies: config: - field.storage.node.field_tags - node.type.article + module: + - entity_reference diff --git a/core/profiles/standard/config/install/field.storage.node.field_tags.yml b/core/profiles/standard/config/install/field.storage.node.field_tags.yml index 60c454676bbe887fdc7c1413bc236cd81faeefbe..71e0425f643f9af157cd491610cdd88e5e9452be 100644 --- a/core/profiles/standard/config/install/field.storage.node.field_tags.yml +++ b/core/profiles/standard/config/install/field.storage.node.field_tags.yml @@ -1,19 +1,13 @@ id: node.field_tags field_name: field_tags entity_type: node -type: taxonomy_term_reference +type: entity_reference module: taxonomy settings: - allowed_values: - - - vocabulary: tags - parent: 0 + target_type: taxonomy_term locked: false cardinality: -1 translatable: true -indexes: - target_id: - - target_id status: true langcode: en dependencies: diff --git a/core/themes/bartik/css/components/content.css b/core/themes/bartik/css/components/content.css index 28977ff99e3bc70d84caceeba0c61efeb2f53d2f..5f899f9dfa5d35dc57e95a3d0102169a103fb0ee 100644 --- a/core/themes/bartik/css/components/content.css +++ b/core/themes/bartik/css/components/content.css @@ -96,38 +96,38 @@ h1#page-title { margin-left: 20px; margin-right: 0; } -.field-type-taxonomy-term-reference { +.field-name-field-tags { margin: 0 0 1.2em; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; } -.field-type-taxonomy-term-reference .field-label { +.field-name-field-tags .field-label { font-weight: normal; margin: 0; padding-right: 5px; /* LTR */ } -[dir="rtl"] .field-type-taxonomy-term-reference .field-label { +[dir="rtl"] .field-name-field-tags .field-label { padding-left: 5px; padding-right: 0; } -.field-type-taxonomy-term-reference .field-label, -.field-type-taxonomy-term-reference ul.links { +.field-name-field-tags .field-label, +.field-name-field-tags ul.links { font-size: 0.8em; } -.node--view-mode-teaser .field-type-taxonomy-term-reference .field-label, -.node--view-mode-teaser .field-type-taxonomy-term-reference ul.links { +.node--view-mode-teaser .field-name-field-tags .field-label, +.node--view-mode-teaser .field-name-field-tags ul.links { font-size: 0.821em; } -.field-type-taxonomy-term-reference ul.links { +.field-name-field-tags ul.links { padding: 0; margin: 0; list-style: none; } -.field-type-taxonomy-term-reference ul.links li { +.field-name-field-tags ul.links li { float: left; /* LTR */ padding: 0 1em 0 0; /* LTR */ white-space: nowrap; } -[dir="rtl"] .field-type-taxonomy-term-reference ul.links li { +[dir="rtl"] .field-name-field-tags ul.links li { padding: 0 0 0 1em; float: right; } diff --git a/core/themes/bartik/templates/field--taxonomy-term-reference.html.twig b/core/themes/bartik/templates/field--node--field-tags.html.twig similarity index 100% rename from core/themes/bartik/templates/field--taxonomy-term-reference.html.twig rename to core/themes/bartik/templates/field--node--field-tags.html.twig